From 7d3a5ec579759a57b0a6c192e2aadab956879a26 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 19 Jan 2023 18:34:56 +0200 Subject: [PATCH 0001/1017] ASoC: Intel: sof_rt5682: always set dpcm_capture for amplifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 324f065cdbaba1b879a63bf07e61ca156b789537 ] The amplifier may provide hardware support for I/V feedback, or alternatively the firmware may generate an echo reference attached to the SSP and dailink used for the amplifier. To avoid any issues with invalid/NULL substreams in the latter case, always unconditionally set dpcm_capture. Link: https://github.com/thesofproject/linux/issues/4083 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20230119163459.2235843-2-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/sof_rt5682.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 1f94fa5a15db..5883d1fa3b7e 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -704,6 +704,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].nonatomic = true; links[id].dpcm_playback = 1; + /* feedback stream or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; From 490fcbc7b5f6c4d7841de2baf59211dd3395cf21 Mon Sep 17 00:00:00 2001 From: Eduard Zingerman Date: Fri, 6 Jan 2023 16:22:14 +0200 Subject: [PATCH 0002/1017] selftests/bpf: Verify copy_register_state() preserves parent/live fields [ Upstream commit b9fa9bc839291020b362ab5392e5f18ba79657ac ] A testcase to check that verifier.c:copy_register_state() preserves register parentage chain and livness information. Signed-off-by: Eduard Zingerman Link: https://lore.kernel.org/r/20230106142214.1040390-3-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- .../selftests/bpf/verifier/search_pruning.c | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/testing/selftests/bpf/verifier/search_pruning.c b/tools/testing/selftests/bpf/verifier/search_pruning.c index 7e50cb80873a..7e36078f8f48 100644 --- a/tools/testing/selftests/bpf/verifier/search_pruning.c +++ b/tools/testing/selftests/bpf/verifier/search_pruning.c @@ -154,3 +154,39 @@ .result_unpriv = ACCEPT, .insn_processed = 15, }, +/* The test performs a conditional 64-bit write to a stack location + * fp[-8], this is followed by an unconditional 8-bit write to fp[-8], + * then data is read from fp[-8]. This sequence is unsafe. + * + * The test would be mistakenly marked as safe w/o dst register parent + * preservation in verifier.c:copy_register_state() function. + * + * Note the usage of BPF_F_TEST_STATE_FREQ to force creation of the + * checkpoint state after conditional 64-bit assignment. + */ +{ + "write tracking and register parent chain bug", + .insns = { + /* r6 = ktime_get_ns() */ + BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), + BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), + /* r0 = ktime_get_ns() */ + BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns), + /* if r0 > r6 goto +1 */ + BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_6, 1), + /* *(u64 *)(r10 - 8) = 0xdeadbeef */ + BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0xdeadbeef), + /* r1 = 42 */ + BPF_MOV64_IMM(BPF_REG_1, 42), + /* *(u8 *)(r10 - 8) = r1 */ + BPF_STX_MEM(BPF_B, BPF_REG_FP, BPF_REG_1, -8), + /* r2 = *(u64 *)(r10 - 8) */ + BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_FP, -8), + /* exit(0) */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .flags = BPF_F_TEST_STATE_FREQ, + .errstr = "invalid read from stack off -8+1 size 8", + .result = REJECT, +}, From 7fc4e7191eae9d9325511e03deadfdb2224914f8 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 19 Jan 2023 15:32:35 +0100 Subject: [PATCH 0003/1017] ALSA: hda: Do not unset preset when cleaning up codec [ Upstream commit 87978e6ad45a16835cc58234451111091be3c59a ] Several functions that take part in codec's initialization and removal are re-used by ASoC codec drivers implementations. Drivers mimic the behavior of hda_codec_driver_probe/remove() found in sound/pci/hda/hda_bind.c with their component->probe/remove() instead. One of the reasons for that is the expectation of snd_hda_codec_device_new() to receive a valid pointer to an instance of struct snd_card. This expectation can be met only once sound card components probing commences. As ASoC sound card may be unbound without codec device being actually removed from the system, unsetting ->preset in snd_hda_codec_cleanup_for_unbind() interferes with module unload -> load scenario causing null-ptr-deref. Preset is assigned only once, during device/driver matching whereas ASoC codec driver's module reloading may occur several times throughout the lifetime of an audio stack. Suggested-by: Takashi Iwai Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20230119143235.1159814-1-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/hda_bind.c | 2 ++ sound/pci/hda/hda_codec.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index 4efbcc41fdfb..0a83afa5f373 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -143,6 +143,7 @@ static int hda_codec_driver_probe(struct device *dev) error: snd_hda_codec_cleanup_for_unbind(codec); + codec->preset = NULL; return err; } @@ -159,6 +160,7 @@ static int hda_codec_driver_remove(struct device *dev) if (codec->patch_ops.free) codec->patch_ops.free(codec); snd_hda_codec_cleanup_for_unbind(codec); + codec->preset = NULL; module_put(dev->driver->owner); return 0; } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 39281106477e..fc4a64a83ff2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -784,7 +784,6 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) snd_array_free(&codec->cvt_setups); snd_array_free(&codec->spdif_out); snd_array_free(&codec->verbs); - codec->preset = NULL; codec->follower_dig_outs = NULL; codec->spdif_status_reset = 0; snd_array_free(&codec->mixers); From 3ec44268e29cb0f3ed65aa12624d8589d7ac2feb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 26 Jan 2023 17:21:24 +0100 Subject: [PATCH 0004/1017] ASoC: cs42l56: fix DT probe [ Upstream commit e18c6da62edc780e4f4f3c9ce07bdacd69505182 ] While looking through legacy platform data users, I noticed that the DT probing never uses data from the DT properties, as the platform_data structure gets overwritten directly after it is initialized. There have never been any boards defining the platform_data in the mainline kernel either, so this driver so far only worked with patched kernels or with the default values. For the benefit of possible downstream users, fix the DT probe by no longer overwriting the data. Signed-off-by: Arnd Bergmann Acked-by: Charles Keepax Link: https://lore.kernel.org/r/20230126162203.2986339-1-arnd@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/cs42l56.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index d41e03193106..3c5ec47a8fe6 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1193,18 +1193,12 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, if (pdata) { cs42l56->pdata = *pdata; } else { - pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), - GFP_KERNEL); - if (!pdata) - return -ENOMEM; - if (i2c_client->dev.of_node) { ret = cs42l56_handle_of_data(i2c_client, &cs42l56->pdata); if (ret != 0) return ret; } - cs42l56->pdata = *pdata; } if (cs42l56->pdata.gpio_nreset) { From 37bb61763d9f62c12064c0c5b37ec4edcc7f5e76 Mon Sep 17 00:00:00 2001 From: Shunsuke Mie Date: Tue, 10 Jan 2023 12:43:10 +0900 Subject: [PATCH 0005/1017] tools/virtio: fix the vringh test for virtio ring changes [ Upstream commit 3f7b75abf41cc4143aa295f62acbb060a012868d ] Fix the build caused by missing kmsan_handle_dma() and is_power_of_2() that are used in drivers/virtio/virtio_ring.c. Signed-off-by: Shunsuke Mie Message-Id: <20230110034310.779744-1-mie@igel.co.jp> Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin --- tools/virtio/linux/bug.h | 8 +++----- tools/virtio/linux/build_bug.h | 7 +++++++ tools/virtio/linux/cpumask.h | 7 +++++++ tools/virtio/linux/gfp.h | 7 +++++++ tools/virtio/linux/kernel.h | 1 + tools/virtio/linux/kmsan.h | 12 ++++++++++++ tools/virtio/linux/scatterlist.h | 1 + tools/virtio/linux/topology.h | 7 +++++++ 8 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 tools/virtio/linux/build_bug.h create mode 100644 tools/virtio/linux/cpumask.h create mode 100644 tools/virtio/linux/gfp.h create mode 100644 tools/virtio/linux/kmsan.h create mode 100644 tools/virtio/linux/topology.h diff --git a/tools/virtio/linux/bug.h b/tools/virtio/linux/bug.h index b14c2c3b6b85..74aef964f509 100644 --- a/tools/virtio/linux/bug.h +++ b/tools/virtio/linux/bug.h @@ -1,11 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifndef BUG_H -#define BUG_H +#ifndef _LINUX_BUG_H +#define _LINUX_BUG_H #define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond)) -#define BUILD_BUG_ON(x) - #define BUG() abort() -#endif /* BUG_H */ +#endif /* _LINUX_BUG_H */ diff --git a/tools/virtio/linux/build_bug.h b/tools/virtio/linux/build_bug.h new file mode 100644 index 000000000000..cdbb75e28a60 --- /dev/null +++ b/tools/virtio/linux/build_bug.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_BUILD_BUG_H +#define _LINUX_BUILD_BUG_H + +#define BUILD_BUG_ON(x) + +#endif /* _LINUX_BUILD_BUG_H */ diff --git a/tools/virtio/linux/cpumask.h b/tools/virtio/linux/cpumask.h new file mode 100644 index 000000000000..307da69d6b26 --- /dev/null +++ b/tools/virtio/linux/cpumask.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_CPUMASK_H +#define _LINUX_CPUMASK_H + +#include + +#endif /* _LINUX_CPUMASK_H */ diff --git a/tools/virtio/linux/gfp.h b/tools/virtio/linux/gfp.h new file mode 100644 index 000000000000..43d146f236f1 --- /dev/null +++ b/tools/virtio/linux/gfp.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_GFP_H +#define __LINUX_GFP_H + +#include + +#endif diff --git a/tools/virtio/linux/kernel.h b/tools/virtio/linux/kernel.h index 315e85cabeda..063ccc897564 100644 --- a/tools/virtio/linux/kernel.h +++ b/tools/virtio/linux/kernel.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/tools/virtio/linux/kmsan.h b/tools/virtio/linux/kmsan.h new file mode 100644 index 000000000000..272b5aa285d5 --- /dev/null +++ b/tools/virtio/linux/kmsan.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_KMSAN_H +#define _LINUX_KMSAN_H + +#include + +inline void kmsan_handle_dma(struct page *page, size_t offset, size_t size, + enum dma_data_direction dir) +{ +} + +#endif /* _LINUX_KMSAN_H */ diff --git a/tools/virtio/linux/scatterlist.h b/tools/virtio/linux/scatterlist.h index 369ee308b668..74d9e1825748 100644 --- a/tools/virtio/linux/scatterlist.h +++ b/tools/virtio/linux/scatterlist.h @@ -2,6 +2,7 @@ #ifndef SCATTERLIST_H #define SCATTERLIST_H #include +#include struct scatterlist { unsigned long page_link; diff --git a/tools/virtio/linux/topology.h b/tools/virtio/linux/topology.h new file mode 100644 index 000000000000..910794afb993 --- /dev/null +++ b/tools/virtio/linux/topology.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_TOPOLOGY_H +#define _LINUX_TOPOLOGY_H + +#include + +#endif /* _LINUX_TOPOLOGY_H */ From aa84a8cc1b536883bc381d03fc036fa9b21d0e6a Mon Sep 17 00:00:00 2001 From: Hyunwoo Kim Date: Wed, 25 Jan 2023 02:59:44 -0800 Subject: [PATCH 0006/1017] net/rose: Fix to not accept on connected socket [ Upstream commit 14caefcf9837a2be765a566005ad82cd0d2a429f ] If you call listen() and accept() on an already connect()ed rose socket, accept() can successfully connect. This is because when the peer socket sends data to sendmsg, the skb with its own sk stored in the connected socket's sk->sk_receive_queue is connected, and rose_accept() dequeues the skb waiting in the sk->sk_receive_queue. This creates a child socket with the sk of the parent rose socket, which can cause confusion. Fix rose_listen() to return -EINVAL if the socket has already been successfully connected, and add lock_sock to prevent this issue. Signed-off-by: Hyunwoo Kim Reviewed-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20230125105944.GA133314@ubuntu Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/rose/af_rose.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 29a208ed8fb8..86c93cf1744b 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -487,6 +487,12 @@ static int rose_listen(struct socket *sock, int backlog) { struct sock *sk = sock->sk; + lock_sock(sk); + if (sock->state != SS_UNCONNECTED) { + release_sock(sk); + return -EINVAL; + } + if (sk->sk_state != TCP_LISTEN) { struct rose_sock *rose = rose_sk(sk); @@ -496,8 +502,10 @@ static int rose_listen(struct socket *sock, int backlog) memset(rose->dest_digis, 0, AX25_ADDR_LEN * ROSE_MAX_DIGIS); sk->sk_max_ack_backlog = backlog; sk->sk_state = TCP_LISTEN; + release_sock(sk); return 0; } + release_sock(sk); return -EOPNOTSUPP; } From 614a58e00d7bcbaf0d698712e0decd29d53a3847 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Fri, 27 Jan 2023 00:35:39 +0300 Subject: [PATCH 0007/1017] net: stmmac: do not stop RX_CLK in Rx LPI state for qcs404 SoC [ Upstream commit 54aa39a513dbf2164ca462a19f04519b2407a224 ] Currently in phy_init_eee() the driver unconditionally configures the PHY to stop RX_CLK after entering Rx LPI state. This causes an LPI interrupt storm on my qcs404-base board. Change the PHY initialization so that for "qcom,qcs404-ethqos" compatible device RX_CLK continues to run even in Rx LPI state. Signed-off-by: Andrey Konovalov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 ++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++- include/linux/stmmac.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index bfc4a92f1d92..78be62ecc9a9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -505,6 +505,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev) plat_dat->has_gmac4 = 1; plat_dat->pmt = 1; plat_dat->tso_en = of_property_read_bool(np, "snps,tso"); + if (of_device_is_compatible(np, "qcom,qcs404-ethqos")) + plat_dat->rx_clk_runs_in_lpi = 1; ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index b52ca2fe04d8..1ec000d4c770 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1058,7 +1058,8 @@ static void stmmac_mac_link_up(struct phylink_config *config, stmmac_mac_set(priv, priv->ioaddr, true); if (phy && priv->dma_cap.eee) { - priv->eee_active = phy_init_eee(phy, 1) >= 0; + priv->eee_active = + phy_init_eee(phy, !priv->plat->rx_clk_runs_in_lpi) >= 0; priv->eee_enabled = stmmac_eee_init(priv); priv->tx_lpi_enabled = priv->eee_enabled; stmmac_set_eee_pls(priv, priv->hw, true); diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 40df88728a6f..abf7b8ec1fb6 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -199,6 +199,7 @@ struct plat_stmmacenet_data { int rss_en; int mac_port_sel_speed; bool en_tx_lpi_clockgating; + bool rx_clk_runs_in_lpi; int has_xgmac; bool vlan_fail_q_en; u8 vlan_fail_q; From 90fcf55d83b20da1091f926a291af05fb74f61c6 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 14:40:37 -0800 Subject: [PATCH 0008/1017] net: sched: sch: Bounds check priority [ Upstream commit de5ca4c3852f896cacac2bf259597aab5e17d9e3 ] Nothing was explicitly bounds checking the priority index used to access clpriop[]. WARN and bail out early if it's pathological. Seen with GCC 13: ../net/sched/sch_htb.c: In function 'htb_activate_prios': ../net/sched/sch_htb.c:437:44: warning: array subscript [0, 31] is outside array bounds of 'struct htb_prio[8]' [-Warray-bounds=] 437 | if (p->inner.clprio[prio].feed.rb_node) | ~~~~~~~~~~~~~~~^~~~~~ ../net/sched/sch_htb.c:131:41: note: while referencing 'clprio' 131 | struct htb_prio clprio[TC_HTB_NUMPRIO]; | ^~~~~~ Cc: Jamal Hadi Salim Cc: Cong Wang Cc: Jiri Pirko Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook Reviewed-by: Simon Horman Reviewed-by: Cong Wang Link: https://lore.kernel.org/r/20230127224036.never.561-kees@kernel.org Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/sched/sch_htb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index c3ba018fd083..c3e773d2ca41 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -405,7 +405,10 @@ static void htb_activate_prios(struct htb_sched *q, struct htb_class *cl) while (cl->cmode == HTB_MAY_BORROW && p && mask) { m = mask; while (m) { - int prio = ffz(~m); + unsigned int prio = ffz(~m); + + if (WARN_ON_ONCE(prio > ARRAY_SIZE(p->inner.clprio))) + break; m &= ~(1 << prio); if (p->inner.clprio[prio].feed.rb_node) From 55dbd6f4ea954751340f4f73d5dcd7c8f12208b2 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Sun, 29 Jan 2023 23:47:23 +0100 Subject: [PATCH 0009/1017] s390/decompressor: specify __decompress() buf len to avoid overflow [ Upstream commit 7ab41c2c08a32132ba8c14624910e2fe8ce4ba4b ] Historically calls to __decompress() didn't specify "out_len" parameter on many architectures including s390, expecting that no writes beyond uncompressed kernel image are performed. This has changed since commit 2aa14b1ab2c4 ("zstd: import usptream v1.5.2") which includes zstd library commit 6a7ede3dfccb ("Reduce size of dctx by reutilizing dst buffer (#2751)"). Now zstd decompression code might store literal buffer in the unwritten portion of the destination buffer. Since "out_len" is not set, it is considered to be unlimited and hence free to use for optimization needs. On s390 this might corrupt initrd or ipl report which are often placed right after the decompressor buffer. Luckily the size of uncompressed kernel image is already known to the decompressor, so to avoid the problem simply specify it in the "out_len" parameter. Link: https://github.com/facebook/zstd/commit/6a7ede3dfccb Signed-off-by: Vasily Gorbik Tested-by: Alexander Egorenkov Link: https://lore.kernel.org/r/patch-1.thread-41c676.git-41c676c2d153.your-ad-here.call-01675030179-ext-9637@work.hours Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin --- arch/s390/boot/compressed/decompressor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/boot/compressed/decompressor.c b/arch/s390/boot/compressed/decompressor.c index 3061b11c4d27..8eaa1712a1c8 100644 --- a/arch/s390/boot/compressed/decompressor.c +++ b/arch/s390/boot/compressed/decompressor.c @@ -79,6 +79,6 @@ void *decompress_kernel(void) void *output = (void *)decompress_offset; __decompress(_compressed_start, _compressed_end - _compressed_start, - NULL, NULL, output, 0, NULL, error); + NULL, NULL, output, vmlinux.image_size, NULL, error); return output; } From ecf5b49df38fa26e5039894e247fa12a8b796799 Mon Sep 17 00:00:00 2001 From: Amit Engel Date: Mon, 23 Jan 2023 14:37:28 +0200 Subject: [PATCH 0010/1017] nvme-fc: fix a missing queue put in nvmet_fc_ls_create_association [ Upstream commit 0cab4404874f2de52617de8400c844891c6ea1ce ] As part of nvmet_fc_ls_create_association there is a case where nvmet_fc_alloc_target_queue fails right after a new association with an admin queue is created. In this case, no one releases the get taken in nvmet_fc_alloc_target_assoc. This fix is adding the missing put. Signed-off-by: Amit Engel Reviewed-by: James Smart Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/fc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index 640031cbda7c..46fc44ce8671 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c @@ -1675,8 +1675,10 @@ nvmet_fc_ls_create_association(struct nvmet_fc_tgtport *tgtport, else { queue = nvmet_fc_alloc_target_queue(iod->assoc, 0, be16_to_cpu(rqst->assoc_cmd.sqsize)); - if (!queue) + if (!queue) { ret = VERR_QUEUE_ALLOC_FAIL; + nvmet_fc_tgt_a_put(iod->assoc); + } } } From 25f65c83f5f7c5de3d7c7f0b10e15a7413dfe5bf Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Feb 2023 11:34:13 +0100 Subject: [PATCH 0011/1017] platform/x86: touchscreen_dmi: Add Chuwi Vi8 (CWI501) DMI match [ Upstream commit eecf2acd4a580e9364e5087daf0effca60a240b7 ] Add a DMI match for the CWI501 version of the Chuwi Vi8 tablet, pointing to the same chuwi_vi8_data as the existing CWI506 version DMI match. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20230202103413.331459-1-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/touchscreen_dmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index bc26acace2c3..b96fbc8dba09 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -1030,6 +1030,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_BIOS_DATE, "05/07/2016"), }, }, + { + /* Chuwi Vi8 (CWI501) */ + .driver_data = (void *)&chuwi_vi8_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "i86"), + DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.W86JLBNR01"), + }, + }, { /* Chuwi Vi8 (CWI506) */ .driver_data = (void *)&chuwi_vi8_data, From a19a0f67dbb89ad2bfc466f2003841acba645884 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Fri, 16 Sep 2022 13:20:50 +0100 Subject: [PATCH 0012/1017] nvmem: core: add error handling for dev_set_name [ Upstream commit 5544e90c81261e82e02bbf7c6015a4b9c8c825ef ] The type of return value of dev_set_name is int, which may return wrong result, so we add error handling for it to reclaim memory of nvmem resource, and return early when an error occurs. Signed-off-by: Gaosheng Cui Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220916122100.170016-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: ab3428cfd9aa ("nvmem: core: fix registration vs use race") Signed-off-by: Sasha Levin --- drivers/nvmem/core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 48fbe49e3772..9da4edbabfe7 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -661,18 +661,24 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) switch (config->id) { case NVMEM_DEVID_NONE: - dev_set_name(&nvmem->dev, "%s", config->name); + rval = dev_set_name(&nvmem->dev, "%s", config->name); break; case NVMEM_DEVID_AUTO: - dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id); + rval = dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id); break; default: - dev_set_name(&nvmem->dev, "%s%d", + rval = dev_set_name(&nvmem->dev, "%s%d", config->name ? : "nvmem", config->name ? config->id : nvmem->id); break; } + if (rval) { + ida_free(&nvmem_ida, nvmem->id); + kfree(nvmem); + return ERR_PTR(rval); + } + nvmem->read_only = device_property_present(config->dev, "read-only") || config->read_only || !nvmem->reg_write; From 89991ededcb557dcfe6398fa37eb182d01cfe257 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Fri, 27 Jan 2023 10:40:09 +0000 Subject: [PATCH 0013/1017] nvmem: core: remove nvmem_config wp_gpio [ Upstream commit 569653f022a29a1a44ea9de5308b657228303fa5 ] No one provides wp_gpio, so let's remove it to avoid issues with the nvmem core putting this gpio. Cc: stable@vger.kernel.org Signed-off-by: Russell King (Oracle) Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230127104015.23839-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: ab3428cfd9aa ("nvmem: core: fix registration vs use race") Signed-off-by: Sasha Levin --- drivers/nvmem/core.c | 4 +--- include/linux/nvmem-provider.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 9da4edbabfe7..38c05fce7d74 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -627,9 +627,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->id = rval; - if (config->wp_gpio) - nvmem->wp_gpio = config->wp_gpio; - else if (!config->ignore_wp) + if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 39ec67689898..5e07f3cfad30 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -49,7 +49,6 @@ enum nvmem_type { * @word_size: Minimum read/write access granularity. * @stride: Minimum read/write access stride. * @priv: User context passed to read/write callbacks. - * @wp-gpio: Write protect pin * @ignore_wp: Write Protect pin is managed by the provider. * * Note: A default "nvmem" name will be assigned to the device if @@ -64,7 +63,6 @@ struct nvmem_config { const char *name; int id; struct module *owner; - struct gpio_desc *wp_gpio; const struct nvmem_cell_info *cells; int ncells; enum nvmem_type type; From 23676ecd2eb377f7c24a6ff578b0f4c7135658b6 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Fri, 27 Jan 2023 10:40:10 +0000 Subject: [PATCH 0014/1017] nvmem: core: fix cleanup after dev_set_name() [ Upstream commit 560181d3ace61825f4ca9dd3481d6c0ee6709fa8 ] If dev_set_name() fails, we leak nvmem->wp_gpio as the cleanup does not put this. While a minimal fix for this would be to add the gpiod_put() call, we can do better if we split device_register(), and use the tested nvmem_release() cleanup code by initialising the device early, and putting the device. This results in a slightly larger fix, but results in clear code. Note: this patch depends on "nvmem: core: initialise nvmem->id early" and "nvmem: core: remove nvmem_config wp_gpio". Fixes: 5544e90c8126 ("nvmem: core: add error handling for dev_set_name") Cc: stable@vger.kernel.org Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Russell King (Oracle) [Srini: Fixed subject line and error code handing with wp_gpio while applying.] Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230127104015.23839-6-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: ab3428cfd9aa ("nvmem: core: fix registration vs use race") Signed-off-by: Sasha Levin --- drivers/nvmem/core.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 38c05fce7d74..de356cdde4ce 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -627,14 +627,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->id = rval; + nvmem->dev.type = &nvmem_provider_type; + nvmem->dev.bus = &nvmem_bus_type; + nvmem->dev.parent = config->dev; + + device_initialize(&nvmem->dev); + if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { - ida_free(&nvmem_ida, nvmem->id); rval = PTR_ERR(nvmem->wp_gpio); - kfree(nvmem); - return ERR_PTR(rval); + goto err_put_device; } kref_init(&nvmem->refcnt); @@ -646,9 +650,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->stride = config->stride ?: 1; nvmem->word_size = config->word_size ?: 1; nvmem->size = config->size; - nvmem->dev.type = &nvmem_provider_type; - nvmem->dev.bus = &nvmem_bus_type; - nvmem->dev.parent = config->dev; nvmem->root_only = config->root_only; nvmem->priv = config->priv; nvmem->type = config->type; @@ -671,11 +672,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) break; } - if (rval) { - ida_free(&nvmem_ida, nvmem->id); - kfree(nvmem); - return ERR_PTR(rval); - } + if (rval) + goto err_put_device; nvmem->read_only = device_property_present(config->dev, "read-only") || config->read_only || !nvmem->reg_write; @@ -686,7 +684,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - rval = device_register(&nvmem->dev); + rval = device_add(&nvmem->dev); if (rval) goto err_put_device; From 2dcb474af1d5d06c1e343a0d7248219bb87a08b7 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Fri, 27 Jan 2023 10:40:11 +0000 Subject: [PATCH 0015/1017] nvmem: core: fix registration vs use race [ Upstream commit ab3428cfd9aa2f3463ee4b2909b5bb2193bd0c4a ] The i.MX6 CPU frequency driver sometimes fails to register at boot time due to nvmem_cell_read_u32() sporadically returning -ENOENT. This happens because there is a window where __nvmem_device_get() in of_nvmem_cell_get() is able to return the nvmem device, but as cells have been setup, nvmem_find_cell_entry_by_node() returns NULL. The occurs because the nvmem core registration code violates one of the fundamental principles of kernel programming: do not publish data structures before their setup is complete. Fix this by making nvmem core code conform with this principle. Fixes: eace75cfdcf7 ("nvmem: Add a simple NVMEM framework for nvmem providers") Cc: stable@vger.kernel.org Signed-off-by: Russell King (Oracle) Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230127104015.23839-7-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/nvmem/core.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index de356cdde4ce..0ef7b95348b1 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -682,16 +682,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->dev.groups = nvmem_dev_groups; #endif - dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - - rval = device_add(&nvmem->dev); - if (rval) - goto err_put_device; - if (config->compat) { rval = nvmem_sysfs_setup_compat(nvmem, config); if (rval) - goto err_device_del; + goto err_put_device; } if (config->cells) { @@ -708,6 +702,12 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (rval) goto err_remove_cells; + dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); + + rval = device_add(&nvmem->dev); + if (rval) + goto err_remove_cells; + blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); return nvmem; @@ -716,8 +716,6 @@ err_remove_cells: nvmem_device_remove_all_cells(nvmem); if (config->compat) nvmem_sysfs_remove_compat(nvmem, config); -err_device_del: - device_del(&nvmem->dev); err_put_device: put_device(&nvmem->dev); From c261f798f7baa8080cf0214081d43d5f86bb073f Mon Sep 17 00:00:00 2001 From: Seth Jenkins Date: Tue, 31 Jan 2023 12:25:55 -0500 Subject: [PATCH 0016/1017] aio: fix mremap after fork null-deref commit 81e9d6f8647650a7bead74c5f926e29970e834d1 upstream. Commit e4a0d3e720e7 ("aio: Make it possible to remap aio ring") introduced a null-deref if mremap is called on an old aio mapping after fork as mm->ioctx_table will be set to NULL. [jmoyer@redhat.com: fix 80 column issue] Link: https://lkml.kernel.org/r/x49sffq4nvg.fsf@segfault.boston.devel.redhat.com Fixes: e4a0d3e720e7 ("aio: Make it possible to remap aio ring") Signed-off-by: Seth Jenkins Signed-off-by: Jeff Moyer Cc: Alexander Viro Cc: Benjamin LaHaise Cc: Jann Horn Cc: Pavel Emelyanov Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/aio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/aio.c b/fs/aio.c index 2a9dfa58ec3a..5934ea84b499 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -335,6 +335,9 @@ static int aio_ring_mremap(struct vm_area_struct *vma) spin_lock(&mm->ioctx_lock); rcu_read_lock(); table = rcu_dereference(mm->ioctx_table); + if (!table) + goto out_unlock; + for (i = 0; i < table->nr; i++) { struct kioctx *ctx; @@ -348,6 +351,7 @@ static int aio_ring_mremap(struct vm_area_struct *vma) } } +out_unlock: rcu_read_unlock(); spin_unlock(&mm->ioctx_lock); return res; From 645df4047bd67e368c5fe9783a115916c4128c1d Mon Sep 17 00:00:00 2001 From: Sumanth Korikkar Date: Wed, 15 Feb 2023 15:13:24 +0100 Subject: [PATCH 0017/1017] s390/signal: fix endless loop in do_signal No upstream commit exists: the problem addressed here is that 'commit 75309018a24d ("s390: add support for TIF_NOTIFY_SIGNAL")' was backported to 5.10. This commit is broken, but nobody noticed upstream, since shortly after s390 converted to generic entry with 'commit 56e62a737028 ("s390: convert to generic entry")', which implicitly fixed the problem outlined below. Thread flag is set to TIF_NOTIFY_SIGNAL for io_uring work. The io work user or syscall calls do_signal when either one of the TIF_SIGPENDING or TIF_NOTIFY_SIGNAL flag is set. However, do_signal does consider only TIF_SIGPENDING signal and ignores TIF_NOTIFY_SIGNAL condition. This means get_signal is never invoked for TIF_NOTIFY_SIGNAL and hence the flag is not cleared, which results in an endless do_signal loop. Reference: 'commit 788d0824269b ("io_uring: import 5.15-stable io_uring")' Fixes: 75309018a24d ("s390: add support for TIF_NOTIFY_SIGNAL") Cc: stable@vger.kernel.org # 5.10.162 Acked-by: Heiko Carstens Acked-by: Sven Schnelle Signed-off-by: Sumanth Korikkar Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index b27b6c1f058d..9e900a8977bd 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -472,7 +472,7 @@ void do_signal(struct pt_regs *regs) current->thread.system_call = test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0; - if (test_thread_flag(TIF_SIGPENDING) && get_signal(&ksig)) { + if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ if (current->thread.system_call) { regs->int_code = current->thread.system_call; From f6f94837d92f0f5f94700589bab6d880009dfc22 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Mon, 17 Oct 2022 17:06:38 +0200 Subject: [PATCH 0018/1017] ovl: remove privs in ovl_copyfile() commit b306e90ffabdaa7e3b3350dbcd19b7663e71ab17 upstream. Underlying fs doesn't remove privs because copy_range/remap_range are called with privileged mounter credentials. This fixes some failures in fstest generic/673. Fixes: 8ede205541ff ("ovl: add reflink/copyfile/dedup support") Acked-by: Miklos Szeredi Signed-off-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/overlayfs/file.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index b019f27c1360..259b2d41b707 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -687,14 +687,23 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, const struct cred *old_cred; loff_t ret; + inode_lock(inode_out); + if (op != OVL_DEDUPE) { + /* Update mode */ + ovl_copyattr(ovl_inode_real(inode_out), inode_out); + ret = file_remove_privs(file_out); + if (ret) + goto out_unlock; + } + ret = ovl_real_fdget(file_out, &real_out); if (ret) - return ret; + goto out_unlock; ret = ovl_real_fdget(file_in, &real_in); if (ret) { fdput(real_out); - return ret; + goto out_unlock; } old_cred = ovl_override_creds(file_inode(file_out)->i_sb); @@ -723,6 +732,9 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, fdput(real_in); fdput(real_out); +out_unlock: + inode_unlock(inode_out); + return ret; } From 6618b0dcf265975555e3eb24183e2a9e9b1c947c Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Mon, 17 Oct 2022 17:06:39 +0200 Subject: [PATCH 0019/1017] ovl: remove privs in ovl_fallocate() commit 23a8ce16419a3066829ad4a8b7032a75817af65b upstream. Underlying fs doesn't remove privs because fallocate is called with privileged mounter credentials. This fixes some failure in fstests generic/683..687. Fixes: aab8848cee5e ("ovl: add ovl_fallocate()") Acked-by: Miklos Szeredi Signed-off-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/overlayfs/file.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 259b2d41b707..0e734c8b4dfa 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -531,9 +531,16 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len const struct cred *old_cred; int ret; + inode_lock(inode); + /* Update mode */ + ovl_copyattr(ovl_inode_real(inode), inode); + ret = file_remove_privs(file); + if (ret) + goto out_unlock; + ret = ovl_real_fdget(file, &real); if (ret) - return ret; + goto out_unlock; old_cred = ovl_override_creds(file_inode(file)->i_sb); ret = vfs_fallocate(real.file, mode, offset, len); @@ -544,6 +551,9 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len fdput(real); +out_unlock: + inode_unlock(inode); + return ret; } From eaba3f9b672c3a3f820da8ee9584b9520674eafa Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Sat, 20 Aug 2022 17:54:06 +0200 Subject: [PATCH 0020/1017] netfilter: nft_tproxy: restrict to prerouting hook commit 18bbc3213383a82b05383827f4b1b882e3f0a5a5 upstream. TPROXY is only allowed from prerouting, but nft_tproxy doesn't check this. This fixes a crash (null dereference) when using tproxy from e.g. output. Fixes: 4ed8eb6570a4 ("netfilter: nf_tables: Add native tproxy support") Reported-by: Shell Chen Signed-off-by: Florian Westphal Signed-off-by: Qingfang DENG Signed-off-by: Greg Kroah-Hartman --- net/netfilter/nft_tproxy.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c index 37c728bdad41..c49d318f8e6e 100644 --- a/net/netfilter/nft_tproxy.c +++ b/net/netfilter/nft_tproxy.c @@ -289,6 +289,13 @@ static int nft_tproxy_dump(struct sk_buff *skb, return 0; } +static int nft_tproxy_validate(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nft_data **data) +{ + return nft_chain_validate_hooks(ctx->chain, 1 << NF_INET_PRE_ROUTING); +} + static struct nft_expr_type nft_tproxy_type; static const struct nft_expr_ops nft_tproxy_ops = { .type = &nft_tproxy_type, @@ -296,6 +303,7 @@ static const struct nft_expr_ops nft_tproxy_ops = { .eval = nft_tproxy_eval, .init = nft_tproxy_init, .dump = nft_tproxy_dump, + .validate = nft_tproxy_validate, }; static struct nft_expr_type nft_tproxy_type __read_mostly = { From 73ad25c50d3c3eba6ea4c6735a585c4613eae537 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Tue, 31 Jan 2023 21:02:28 +0000 Subject: [PATCH 0021/1017] mmc: jz4740: Work around bug on JZ4760(B) commit 3f18c5046e633cc4bbad396b74c05d46d353033d upstream. On JZ4760 and JZ4760B, SD cards fail to run if the maximum clock rate is set to 50 MHz, even though the controller officially does support it. Until the actual bug is found and fixed, limit the maximum clock rate to 24 MHz. Signed-off-by: Paul Cercueil Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230131210229.68129-1-paul@crapouillou.net Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/jz4740_mmc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index aa3dfb9c1071..62d00232f85e 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -1041,6 +1041,16 @@ static int jz4740_mmc_probe(struct platform_device* pdev) mmc->ops = &jz4740_mmc_ops; if (!mmc->f_max) mmc->f_max = JZ_MMC_CLK_RATE; + + /* + * There seems to be a problem with this driver on the JZ4760 and + * JZ4760B SoCs. There, when using the maximum rate supported (50 MHz), + * the communication fails with many SD cards. + * Until this bug is sorted out, limit the maximum rate to 24 MHz. + */ + if (host->version == JZ_MMC_JZ4760 && mmc->f_max > JZ_MMC_CLK_RATE) + mmc->f_max = JZ_MMC_CLK_RATE; + mmc->f_min = mmc->f_max / 128; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; From 30716d9f0fa1766e522cf24c8a456244e4fc9931 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 30 Jan 2023 20:58:08 +0800 Subject: [PATCH 0022/1017] mmc: sdio: fix possible resource leaks in some error paths commit 605d9fb9556f8f5fb4566f4df1480f280f308ded upstream. If sdio_add_func() or sdio_init_func() fails, sdio_remove_func() can not release the resources, because the sdio function is not presented in these two cases, it won't call of_node_put() or put_device(). To fix these leaks, make sdio_func_present() only control whether device_del() needs to be called or not, then always call of_node_put() and put_device(). In error case in sdio_init_func(), the reference of 'card->dev' is not get, to avoid redundant put in sdio_free_func_cis(), move the get_device() to sdio_alloc_func() and put_device() to sdio_release_func(), it can keep the get/put function be balanced. Without this patch, while doing fault inject test, it can get the following leak reports, after this fix, the leak is gone. unreferenced object 0xffff888112514000 (size 2048): comm "kworker/3:2", pid 65, jiffies 4294741614 (age 124.774s) hex dump (first 32 bytes): 00 e0 6f 12 81 88 ff ff 60 58 8d 06 81 88 ff ff ..o.....`X...... 10 40 51 12 81 88 ff ff 10 40 51 12 81 88 ff ff .@Q......@Q..... backtrace: [<000000009e5931da>] kmalloc_trace+0x21/0x110 [<000000002f839ccb>] mmc_alloc_card+0x38/0xb0 [mmc_core] [<0000000004adcbf6>] mmc_sdio_init_card+0xde/0x170 [mmc_core] [<000000007538fea0>] mmc_attach_sdio+0xcb/0x1b0 [mmc_core] [<00000000d4fdeba7>] mmc_rescan+0x54a/0x640 [mmc_core] unreferenced object 0xffff888112511000 (size 2048): comm "kworker/3:2", pid 65, jiffies 4294741623 (age 124.766s) hex dump (first 32 bytes): 00 40 51 12 81 88 ff ff e0 58 8d 06 81 88 ff ff .@Q......X...... 10 10 51 12 81 88 ff ff 10 10 51 12 81 88 ff ff ..Q.......Q..... backtrace: [<000000009e5931da>] kmalloc_trace+0x21/0x110 [<00000000fcbe706c>] sdio_alloc_func+0x35/0x100 [mmc_core] [<00000000c68f4b50>] mmc_attach_sdio.cold.18+0xb1/0x395 [mmc_core] [<00000000d4fdeba7>] mmc_rescan+0x54a/0x640 [mmc_core] Fixes: 3d10a1ba0d37 ("sdio: fix reference counting in sdio_remove_func()") Signed-off-by: Yang Yingliang Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230130125808.3471254-1-yangyingliang@huawei.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/core/sdio_bus.c | 17 ++++++++++++++--- drivers/mmc/core/sdio_cis.c | 12 ------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index a448535c1265..89dd49260080 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -295,6 +295,12 @@ static void sdio_release_func(struct device *dev) if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO)) sdio_free_func_cis(func); + /* + * We have now removed the link to the tuples in the + * card structure, so remove the reference. + */ + put_device(&func->card->dev); + kfree(func->info); kfree(func->tmpbuf); kfree(func); @@ -325,6 +331,12 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card) device_initialize(&func->dev); + /* + * We may link to tuples in the card structure, + * we need make sure we have a reference to it. + */ + get_device(&func->card->dev); + func->dev.parent = &card->dev; func->dev.bus = &sdio_bus_type; func->dev.release = sdio_release_func; @@ -378,10 +390,9 @@ int sdio_add_func(struct sdio_func *func) */ void sdio_remove_func(struct sdio_func *func) { - if (!sdio_func_present(func)) - return; + if (sdio_func_present(func)) + device_del(&func->dev); - device_del(&func->dev); of_node_put(func->dev.of_node); put_device(&func->dev); } diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index b23773583179..ce524f7e11fb 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -391,12 +391,6 @@ int sdio_read_func_cis(struct sdio_func *func) if (ret) return ret; - /* - * Since we've linked to tuples in the card structure, - * we must make sure we have a reference to it. - */ - get_device(&func->card->dev); - /* * Vendor/device id is optional for function CIS, so * copy it from the card structure as needed. @@ -422,11 +416,5 @@ void sdio_free_func_cis(struct sdio_func *func) } func->tuples = NULL; - - /* - * We have now removed the link to the tuples in the - * card structure, so remove the reference. - */ - put_device(&func->card->dev); } From 0b3edcb24bd81b3b2e3dac89f4733bfd47d283be Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 31 Jan 2023 09:38:35 +0800 Subject: [PATCH 0023/1017] mmc: mmc_spi: fix error handling in mmc_spi_probe() commit cf4c9d2ac1e42c7d18b921bec39486896645b714 upstream. If mmc_add_host() fails, it doesn't need to call mmc_remove_host(), or it will cause null-ptr-deref, because of deleting a not added device in mmc_remove_host(). To fix this, goto label 'fail_glue_init', if mmc_add_host() fails, and change the label 'fail_add_host' to 'fail_gpiod_request'. Fixes: 15a0580ced08 ("mmc_spi host driver") Signed-off-by: Yang Yingliang Cc:stable@vger.kernel.org Link: https://lore.kernel.org/r/20230131013835.3564011-1-yangyingliang@huawei.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/mmc_spi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 02f4fd26e76a..1d814919eb6b 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1450,7 +1450,7 @@ static int mmc_spi_probe(struct spi_device *spi) status = mmc_add_host(mmc); if (status != 0) - goto fail_add_host; + goto fail_glue_init; /* * Index 0 is card detect @@ -1458,7 +1458,7 @@ static int mmc_spi_probe(struct spi_device *spi) */ status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1000); if (status == -EPROBE_DEFER) - goto fail_add_host; + goto fail_gpiod_request; if (!status) { /* * The platform has a CD GPIO signal that may support @@ -1473,7 +1473,7 @@ static int mmc_spi_probe(struct spi_device *spi) /* Index 1 is write protect/read only */ status = mmc_gpiod_request_ro(mmc, NULL, 1, 0); if (status == -EPROBE_DEFER) - goto fail_add_host; + goto fail_gpiod_request; if (!status) has_ro = true; @@ -1487,7 +1487,7 @@ static int mmc_spi_probe(struct spi_device *spi) ? ", cd polling" : ""); return 0; -fail_add_host: +fail_gpiod_request: mmc_remove_host(mmc); fail_glue_init: mmc_spi_dma_free(host); From 59d5c80ce538e64074e0f6089d94bb9928938a8a Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Thu, 9 Feb 2023 10:13:48 +0800 Subject: [PATCH 0024/1017] ALSA: hda/conexant: add a new hda codec SN6180 commit 18d7e16c917a08f08778ecf2b780d63648d5d923 upstream. The current kernel does not support the SN6180 codec chip. Add the SN6180 codec configuration item to kernel. Signed-off-by: Bo Liu Cc: Link: https://lore.kernel.org/r/1675908828-1012-1-git-send-email-bo.liu@senarytech.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2bd0a5839e80..48b802563c2d 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1117,6 +1117,7 @@ static const struct hda_device_id snd_hda_id_conexant[] = { HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f120d1, "SN6180", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto), From 7ed5c147220fc205bb8a33ed36facc56ad6f3fd2 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Mon, 13 Feb 2023 14:54:22 +0800 Subject: [PATCH 0025/1017] ALSA: hda/realtek - fixed wrong gpio assigned commit 2bdccfd290d421b50df4ec6a68d832dad1310748 upstream. GPIO2 PIN use for output. Mask Dir and Data need to assign for 0x4. Not 0x3. This fixed was for Lenovo Desktop(0x17aa1056). GPIO2 use for AMP enable. Signed-off-by: Kailang Yang Cc: Link: https://lore.kernel.org/r/8d02bb9ac8134f878cd08607fdf088fd@realtek.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d66d2cf7708e..fffa681313b6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -827,7 +827,7 @@ do_sku: alc_setup_gpio(codec, 0x02); break; case 7: - alc_setup_gpio(codec, 0x03); + alc_setup_gpio(codec, 0x04); break; case 5: default: From ec9c7aa08819f976b2492fa63c41b5712d2924b5 Mon Sep 17 00:00:00 2001 From: Munehisa Kamata Date: Tue, 14 Feb 2023 13:27:05 -0800 Subject: [PATCH 0026/1017] sched/psi: Fix use-after-free in ep_remove_wait_queue() commit c2dbe32d5db5c4ead121cf86dabd5ab691fb47fe upstream. If a non-root cgroup gets removed when there is a thread that registered trigger and is polling on a pressure file within the cgroup, the polling waitqueue gets freed in the following path: do_rmdir cgroup_rmdir kernfs_drain_open_files cgroup_file_release cgroup_pressure_release psi_trigger_destroy However, the polling thread still has a reference to the pressure file and will access the freed waitqueue when the file is closed or upon exit: fput ep_eventpoll_release ep_free ep_remove_wait_queue remove_wait_queue This results in use-after-free as pasted below. The fundamental problem here is that cgroup_file_release() (and consequently waitqueue's lifetime) is not tied to the file's real lifetime. Using wake_up_pollfree() here might be less than ideal, but it is in line with the comment at commit 42288cb44c4b ("wait: add wake_up_pollfree()") since the waitqueue's lifetime is not tied to file's one and can be considered as another special case. While this would be fixable by somehow making cgroup_file_release() be tied to the fput(), it would require sizable refactoring at cgroups or higher layer which might be more justifiable if we identify more cases like this. BUG: KASAN: use-after-free in _raw_spin_lock_irqsave+0x60/0xc0 Write of size 4 at addr ffff88810e625328 by task a.out/4404 CPU: 19 PID: 4404 Comm: a.out Not tainted 6.2.0-rc6 #38 Hardware name: Amazon EC2 c5a.8xlarge/, BIOS 1.0 10/16/2017 Call Trace: dump_stack_lvl+0x73/0xa0 print_report+0x16c/0x4e0 kasan_report+0xc3/0xf0 kasan_check_range+0x2d2/0x310 _raw_spin_lock_irqsave+0x60/0xc0 remove_wait_queue+0x1a/0xa0 ep_free+0x12c/0x170 ep_eventpoll_release+0x26/0x30 __fput+0x202/0x400 task_work_run+0x11d/0x170 do_exit+0x495/0x1130 do_group_exit+0x100/0x100 get_signal+0xd67/0xde0 arch_do_signal_or_restart+0x2a/0x2b0 exit_to_user_mode_prepare+0x94/0x100 syscall_exit_to_user_mode+0x20/0x40 do_syscall_64+0x52/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Allocated by task 4404: kasan_set_track+0x3d/0x60 __kasan_kmalloc+0x85/0x90 psi_trigger_create+0x113/0x3e0 pressure_write+0x146/0x2e0 cgroup_file_write+0x11c/0x250 kernfs_fop_write_iter+0x186/0x220 vfs_write+0x3d8/0x5c0 ksys_write+0x90/0x110 do_syscall_64+0x43/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 4407: kasan_set_track+0x3d/0x60 kasan_save_free_info+0x27/0x40 ____kasan_slab_free+0x11d/0x170 slab_free_freelist_hook+0x87/0x150 __kmem_cache_free+0xcb/0x180 psi_trigger_destroy+0x2e8/0x310 cgroup_file_release+0x4f/0xb0 kernfs_drain_open_files+0x165/0x1f0 kernfs_drain+0x162/0x1a0 __kernfs_remove+0x1fb/0x310 kernfs_remove_by_name_ns+0x95/0xe0 cgroup_addrm_files+0x67f/0x700 cgroup_destroy_locked+0x283/0x3c0 cgroup_rmdir+0x29/0x100 kernfs_iop_rmdir+0xd1/0x140 vfs_rmdir+0xfe/0x240 do_rmdir+0x13d/0x280 __x64_sys_rmdir+0x2c/0x30 do_syscall_64+0x43/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: 0e94682b73bf ("psi: introduce psi monitor") Signed-off-by: Munehisa Kamata Signed-off-by: Mengchi Cheng Signed-off-by: Ingo Molnar Acked-by: Suren Baghdasaryan Acked-by: Peter Zijlstra Cc: stable@vger.kernel.org Link: https://lore.kernel.org/lkml/20230106224859.4123476-1-kamatam@amazon.com/ Link: https://lore.kernel.org/r/20230214212705.4058045-1-kamatam@amazon.com Signed-off-by: Greg Kroah-Hartman --- kernel/sched/psi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index b7f38f3ad42a..debaeb07ae53 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -1158,10 +1158,11 @@ void psi_trigger_destroy(struct psi_trigger *t) group = t->group; /* - * Wakeup waiters to stop polling. Can happen if cgroup is deleted - * from under a polling process. + * Wakeup waiters to stop polling and clear the queue to prevent it from + * being accessed later. Can happen if cgroup is deleted from under a + * polling process. */ - wake_up_interruptible(&t->event_wait); + wake_up_pollfree(&t->event_wait); mutex_lock(&group->trigger_lock); From 9662320238b9903e691958add64f4125615a143a Mon Sep 17 00:00:00 2001 From: Mike Kravetz Date: Wed, 15 Feb 2023 17:35:42 -0800 Subject: [PATCH 0027/1017] hugetlb: check for undefined shift on 32 bit architectures commit ec4288fe63966b26d53907212ecd05dfa81dd2cc upstream. Users can specify the hugetlb page size in the mmap, shmget and memfd_create system calls. This is done by using 6 bits within the flags argument to encode the base-2 logarithm of the desired page size. The routine hstate_sizelog() uses the log2 value to find the corresponding hugetlb hstate structure. Converting the log2 value (page_size_log) to potential hugetlb page size is the simple statement: 1UL << page_size_log Because only 6 bits are used for page_size_log, the left shift can not be greater than 63. This is fine on 64 bit architectures where a long is 64 bits. However, if a value greater than 31 is passed on a 32 bit architecture (where long is 32 bits) the shift will result in undefined behavior. This was generally not an issue as the result of the undefined shift had to exactly match hugetlb page size to proceed. Recent improvements in runtime checking have resulted in this undefined behavior throwing errors such as reported below. Fix by comparing page_size_log to BITS_PER_LONG before doing shift. Link: https://lkml.kernel.org/r/20230216013542.138708-1-mike.kravetz@oracle.com Link: https://lore.kernel.org/lkml/CA+G9fYuei_Tr-vN9GS7SfFyU1y9hNysnf=PB7kT0=yv4MiPgVg@mail.gmail.com/ Fixes: 42d7395feb56 ("mm: support more pagesizes for MAP_HUGETLB/SHM_HUGETLB") Signed-off-by: Mike Kravetz Reported-by: Naresh Kamboju Reviewed-by: Jesper Juhl Acked-by: Muchun Song Tested-by: Linux Kernel Functional Testing Tested-by: Naresh Kamboju Cc: Anders Roxell Cc: Andi Kleen Cc: Sasha Levin Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/hugetlb.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index c0ba379574a4..99b73fc4a824 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -542,7 +542,10 @@ static inline struct hstate *hstate_sizelog(int page_size_log) if (!page_size_log) return &default_hstate; - return size_to_hstate(1UL << page_size_log); + if (page_size_log < BITS_PER_LONG) + return size_to_hstate(1UL << page_size_log); + + return NULL; } static inline struct hstate *hstate_vma(struct vm_area_struct *vma) From 1933be146c96b5a707ce297eddfc3c49a9eec775 Mon Sep 17 00:00:00 2001 From: Aaron Thompson Date: Tue, 7 Feb 2023 08:21:51 +0000 Subject: [PATCH 0028/1017] Revert "mm: Always release pages to the buddy allocator in memblock_free_late()." commit 647037adcad00f2bab8828d3d41cd0553d41f3bd upstream. This reverts commit 115d9d77bb0f9152c60b6e8646369fa7f6167593. The pages being freed by memblock_free_late() have already been initialized, but if they are in the deferred init range, __free_one_page() might access nearby uninitialized pages when trying to coalesce buddies. This can, for example, trigger this BUG: BUG: unable to handle page fault for address: ffffe964c02580c8 RIP: 0010:__list_del_entry_valid+0x3f/0x70 __free_one_page+0x139/0x410 __free_pages_ok+0x21d/0x450 memblock_free_late+0x8c/0xb9 efi_free_boot_services+0x16b/0x25c efi_enter_virtual_mode+0x403/0x446 start_kernel+0x678/0x714 secondary_startup_64_no_verify+0xd2/0xdb A proper fix will be more involved so revert this change for the time being. Fixes: 115d9d77bb0f ("mm: Always release pages to the buddy allocator in memblock_free_late().") Signed-off-by: Aaron Thompson Link: https://lore.kernel.org/r/20230207082151.1303-1-dev@aaront.org Signed-off-by: Mike Rapoport (IBM) Signed-off-by: Greg Kroah-Hartman --- mm/memblock.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index f6a4dffb9a88..f72d53957033 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1597,13 +1597,7 @@ void __init __memblock_free_late(phys_addr_t base, phys_addr_t size) end = PFN_DOWN(base + size); for (; cursor < end; cursor++) { - /* - * Reserved pages are always initialized by the end of - * memblock_free_all() (by memmap_init() and, if deferred - * initialization is enabled, memmap_init_reserved_pages()), so - * these pages can be released directly to the buddy allocator. - */ - __free_pages_core(pfn_to_page(cursor), 0); + memblock_free_pages(pfn_to_page(cursor), cursor, 0); totalram_pages_inc(); } } From e2bf52ff159db37b5b60d34069464c00a1f54fd6 Mon Sep 17 00:00:00 2001 From: Felix Riemann Date: Fri, 10 Feb 2023 13:36:44 +0100 Subject: [PATCH 0029/1017] net: Fix unwanted sign extension in netdev_stats_to_stats64() commit 9b55d3f0a69af649c62cbc2633e6d695bb3cc583 upstream. When converting net_device_stats to rtnl_link_stats64 sign extension is triggered on ILP32 machines as 6c1c509778 changed the previous "ulong -> u64" conversion to "long -> u64" by accessing the net_device_stats fields through a (signed) atomic_long_t. This causes for example the received bytes counter to jump to 16EiB after having received 2^31 bytes. Casting the atomic value to "unsigned long" beforehand converting it into u64 avoids this. Fixes: 6c1c5097781f ("net: add atomic_long_t to net_device_stats fields") Signed-off-by: Felix Riemann Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 37bb60a7e97e..b7646d4e079b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10326,7 +10326,7 @@ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64, BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64)); for (i = 0; i < n; i++) - dst[i] = atomic_long_read(&src[i]); + dst[i] = (unsigned long)atomic_long_read(&src[i]); /* zero out counters that only exist in rtnl_link_stats64 */ memset((char *)stats64 + n * sizeof(u64), 0, sizeof(*stats64) - n * sizeof(u64)); From 3a63392c19e95f631a7ed24a215727d059c1feeb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 2 Feb 2023 18:07:35 -0800 Subject: [PATCH 0030/1017] revert "squashfs: harden sanity check in squashfs_read_xattr_id_table" commit a5b21d8d791cd4db609d0bbcaa9e0c7e019888d1 upstream. This fix was nacked by Philip, for reasons identified in the email linked below. Link: https://lkml.kernel.org/r/68f15d67-8945-2728-1f17-5b53a80ec52d@squashfs.org.uk Fixes: 72e544b1b28325 ("squashfs: harden sanity check in squashfs_read_xattr_id_table") Cc: Alexey Khoroshilov Cc: Fedor Pchelkin Cc: Phillip Lougher Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/squashfs/xattr_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c index b88d19e9581e..c8469c656e0d 100644 --- a/fs/squashfs/xattr_id.c +++ b/fs/squashfs/xattr_id.c @@ -76,7 +76,7 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start, /* Sanity check values */ /* there is always at least one xattr id */ - if (*xattr_ids <= 0) + if (*xattr_ids == 0) return ERR_PTR(-EINVAL); len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); From 152a5f32ac9ec497b514130b603e720ed61df575 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Wed, 8 Feb 2023 10:43:32 +0800 Subject: [PATCH 0031/1017] ixgbe: allow to increase MTU to 3K with XDP enabled commit f9cd6a4418bac6a046ee78382423b1ae7565fb24 upstream. Recently I encountered one case where I cannot increase the MTU size directly from 1500 to a much bigger value with XDP enabled if the server is equipped with IXGBE card, which happened on thousands of servers in production environment. After applying the current patch, we can set the maximum MTU size to 3K. This patch follows the behavior of changing MTU as i40e/ice does. References: [1] commit 23b44513c3e6 ("ice: allow 3k MTU for XDP") [2] commit 0c8493d90b6b ("i40e: add XDP support for pass and drop actions") Fixes: fabf1bce103a ("ixgbe: Prevent unsupported configurations with XDP") Signed-off-by: Jason Xing Reviewed-by: Alexander Duyck Tested-by: Chandan Kumar Rout (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index b5b8be4672aa..dbfd0cc3df90 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6728,6 +6728,18 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) ixgbe_free_rx_resources(adapter->rx_ring[i]); } +/** + * ixgbe_max_xdp_frame_size - returns the maximum allowed frame size for XDP + * @adapter: device handle, pointer to adapter + */ +static int ixgbe_max_xdp_frame_size(struct ixgbe_adapter *adapter) +{ + if (PAGE_SIZE >= 8192 || adapter->flags2 & IXGBE_FLAG2_RX_LEGACY) + return IXGBE_RXBUFFER_2K; + else + return IXGBE_RXBUFFER_3K; +} + /** * ixgbe_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -6739,18 +6751,13 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - if (adapter->xdp_prog) { + if (ixgbe_enabled_xdp_adapter(adapter)) { int new_frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; - int i; - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; - - if (new_frame_size > ixgbe_rx_bufsz(ring)) { - e_warn(probe, "Requested MTU size is not supported with XDP\n"); - return -EINVAL; - } + if (new_frame_size > ixgbe_max_xdp_frame_size(adapter)) { + e_warn(probe, "Requested MTU size is not supported with XDP\n"); + return -EINVAL; } } From 23974088fd6a57922abc80ac7d6219572cd48a4f Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Wed, 8 Feb 2023 10:43:33 +0800 Subject: [PATCH 0032/1017] i40e: add double of VLAN header when computing the max MTU commit ce45ffb815e8e238f05de1630be3969b6bb15e4e upstream. Include the second VLAN HLEN into account when computing the maximum MTU size as other drivers do. Fixes: 0c8493d90b6b ("i40e: add XDP support for pass and drop actions") Signed-off-by: Jason Xing Reviewed-by: Alexander Duyck Tested-by: Chandan Kumar Rout (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 2c60d2a93330..c4f4ee34d58a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2788,7 +2788,7 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu) struct i40e_pf *pf = vsi->back; if (i40e_enabled_xdp_vsi(vsi)) { - int frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + int frame_size = new_mtu + I40E_PACKET_HDR_PAD; if (frame_size > i40e_max_xdp_frame_size(vsi)) return -EINVAL; From a5c51e0c3202820192db3f3809e072f3ca2b1177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 8 Feb 2023 10:16:37 +0100 Subject: [PATCH 0033/1017] net: bgmac: fix BCM5358 support by setting correct flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d61615c366a489646a1bfe5b33455f916762d5f4 upstream. Code blocks handling BCMA_CHIP_ID_BCM5357 and BCMA_CHIP_ID_BCM53572 were incorrectly unified. Chip package values are not unique and cannot be checked independently. They are meaningful only in a context of a given chip. Packages BCM5358 and BCM47188 share the same value but then belong to different chips. Code unification resulted in treating BCM5358 as BCM47188 and broke its initialization. Link: https://github.com/openwrt/openwrt/issues/8278 Fixes: cb1b0f90acfe ("net: ethernet: bgmac: unify code of the same family") Cc: Jon Mason Signed-off-by: Rafał Miłecki Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20230208091637.16291-1-zajec5@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bgmac-bcma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c index 26746197515f..022aebb68f46 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -228,12 +228,12 @@ static int bgmac_probe(struct bcma_device *core) bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (ci->pkg == BCMA_PKG_ID_BCM47188 || - ci->pkg == BCMA_PKG_ID_BCM47186) { + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) || + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188)) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } - if (ci->pkg == BCMA_PKG_ID_BCM5358) + if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM5358) bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII; break; case BCMA_CHIP_ID_BCM53573: From 747a17e25aecb4ea8a66427058e0d2d2a25046ad Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Thu, 9 Feb 2023 12:13:05 +0000 Subject: [PATCH 0034/1017] sctp: sctp_sock_filter(): avoid list_entry() on possibly empty list commit a1221703a0f75a9d81748c516457e0fc76951496 upstream. Use list_is_first() to check whether tsp->asoc matches the first element of ep->asocs, as the list is not guaranteed to have an entry. Fixes: 8f840e47f190 ("sctp: add the sctp_diag.c file") Signed-off-by: Pietro Borrello Acked-by: Xin Long Link: https://lore.kernel.org/r/20230208-sctp-filter-v2-1-6e1f4017f326@diag.uniroma1.it Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sctp/diag.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/sctp/diag.c b/net/sctp/diag.c index 68ff82ff49a3..07d0ada23bfd 100644 --- a/net/sctp/diag.c +++ b/net/sctp/diag.c @@ -349,11 +349,9 @@ static int sctp_sock_filter(struct sctp_endpoint *ep, struct sctp_transport *tsp struct sctp_comm_param *commp = p; struct sock *sk = ep->base.sk; const struct inet_diag_req_v2 *r = commp->r; - struct sctp_association *assoc = - list_entry(ep->asocs.next, struct sctp_association, asocs); /* find the ep only once through the transports by this condition */ - if (tsp->asoc != assoc) + if (!list_is_first(&tsp->asoc->asocs, &ep->asocs)) return 0; if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family) From eb8e9d8572d1d9df17272783ad8a84843ce559d4 Mon Sep 17 00:00:00 2001 From: Pedro Tammela Date: Thu, 9 Feb 2023 11:37:39 -0300 Subject: [PATCH 0035/1017] net/sched: tcindex: update imperfect hash filters respecting rcu commit ee059170b1f7e94e55fa6cadee544e176a6e59c2 upstream. The imperfect hash area can be updated while packets are traversing, which will cause a use-after-free when 'tcf_exts_exec()' is called with the destroyed tcf_ext. CPU 0: CPU 1: tcindex_set_parms tcindex_classify tcindex_lookup tcindex_lookup tcf_exts_change tcf_exts_exec [UAF] Stop operating on the shared area directly, by using a local copy, and update the filter with 'rcu_replace_pointer()'. Delete the old filter version only after a rcu grace period elapsed. Fixes: 9b0d4446b569 ("net: sched: avoid atomic swap in tcf_exts_change") Reported-by: valis Suggested-by: valis Signed-off-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela Link: https://lore.kernel.org/r/20230209143739.279867-1-pctammela@mojatatu.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sched/cls_tcindex.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 86250221d08d..50bf7ec4b5b2 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -338,6 +339,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, struct tcf_result cr = {}; int err, balloc = 0; struct tcf_exts e; + bool update_h = false; err = tcf_exts_init(&e, net, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); if (err < 0) @@ -455,10 +457,13 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, } } - if (cp->perfect) + if (cp->perfect) { r = cp->perfect + handle; - else - r = tcindex_lookup(cp, handle) ? : &new_filter_result; + } else { + /* imperfect area is updated in-place using rcu */ + update_h = !!tcindex_lookup(cp, handle); + r = &new_filter_result; + } if (r == &new_filter_result) { f = kzalloc(sizeof(*f), GFP_KERNEL); @@ -484,7 +489,28 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, rcu_assign_pointer(tp->root, cp); - if (r == &new_filter_result) { + if (update_h) { + struct tcindex_filter __rcu **fp; + struct tcindex_filter *cf; + + f->result.res = r->res; + tcf_exts_change(&f->result.exts, &r->exts); + + /* imperfect area bucket */ + fp = cp->h + (handle % cp->hash); + + /* lookup the filter, guaranteed to exist */ + for (cf = rcu_dereference_bh_rtnl(*fp); cf; + fp = &cf->next, cf = rcu_dereference_bh_rtnl(*fp)) + if (cf->key == handle) + break; + + f->next = cf->next; + + cf = rcu_replace_pointer(*fp, f, 1); + tcf_exts_get_net(&cf->result.exts); + tcf_queue_work(&cf->rwork, tcindex_destroy_fexts_work); + } else if (r == &new_filter_result) { struct tcindex_filter *nfp; struct tcindex_filter __rcu **fp; From 9d68bfa2205d249f705469d6799d0e081ac2b017 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 9 Feb 2023 16:22:01 -0800 Subject: [PATCH 0036/1017] dccp/tcp: Avoid negative sk_forward_alloc by ipv6_pinfo.pktoptions. commit ca43ccf41224b023fc290073d5603a755fd12eed upstream. Eric Dumazet pointed out [0] that when we call skb_set_owner_r() for ipv6_pinfo.pktoptions, sk_rmem_schedule() has not been called, resulting in a negative sk_forward_alloc. We add a new helper which clones a skb and sets its owner only when sk_rmem_schedule() succeeds. Note that we move skb_set_owner_r() forward in (dccp|tcp)_v6_do_rcv() because tcp_send_synack() can make sk_forward_alloc negative before ipv6_opt_accepted() in the crossed SYN-ACK or self-connect() cases. [0]: https://lore.kernel.org/netdev/CANn89iK9oc20Jdi_41jb9URdF210r7d1Y-+uypbMSbOfY6jqrg@mail.gmail.com/ Fixes: 323fbd0edf3f ("net: dccp: Add handling of IPV6_PKTOPTIONS to dccp_v6_do_rcv()") Fixes: 3df80d9320bc ("[DCCP]: Introduce DCCPv6") Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- include/net/sock.h | 13 +++++++++++++ net/dccp/ipv6.c | 7 ++----- net/ipv6/tcp_ipv6.c | 10 +++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 69bbbe8bbf34..0f48d50a6dde 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2243,6 +2243,19 @@ static inline __must_check bool skb_set_owner_sk_safe(struct sk_buff *skb, struc return false; } +static inline struct sk_buff *skb_clone_and_charge_r(struct sk_buff *skb, struct sock *sk) +{ + skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC)); + if (skb) { + if (sk_rmem_schedule(sk, skb, skb->truesize)) { + skb_set_owner_r(skb, sk); + return skb; + } + __kfree_skb(skb); + } + return NULL; +} + void sk_reset_timer(struct sock *sk, struct timer_list *timer, unsigned long expires); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 21c61a9c3b15..c563f9b325d0 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -541,11 +541,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk, *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL); /* Clone pktoptions received with SYN, if we own the req */ if (*own_req && ireq->pktopts) { - newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC); + newnp->pktoptions = skb_clone_and_charge_r(ireq->pktopts, newsk); consume_skb(ireq->pktopts); ireq->pktopts = NULL; - if (newnp->pktoptions) - skb_set_owner_r(newnp->pktoptions, newsk); } return newsk; @@ -605,7 +603,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) --ANK (980728) */ if (np->rxopt.all) - opt_skb = skb_clone(skb, GFP_ATOMIC); + opt_skb = skb_clone_and_charge_r(skb, sk); if (sk->sk_state == DCCP_OPEN) { /* Fast path */ if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) @@ -669,7 +667,6 @@ ipv6_pktoptions: np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); if (ipv6_opt_accepted(sk, opt_skb, &DCCP_SKB_CB(opt_skb)->header.h6)) { - skb_set_owner_r(opt_skb, sk); memmove(IP6CB(opt_skb), &DCCP_SKB_CB(opt_skb)->header.h6, sizeof(struct inet6_skb_parm)); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c599e14be414..6df042863860 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1406,14 +1406,11 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * /* Clone pktoptions received with SYN, if we own the req */ if (ireq->pktopts) { - newnp->pktoptions = skb_clone(ireq->pktopts, - sk_gfp_mask(sk, GFP_ATOMIC)); + newnp->pktoptions = skb_clone_and_charge_r(ireq->pktopts, newsk); consume_skb(ireq->pktopts); ireq->pktopts = NULL; - if (newnp->pktoptions) { + if (newnp->pktoptions) tcp_v6_restore_cb(newnp->pktoptions); - skb_set_owner_r(newnp->pktoptions, newsk); - } } } else { if (!req_unhash && found_dup_sk) { @@ -1481,7 +1478,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) --ANK (980728) */ if (np->rxopt.all) - opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC)); + opt_skb = skb_clone_and_charge_r(skb, sk); if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ struct dst_entry *dst; @@ -1563,7 +1560,6 @@ ipv6_pktoptions: if (np->repflow) np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) { - skb_set_owner_r(opt_skb, sk); tcp_v6_restore_cb(opt_skb); opt_skb = xchg(&np->pktoptions, opt_skb); } else { From 525bdcb0838d19d918c7786151ee14661967a030 Mon Sep 17 00:00:00 2001 From: Miko Larsson Date: Fri, 10 Feb 2023 09:13:44 +0100 Subject: [PATCH 0037/1017] net/usb: kalmia: Don't pass act_len in usb_bulk_msg error path commit c68f345b7c425b38656e1791a0486769a8797016 upstream. syzbot reported that act_len in kalmia_send_init_packet() is uninitialized when passing it to the first usb_bulk_msg error path. Jiri Pirko noted that it's pointless to pass it in the error path, and that the value that would be printed in the second error path would be the value of act_len from the first call to usb_bulk_msg.[1] With this in mind, let's just not pass act_len to the usb_bulk_msg error paths. 1: https://lore.kernel.org/lkml/Y9pY61y1nwTuzMOa@nanopsycho/ Fixes: d40261236e8e ("net/usb: Add Samsung Kalmia driver for Samsung GT-B3730") Reported-and-tested-by: syzbot+cd80c5ef5121bfe85b55@syzkaller.appspotmail.com Signed-off-by: Miko Larsson Reviewed-by: Alexander Duyck Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/kalmia.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index fc5895f85cee..a552bb1665b8 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -65,8 +65,8 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len, init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT); if (status != 0) { netdev_err(dev->net, - "Error sending init packet. Status %i, length %i\n", - status, act_len); + "Error sending init packet. Status %i\n", + status); return status; } else if (act_len != init_msg_len) { @@ -83,8 +83,8 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len, if (status != 0) netdev_err(dev->net, - "Error receiving init result. Status %i, length %i\n", - status, act_len); + "Error receiving init result. Status %i\n", + status); else if (act_len != expected_len) netdev_err(dev->net, "Unexpected init result length: %i\n", act_len); From c0f65ee0a3329eb4b94beaef0268633696e2d0c6 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Fri, 10 Feb 2023 10:05:51 +0800 Subject: [PATCH 0038/1017] net: openvswitch: fix possible memory leak in ovs_meter_cmd_set() commit 2fa28f5c6fcbfc794340684f36d2581b4f2d20b5 upstream. old_meter needs to be free after it is detached regardless of whether the new meter is successfully attached. Fixes: c7c4c44c9a95 ("net: openvswitch: expand the meters supported number") Signed-off-by: Hangyu Hua Acked-by: Eelco Chaudron Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/openvswitch/meter.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/meter.c b/net/openvswitch/meter.c index e594b4d6b58a..0cf3dda5319f 100644 --- a/net/openvswitch/meter.c +++ b/net/openvswitch/meter.c @@ -450,7 +450,7 @@ static int ovs_meter_cmd_set(struct sk_buff *skb, struct genl_info *info) err = attach_meter(meter_tbl, meter); if (err) - goto exit_unlock; + goto exit_free_old_meter; ovs_unlock(); @@ -473,6 +473,8 @@ static int ovs_meter_cmd_set(struct sk_buff *skb, struct genl_info *info) genlmsg_end(reply, ovs_reply_header); return genlmsg_reply(reply, info); +exit_free_old_meter: + ovs_meter_free(old_meter); exit_unlock: ovs_unlock(); nlmsg_free(reply); From cc7ca4871a92611d537b75a2a8e466106782bb31 Mon Sep 17 00:00:00 2001 From: Johannes Zink Date: Fri, 10 Feb 2023 15:39:37 +0100 Subject: [PATCH 0039/1017] net: stmmac: fix order of dwmac5 FlexPPS parametrization sequence commit 4562c65ec852067c6196abdcf2d925f08841dcbc upstream. So far changing the period by just setting new period values while running did not work. The order as indicated by the publicly available reference manual of the i.MX8MP [1] indicates a sequence: * initiate the programming sequence * set the values for PPS period and start time * start the pulse train generation. This is currently not used in dwmac5_flex_pps_config(), which instead does: * initiate the programming sequence and immediately start the pulse train generation * set the values for PPS period and start time This caused the period values written not to take effect until the FlexPPS output was disabled and re-enabled again. This patch fix the order and allows the period to be set immediately. [1] https://www.nxp.com/webapp/Download?colCode=IMX8MPRM Fixes: 9a8a02c9d46d ("net: stmmac: Add Flexible PPS support") Signed-off-by: Johannes Zink Link: https://lore.kernel.org/r/20230210143937.3427483-1-j.zink@pengutronix.de Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c index de5255b951e1..d1b8b51bf6ad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c @@ -520,9 +520,9 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index, return 0; } - val |= PPSCMDx(index, 0x2); val |= TRGTMODSELx(index, 0x2); val |= PPSEN0; + writel(val, ioaddr + MAC_PPS_CONTROL); writel(cfg->start.tv_sec, ioaddr + MAC_PPSx_TARGET_TIME_SEC(index)); @@ -547,6 +547,7 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index, writel(period - 1, ioaddr + MAC_PPSx_WIDTH(index)); /* Finally, activate it */ + val |= PPSCMDx(index, 0x2); writel(val, ioaddr + MAC_PPS_CONTROL); return 0; } From 7eb8ebb5e83f8fdbac2eda1f81ed70048cbdb090 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 10 Feb 2023 12:31:55 -0500 Subject: [PATCH 0040/1017] bnxt_en: Fix mqprio and XDP ring checking logic commit 2038cc592811209de20c4e094ca08bfb1e6fbc6c upstream. In bnxt_reserve_rings(), there is logic to check that the number of TX rings reserved is enough to cover all the mqprio TCs, but it fails to account for the TX XDP rings. So the check will always fail if there are mqprio TCs and TX XDP rings. As a result, the driver always fails to initialize after the XDP program is attached and the device will be brought down. A subsequent ifconfig up will also fail because the number of TX rings is set to an inconsistent number. Fix the check to properly account for TX XDP rings. If the check fails, set the number of TX rings back to a consistent number after calling netdev_reset_tc(). Fixes: 674f50a5b026 ("bnxt_en: Implement new method to reserve rings.") Reviewed-by: Hongguang Gao Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 92f54e333395..c4a768ce8c99 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8761,10 +8761,14 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init) netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc); return rc; } - if (tcs && (bp->tx_nr_rings_per_tc * tcs != bp->tx_nr_rings)) { + if (tcs && (bp->tx_nr_rings_per_tc * tcs != + bp->tx_nr_rings - bp->tx_nr_rings_xdp)) { netdev_err(bp->dev, "tx ring reservation failure\n"); netdev_reset_tc(bp->dev); - bp->tx_nr_rings_per_tc = bp->tx_nr_rings; + if (bp->tx_nr_rings_xdp) + bp->tx_nr_rings_per_tc = bp->tx_nr_rings_xdp; + else + bp->tx_nr_rings_per_tc = bp->tx_nr_rings; return -ENOMEM; } return 0; From 2dd914105a1e59df820edee3a408f480f65c3705 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Fri, 10 Feb 2023 22:21:26 +0200 Subject: [PATCH 0041/1017] net: stmmac: Restrict warning on disabling DMA store and fwd mode commit 05d7623a892a9da62da0e714428e38f09e4a64d8 upstream. When setting 'snps,force_thresh_dma_mode' DT property, the following warning is always emitted, regardless the status of force_sf_dma_mode: dwmac-starfive 10020000.ethernet: force_sf_dma_mode is ignored if force_thresh_dma_mode is set. Do not print the rather misleading message when DMA store and forward mode is already disabled. Fixes: e2a240c7d3bc ("driver:net:stmmac: Disable DMA store and forward mode if platform data force_thresh_dma_mode is set.") Signed-off-by: Cristian Ciocaltea Link: https://lore.kernel.org/r/20230210202126.877548-1-cristian.ciocaltea@collabora.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 1ed74cfb61fc..f02ce09020fb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -559,7 +559,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst"); plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode"); - if (plat->force_thresh_dma_mode) { + if (plat->force_thresh_dma_mode && plat->force_sf_dma_mode) { plat->force_sf_dma_mode = 0; dev_warn(&pdev->dev, "force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n"); From 7ff0fdba82298d1f456c685e24930da89703c0fb Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Mon, 13 Feb 2023 22:53:55 -0800 Subject: [PATCH 0042/1017] net: mpls: fix stale pointer if allocation fails during device rename commit fda6c89fe3d9aca073495a664e1d5aea28cd4377 upstream. lianhui reports that when MPLS fails to register the sysctl table under new location (during device rename) the old pointers won't get overwritten and may be freed again (double free). Handle this gracefully. The best option would be unregistering the MPLS from the device completely on failure, but unfortunately mpls_ifdown() can fail. So failing fully is also unreliable. Another option is to register the new table first then only remove old one if the new one succeeds. That requires more code, changes order of notifications and two tables may be visible at the same time. sysctl point is not used in the rest of the code - set to NULL on failures and skip unregister if already NULL. Reported-by: lianhui tang Fixes: 0fae3bf018d9 ("mpls: handle device renames for per-device sysctls") Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/mpls/af_mpls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 72398149e4d4..1dcbdab9319b 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1427,6 +1427,7 @@ static int mpls_dev_sysctl_register(struct net_device *dev, free: kfree(table); out: + mdev->sysctl = NULL; return -ENOBUFS; } @@ -1436,6 +1437,9 @@ static void mpls_dev_sysctl_unregister(struct net_device *dev, struct net *net = dev_net(dev); struct ctl_table *table; + if (!mdev->sysctl) + return; + table = mdev->sysctl->ctl_table_arg; unregister_net_sysctl_table(mdev->sysctl); kfree(table); From 1a4a5fd652dd6f84eb7ca1ac4cba682196e3ea7d Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Thu, 9 Feb 2023 10:41:28 +0800 Subject: [PATCH 0043/1017] ixgbe: add double of VLAN header when computing the max MTU commit 0967bf837784a11c65d66060623a74e65211af0b upstream. Include the second VLAN HLEN into account when computing the maximum MTU size as other drivers do. Fixes: fabf1bce103a ("ixgbe: Prevent unsupported configurations with XDP") Signed-off-by: Jason Xing Reviewed-by: Alexander Duyck Tested-by: Chandan Kumar Rout (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 27c6f911737b..18251edbfabf 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -67,6 +67,8 @@ #define IXGBE_RXBUFFER_4K 4096 #define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */ +#define IXGBE_PKT_HDR_PAD (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2)) + /* Attempt to maximize the headroom available for incoming frames. We * use a 2K buffer for receives and need 1536/1534 to store the data for * the frame. This leaves us with 512 bytes of room. From that we need diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index dbfd0cc3df90..5c542f5d2b20 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6752,8 +6752,7 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) struct ixgbe_adapter *adapter = netdev_priv(netdev); if (ixgbe_enabled_xdp_adapter(adapter)) { - int new_frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + - VLAN_HLEN; + int new_frame_size = new_mtu + IXGBE_PKT_HDR_PAD; if (new_frame_size > ixgbe_max_xdp_frame_size(adapter)) { e_warn(probe, "Requested MTU size is not supported with XDP\n"); From 5337bb508ba2b9cb086472def6c0aa0c832ca9d7 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Wed, 8 Feb 2023 18:13:59 +0100 Subject: [PATCH 0044/1017] ipv6: Fix datagram socket connection with DSCP. commit e010ae08c71fda8be3d6bda256837795a0b3ea41 upstream. Take into account the IPV6_TCLASS socket option (DSCP) in ip6_datagram_flow_key_init(). Otherwise fib6_rule_match() can't properly match the DSCP value, resulting in invalid route lookup. For example: ip route add unreachable table main 2001:db8::10/124 ip route add table 100 2001:db8::10/124 dev eth0 ip -6 rule add dsfield 0x04 table 100 echo test | socat - UDP6:[2001:db8::11]:54321,ipv6-tclass=0x04 Without this patch, socat fails at connect() time ("No route to host") because the fib-rule doesn't jump to table 100 and the lookup ends up being done in the main table. Fixes: 2cc67cc731d9 ("[IPV6] ROUTE: Routing by Traffic Class.") Signed-off-by: Guillaume Nault Reviewed-by: Eric Dumazet Reviewed-by: David Ahern Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/ipv6/datagram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f4559e5bc84b..a30ff5d6808a 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -51,7 +51,7 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk) fl6->flowi6_mark = sk->sk_mark; fl6->fl6_dport = inet->inet_dport; fl6->fl6_sport = inet->inet_sport; - fl6->flowlabel = np->flow_label; + fl6->flowlabel = ip6_make_flowinfo(np->tclass, np->flow_label); fl6->flowi6_uid = sk->sk_uid; if (!fl6->flowi6_oif) From 7546fb3554df580e49b490c21a61dd3c38212571 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Wed, 8 Feb 2023 18:14:03 +0100 Subject: [PATCH 0045/1017] ipv6: Fix tcp socket connection with DSCP. commit 8230680f36fd1525303d1117768c8852314c488c upstream. Take into account the IPV6_TCLASS socket option (DSCP) in tcp_v6_connect(). Otherwise fib6_rule_match() can't properly match the DSCP value, resulting in invalid route lookup. For example: ip route add unreachable table main 2001:db8::10/124 ip route add table 100 2001:db8::10/124 dev eth0 ip -6 rule add dsfield 0x04 table 100 echo test | socat - TCP6:[2001:db8::11]:54321,ipv6-tclass=0x04 Without this patch, socat fails at connect() time ("No route to host") because the fib-rule doesn't jump to table 100 and the lookup ends up being done in the main table. Fixes: 2cc67cc731d9 ("[IPV6] ROUTE: Routing by Traffic Class.") Signed-off-by: Guillaume Nault Reviewed-by: Eric Dumazet Reviewed-by: David Ahern Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/ipv6/tcp_ipv6.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6df042863860..e4ae5362cb51 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -269,6 +269,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, fl6.flowi6_proto = IPPROTO_TCP; fl6.daddr = sk->sk_v6_daddr; fl6.saddr = saddr ? *saddr : np->saddr; + fl6.flowlabel = ip6_make_flowinfo(np->tclass, np->flow_label); fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = usin->sin6_port; From 0ee5ed0126a2211f7174492da2ca2c29f43755c5 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Wed, 15 Feb 2023 07:40:43 +0900 Subject: [PATCH 0046/1017] nilfs2: fix underflow in second superblock position calculations commit 99b9402a36f0799f25feee4465bfa4b8dfa74b4d upstream. Macro NILFS_SB2_OFFSET_BYTES, which computes the position of the second superblock, underflows when the argument device size is less than 4096 bytes. Therefore, when using this macro, it is necessary to check in advance that the device size is not less than a lower limit, or at least that underflow does not occur. The current nilfs2 implementation lacks this check, causing out-of-bound block access when mounting devices smaller than 4096 bytes: I/O error, dev loop0, sector 36028797018963960 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2 NILFS (loop0): unable to read secondary superblock (blocksize = 1024) In addition, when trying to resize the filesystem to a size below 4096 bytes, this underflow occurs in nilfs_resize_fs(), passing a huge number of segments to nilfs_sufile_resize(), corrupting parameters such as the number of segments in superblocks. This causes excessive loop iterations in nilfs_sufile_resize() during a subsequent resize ioctl, causing semaphore ns_segctor_sem to block for a long time and hang the writer thread: INFO: task segctord:5067 blocked for more than 143 seconds. Not tainted 6.2.0-rc8-syzkaller-00015-gf6feea56f66d #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:segctord state:D stack:23456 pid:5067 ppid:2 flags:0x00004000 Call Trace: context_switch kernel/sched/core.c:5293 [inline] __schedule+0x1409/0x43f0 kernel/sched/core.c:6606 schedule+0xc3/0x190 kernel/sched/core.c:6682 rwsem_down_write_slowpath+0xfcf/0x14a0 kernel/locking/rwsem.c:1190 nilfs_transaction_lock+0x25c/0x4f0 fs/nilfs2/segment.c:357 nilfs_segctor_thread_construct fs/nilfs2/segment.c:2486 [inline] nilfs_segctor_thread+0x52f/0x1140 fs/nilfs2/segment.c:2570 kthread+0x270/0x300 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308 ... Call Trace: folio_mark_accessed+0x51c/0xf00 mm/swap.c:515 __nilfs_get_page_block fs/nilfs2/page.c:42 [inline] nilfs_grab_buffer+0x3d3/0x540 fs/nilfs2/page.c:61 nilfs_mdt_submit_block+0xd7/0x8f0 fs/nilfs2/mdt.c:121 nilfs_mdt_read_block+0xeb/0x430 fs/nilfs2/mdt.c:176 nilfs_mdt_get_block+0x12d/0xbb0 fs/nilfs2/mdt.c:251 nilfs_sufile_get_segment_usage_block fs/nilfs2/sufile.c:92 [inline] nilfs_sufile_truncate_range fs/nilfs2/sufile.c:679 [inline] nilfs_sufile_resize+0x7a3/0x12b0 fs/nilfs2/sufile.c:777 nilfs_resize_fs+0x20c/0xed0 fs/nilfs2/super.c:422 nilfs_ioctl_resize fs/nilfs2/ioctl.c:1033 [inline] nilfs_ioctl+0x137c/0x2440 fs/nilfs2/ioctl.c:1301 ... This fixes these issues by inserting appropriate minimum device size checks or anti-underflow checks, depending on where the macro is used. Link: https://lkml.kernel.org/r/0000000000004e1dfa05f4a48e6b@google.com Link: https://lkml.kernel.org/r/20230214224043.24141-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi Reported-by: Tested-by: Ryusuke Konishi Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/nilfs2/ioctl.c | 7 +++++++ fs/nilfs2/super.c | 9 +++++++++ fs/nilfs2/the_nilfs.c | 8 +++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 07d26f61f22a..3a1dea5d1448 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -1129,7 +1129,14 @@ static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp) minseg = range[0] + segbytes - 1; do_div(minseg, segbytes); + + if (range[1] < 4096) + goto out; + maxseg = NILFS_SB2_OFFSET_BYTES(range[1]); + if (maxseg < segbytes) + goto out; + do_div(maxseg, segbytes); maxseg--; diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 7a41c9727c9e..775184868763 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -408,6 +408,15 @@ int nilfs_resize_fs(struct super_block *sb, __u64 newsize) if (newsize > devsize) goto out; + /* + * Prevent underflow in second superblock position calculation. + * The exact minimum size check is done in nilfs_sufile_resize(). + */ + if (newsize < 4096) { + ret = -ENOSPC; + goto out; + } + /* * Write lock is required to protect some functions depending * on the number of segments, the number of reserved segments, diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 211937054c31..38a1206cf948 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -544,9 +544,15 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs, { struct nilfs_super_block **sbp = nilfs->ns_sbp; struct buffer_head **sbh = nilfs->ns_sbh; - u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size); + u64 sb2off, devsize = nilfs->ns_bdev->bd_inode->i_size; int valid[2], swp = 0; + if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) { + nilfs_err(sb, "device size too small"); + return -EINVAL; + } + sb2off = NILFS_SB2_OFFSET_BYTES(devsize); + sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize, &sbh[0]); sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]); From 210e6011806acba0bc7ad57b1cf24be7ba76d836 Mon Sep 17 00:00:00 2001 From: Raviteja Goud Talla Date: Fri, 3 Dec 2021 20:26:03 +0530 Subject: [PATCH 0047/1017] drm/i915/gen11: Moving WAs to icl_gt_workarounds_init() [ Upstream commit 67b858dd89932086ae0ee2d0ce4dd070a2c88bb3 ] Bspec page says "Reset: BUS", Accordingly moving w/a's: Wa_1407352427,Wa_1406680159 to proper function icl_gt_workarounds_init() Which will resolve guc enabling error v2: - Previous patch rev2 was created by email client which caused the Build failure, This v2 is to resolve the previous broken series Reviewed-by: John Harrison Signed-off-by: Raviteja Goud Talla Signed-off-by: John Harrison Link: https://patchwork.freedesktop.org/patch/msgid/20211203145603.4006937-1-ravitejax.goud.talla@intel.com Stable-dep-of: d5a1224aa68c ("drm/i915/gen11: Wa_1408615072/Wa_1407596294 should be on GT list") Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 4a3bde7c9f21..5c92789504d0 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1212,6 +1212,15 @@ icl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) GAMT_CHKN_BIT_REG, GAMT_CHKN_DISABLE_L3_COH_PIPE); + /* Wa_1407352427:icl,ehl */ + wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2, + PSDUNIT_CLKGATE_DIS); + + /* Wa_1406680159:icl,ehl */ + wa_write_or(wal, + SUBSLICE_UNIT_LEVEL_CLKGATE, + GWUNIT_CLKGATE_DIS); + /* Wa_1607087056:icl,ehl,jsl */ if (IS_ICELAKE(i915) || IS_EHL_REVID(i915, EHL_REVID_A0, EHL_REVID_A0)) { @@ -1823,15 +1832,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); - /* Wa_1407352427:icl,ehl */ - wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2, - PSDUNIT_CLKGATE_DIS); - - /* Wa_1406680159:icl,ehl */ - wa_write_or(wal, - SUBSLICE_UNIT_LEVEL_CLKGATE, - GWUNIT_CLKGATE_DIS); - /* * Wa_1408767742:icl[a2..forever],ehl[all] * Wa_1605460711:icl[a0..c0] From 1d76a844487490fbb2165953d5523ed9feb3cdc4 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Wed, 1 Feb 2023 14:28:29 -0800 Subject: [PATCH 0048/1017] drm/i915/gen11: Wa_1408615072/Wa_1407596294 should be on GT list [ Upstream commit d5a1224aa68c8b124a4c5c390186e571815ed390 ] The UNSLICE_UNIT_LEVEL_CLKGATE register programmed by this workaround has 'BUS' style reset, indicating that it does not lose its value on engine resets. Furthermore, this register is part of the GT forcewake domain rather than the RENDER domain, so it should not be impacted by RCS engine resets. As such, we should implement this on the GT workaround list rather than an engine list. Bspec: 19219 Fixes: 3551ff928744 ("drm/i915/gen11: Moving WAs to rcs_engine_wa_init()") Signed-off-by: Matt Roper Reviewed-by: Gustavo Sousa Link: https://patchwork.freedesktop.org/patch/msgid/20230201222831.608281-2-matthew.d.roper@intel.com (cherry picked from commit 5f21dc07b52eb54a908e66f5d6e05a87bcb5b049) Signed-off-by: Rodrigo Vivi Signed-off-by: Sasha Levin --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 5c92789504d0..ae5cf2b55e15 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1212,6 +1212,13 @@ icl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) GAMT_CHKN_BIT_REG, GAMT_CHKN_DISABLE_L3_COH_PIPE); + /* + * Wa_1408615072:icl,ehl (vsunit) + * Wa_1407596294:icl,ehl (hsunit) + */ + wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, + VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); + /* Wa_1407352427:icl,ehl */ wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2, PSDUNIT_CLKGATE_DIS); @@ -1825,13 +1832,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) wa_masked_en(wal, GEN9_CSFE_CHICKEN1_RCS, GEN11_ENABLE_32_PLANE_MODE); - /* - * Wa_1408615072:icl,ehl (vsunit) - * Wa_1407596294:icl,ehl (hsunit) - */ - wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, - VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); - /* * Wa_1408767742:icl[a2..forever],ehl[all] * Wa_1605460711:icl[a0..c0] From 015ea70d72c3449ab708024521bcdce7aad58aba Mon Sep 17 00:00:00 2001 From: Baowen Zheng Date: Fri, 17 Dec 2021 19:16:17 +0100 Subject: [PATCH 0049/1017] flow_offload: fill flags to action structure [ Upstream commit 40bd094d65fc9f83941b024cde7c24516f036879 ] Fill flags to action structure to allow user control if the action should be offloaded to hardware or not. Signed-off-by: Baowen Zheng Signed-off-by: Louis Peens Signed-off-by: Simon Horman Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller Stable-dep-of: 21c167aa0ba9 ("net/sched: act_ctinfo: use percpu stats") Signed-off-by: Sasha Levin --- net/sched/act_bpf.c | 2 +- net/sched/act_connmark.c | 2 +- net/sched/act_ctinfo.c | 2 +- net/sched/act_gate.c | 2 +- net/sched/act_ife.c | 2 +- net/sched/act_ipt.c | 2 +- net/sched/act_mpls.c | 2 +- net/sched/act_nat.c | 2 +- net/sched/act_pedit.c | 2 +- net/sched/act_police.c | 2 +- net/sched/act_sample.c | 2 +- net/sched/act_simple.c | 2 +- net/sched/act_skbedit.c | 2 +- net/sched/act_skbmod.c | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index a4c7ba35a343..78f1cd70c8d1 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c @@ -307,7 +307,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla, ret = tcf_idr_check_alloc(tn, &index, act, bind); if (!ret) { ret = tcf_idr_create(tn, index, est, act, - &act_bpf_ops, bind, true, 0); + &act_bpf_ops, bind, true, flags); if (ret < 0) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index 31d268eedf3f..b6576a250e85 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c @@ -124,7 +124,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, ret = tcf_idr_check_alloc(tn, &index, a, bind); if (!ret) { ret = tcf_idr_create(tn, index, est, a, - &act_connmark_ops, bind, false, 0); + &act_connmark_ops, bind, false, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c index 06c74f22ab98..9bde94e7bb93 100644 --- a/net/sched/act_ctinfo.c +++ b/net/sched/act_ctinfo.c @@ -212,7 +212,7 @@ static int tcf_ctinfo_init(struct net *net, struct nlattr *nla, err = tcf_idr_check_alloc(tn, &index, a, bind); if (!err) { ret = tcf_idr_create(tn, index, est, a, - &act_ctinfo_ops, bind, false, 0); + &act_ctinfo_ops, bind, false, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c index a78cb7965718..0e7568a06351 100644 --- a/net/sched/act_gate.c +++ b/net/sched/act_gate.c @@ -357,7 +357,7 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, if (!err) { ret = tcf_idr_create(tn, index, est, a, - &act_gate_ops, bind, false, 0); + &act_gate_ops, bind, false, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index a2ddea04183a..99548b2a1bc8 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -553,7 +553,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, &act_ife_ops, - bind, true, 0); + bind, true, flags); if (ret) { tcf_idr_cleanup(tn, index); kfree(p); diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 8dc3bec0d325..080f2952cd53 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -144,7 +144,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, ops, bind, - false, 0); + false, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c index 09799412b248..47b963ded4e4 100644 --- a/net/sched/act_mpls.c +++ b/net/sched/act_mpls.c @@ -254,7 +254,7 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, - &act_mpls_ops, bind, true, 0); + &act_mpls_ops, bind, true, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 1ebd2a86d980..8466dc25fe39 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -61,7 +61,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, err = tcf_idr_check_alloc(tn, &index, a, bind); if (!err) { ret = tcf_idr_create(tn, index, est, a, - &act_nat_ops, bind, false, 0); + &act_nat_ops, bind, false, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 0d5463ddfd62..db0d3bff19eb 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -189,7 +189,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, err = tcf_idr_check_alloc(tn, &index, a, bind); if (!err) { ret = tcf_idr_create(tn, index, est, a, - &act_pedit_ops, bind, false, 0); + &act_pedit_ops, bind, false, flags); if (ret) { tcf_idr_cleanup(tn, index); goto out_free; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 380733588959..c30cd3ecb391 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -87,7 +87,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, NULL, a, - &act_police_ops, bind, true, 0); + &act_police_ops, bind, true, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 3ebf9ede3cf1..2f0e98bcf494 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c @@ -69,7 +69,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, - &act_sample_ops, bind, true, 0); + &act_sample_ops, bind, true, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index a4f3d0f0daa9..b9bbc87a87c5 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -128,7 +128,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, - &act_simp_ops, bind, false, 0); + &act_simp_ops, bind, false, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index e5f3fb8b00e3..a5661f2d93e9 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -176,7 +176,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, - &act_skbedit_ops, bind, true, 0); + &act_skbedit_ops, bind, true, act_flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index 8d17a543cc9f..aa98dcac94b9 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c @@ -147,7 +147,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, if (!exists) { ret = tcf_idr_create(tn, index, est, a, - &act_skbmod_ops, bind, true, 0); + &act_skbmod_ops, bind, true, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; From 5dfa51dbfc123fb42ce3464a3124e5cd758e0c59 Mon Sep 17 00:00:00 2001 From: Pedro Tammela Date: Fri, 10 Feb 2023 17:08:25 -0300 Subject: [PATCH 0050/1017] net/sched: act_ctinfo: use percpu stats [ Upstream commit 21c167aa0ba943a7cac2f6969814f83bb701666b ] The tc action act_ctinfo was using shared stats, fix it to use percpu stats since bstats_update() must be called with locks or with a percpu pointer argument. tdc results: 1..12 ok 1 c826 - Add ctinfo action with default setting ok 2 0286 - Add ctinfo action with dscp ok 3 4938 - Add ctinfo action with valid cpmark and zone ok 4 7593 - Add ctinfo action with drop control ok 5 2961 - Replace ctinfo action zone and action control ok 6 e567 - Delete ctinfo action with valid index ok 7 6a91 - Delete ctinfo action with invalid index ok 8 5232 - List ctinfo actions ok 9 7702 - Flush ctinfo actions ok 10 3201 - Add ctinfo action with duplicate index ok 11 8295 - Add ctinfo action with invalid index ok 12 3964 - Replace ctinfo action with invalid goto_chain control Fixes: 24ec483cec98 ("net: sched: Introduce act_ctinfo action") Reviewed-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela Reviewed-by: Larysa Zaremba Link: https://lore.kernel.org/r/20230210200824.444856-1-pctammela@mojatatu.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/act_ctinfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c index 9bde94e7bb93..5aa005835c06 100644 --- a/net/sched/act_ctinfo.c +++ b/net/sched/act_ctinfo.c @@ -92,7 +92,7 @@ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a, cp = rcu_dereference_bh(ca->params); tcf_lastuse_update(&ca->tcf_tm); - bstats_update(&ca->tcf_bstats, skb); + tcf_action_update_bstats(&ca->common, skb); action = READ_ONCE(ca->tcf_action); wlen = skb_network_offset(skb); @@ -211,8 +211,8 @@ static int tcf_ctinfo_init(struct net *net, struct nlattr *nla, index = actparm->index; err = tcf_idr_check_alloc(tn, &index, a, bind); if (!err) { - ret = tcf_idr_create(tn, index, est, a, - &act_ctinfo_ops, bind, false, flags); + ret = tcf_idr_create_from_flags(tn, index, est, a, + &act_ctinfo_ops, bind, flags); if (ret) { tcf_idr_cleanup(tn, index); return ret; From b452e20b95d7e0b09ee4a6f773e3ebe6764ff1cf Mon Sep 17 00:00:00 2001 From: Natalia Petrova Date: Thu, 9 Feb 2023 09:28:33 -0800 Subject: [PATCH 0051/1017] i40e: Add checking for null for nlmsg_find_attr() [ Upstream commit 7fa0b526f865cb42aa33917fd02a92cb03746f4d ] The result of nlmsg_find_attr() 'br_spec' is dereferenced in nla_for_each_nested(), but it can take NULL value in nla_find() function, which will result in an error. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 51616018dd1b ("i40e: Add support for getlink, setlink ndo ops") Signed-off-by: Natalia Petrova Reviewed-by: Jesse Brandeburg Tested-by: Gurucharan G (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Link: https://lore.kernel.org/r/20230209172833.3596034-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index c4f4ee34d58a..9e8a20a94862 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -12520,6 +12520,8 @@ static int i40e_ndo_bridge_setlink(struct net_device *dev, } br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); + if (!br_spec) + return -EINVAL; nla_for_each_nested(attr, br_spec, rem) { __u16 mode; From 4fe9950815e19051b7b8268b4d4c3ac286a741bf Mon Sep 17 00:00:00 2001 From: Pedro Tammela Date: Mon, 13 Feb 2023 22:47:29 -0300 Subject: [PATCH 0052/1017] net/sched: tcindex: search key must be 16 bits [ Upstream commit 42018a322bd453e38b3ffee294982243e50a484f ] Syzkaller found an issue where a handle greater than 16 bits would trigger a null-ptr-deref in the imperfect hash area update. general protection fault, probably for non-canonical address 0xdffffc0000000015: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af] CPU: 0 PID: 5070 Comm: syz-executor456 Not tainted 6.2.0-rc7-syzkaller-00112-gc68f345b7c42 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/21/2023 RIP: 0010:tcindex_set_parms+0x1a6a/0x2990 net/sched/cls_tcindex.c:509 Code: 01 e9 e9 fe ff ff 4c 8b bd 28 fe ff ff e8 0e 57 7d f9 48 8d bb a8 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 94 0c 00 00 48 8b 85 f8 fd ff ff 48 8b 9b a8 00 RSP: 0018:ffffc90003d3ef88 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000015 RSI: ffffffff8803a102 RDI: 00000000000000a8 RBP: ffffc90003d3f1d8 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: ffff88801e2b10a8 R13: dffffc0000000000 R14: 0000000000030000 R15: ffff888017b3be00 FS: 00005555569af300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000056041c6d2000 CR3: 000000002bfca000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: tcindex_change+0x1ea/0x320 net/sched/cls_tcindex.c:572 tc_new_tfilter+0x96e/0x2220 net/sched/cls_api.c:2155 rtnetlink_rcv_msg+0x959/0xca0 net/core/rtnetlink.c:6132 netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2574 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x91b/0xe10 net/netlink/af_netlink.c:1942 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xd3/0x120 net/socket.c:734 ____sys_sendmsg+0x334/0x8c0 net/socket.c:2476 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2530 __sys_sendmmsg+0x18f/0x460 net/socket.c:2616 __do_sys_sendmmsg net/socket.c:2645 [inline] __se_sys_sendmmsg net/socket.c:2642 [inline] __x64_sys_sendmmsg+0x9d/0x100 net/socket.c:2642 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 Fixes: ee059170b1f7 ("net/sched: tcindex: update imperfect hash filters respecting rcu") Signed-off-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela Reported-by: syzbot Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/cls_tcindex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 50bf7ec4b5b2..2c0c95204cb5 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -502,7 +502,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, /* lookup the filter, guaranteed to exist */ for (cf = rcu_dereference_bh_rtnl(*fp); cf; fp = &cf->next, cf = rcu_dereference_bh_rtnl(*fp)) - if (cf->key == handle) + if (cf->key == (u16)handle) break; f->next = cf->next; From 6416c2108ba54d569e4c98d3b62ac78cb12e7107 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 14 Feb 2023 11:33:04 +0100 Subject: [PATCH 0053/1017] kvm: initialize all of the kvm_debugregs structure before sending it to userspace commit 2c10b61421a28e95a46ab489fd56c0f442ff6952 upstream. When calling the KVM_GET_DEBUGREGS ioctl, on some configurations, there might be some unitialized portions of the kvm_debugregs structure that could be copied to userspace. Prevent this as is done in the other kvm ioctls, by setting the whole structure to 0 before copying anything into it. Bonus is that this reduces the lines of code as the explicit flag setting and reserved space zeroing out can be removed. Cc: Sean Christopherson Cc: Paolo Bonzini Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: Cc: "H. Peter Anvin" Cc: stable Reported-by: Xingyuan Mo Signed-off-by: Greg Kroah-Hartman Message-Id: <20230214103304.3689213-1-gregkh@linuxfoundation.org> Tested-by: Xingyuan Mo Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/x86.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 23d7c563e012..554d37873c25 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4455,12 +4455,11 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, { unsigned long val; + memset(dbgregs, 0, sizeof(*dbgregs)); memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); kvm_get_dr(vcpu, 6, &val); dbgregs->dr6 = val; dbgregs->dr7 = vcpu->arch.dr7; - dbgregs->flags = 0; - memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved)); } static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, From 6af2872cc62549b2b034dcd02770ac52edf440ba Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 9 Feb 2023 23:25:49 +0100 Subject: [PATCH 0054/1017] alarmtimer: Prevent starvation by small intervals and SIG_IGN commit d125d1349abeb46945dc5e98f7824bf688266f13 upstream. syzbot reported a RCU stall which is caused by setting up an alarmtimer with a very small interval and ignoring the signal. The reproducer arms the alarm timer with a relative expiry of 8ns and an interval of 9ns. Not a problem per se, but that's an issue when the signal is ignored because then the timer is immediately rearmed because there is no way to delay that rearming to the signal delivery path. See posix_timer_fn() and commit 58229a189942 ("posix-timers: Prevent softirq starvation by small intervals and SIG_IGN") for details. The reproducer does not set SIG_IGN explicitely, but it sets up the timers signal with SIGCONT. That has the same effect as explicitely setting SIG_IGN for a signal as SIGCONT is ignored if there is no handler set and the task is not ptraced. The log clearly shows that: [pid 5102] --- SIGCONT {si_signo=SIGCONT, si_code=SI_TIMER, si_timerid=0, si_overrun=316014, si_int=0, si_ptr=NULL} --- It works because the tasks are traced and therefore the signal is queued so the tracer can see it, which delays the restart of the timer to the signal delivery path. But then the tracer is killed: [pid 5087] kill(-5102, SIGKILL ... ./strace-static-x86_64: Process 5107 detached and after it's gone the stall can be observed: syzkaller login: [ 79.439102][ C0] hrtimer: interrupt took 68471 ns [ 184.460538][ C1] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks: ... [ 184.658237][ C1] rcu: Stack dump where RCU GP kthread last ran: [ 184.664574][ C1] Sending NMI from CPU 1 to CPUs 0: [ 184.669821][ C0] NMI backtrace for cpu 0 [ 184.669831][ C0] CPU: 0 PID: 5108 Comm: syz-executor192 Not tainted 6.2.0-rc6-next-20230203-syzkaller #0 ... [ 184.670036][ C0] Call Trace: [ 184.670041][ C0] [ 184.670045][ C0] alarmtimer_fired+0x327/0x670 posix_timer_fn() prevents that by checking whether the interval for timers which have the signal ignored is smaller than a jiffie and artifically delay it by shifting the next expiry out by a jiffie. That's accurate vs. the overrun accounting, but slightly inaccurate vs. timer_gettimer(2). The comment in that function says what needs to be done and there was a fix available for the regular userspace induced SIG_IGN mechanism, but that did not work due to the implicit ignore for SIGCONT and similar signals. This needs to be worked on, but for now the only available workaround is to do exactly what posix_timer_fn() does: Increase the interval of self-rearming timers, which have their signal ignored, to at least a jiffie. Interestingly this has been fixed before via commit ff86bf0c65f1 ("alarmtimer: Rate limit periodic intervals") already, but that fix got lost in a later rework. Reported-by: syzbot+b9564ba6e8e00694511b@syzkaller.appspotmail.com Fixes: f2c45807d399 ("alarmtimer: Switch over to generic set/get/rearm routine") Signed-off-by: Thomas Gleixner Acked-by: John Stultz Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/87k00q1no2.ffs@tglx Signed-off-by: Greg Kroah-Hartman --- kernel/time/alarmtimer.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index daeaa7140d0a..1de426d3f694 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -470,11 +470,35 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval) } EXPORT_SYMBOL_GPL(alarm_forward); -u64 alarm_forward_now(struct alarm *alarm, ktime_t interval) +static u64 __alarm_forward_now(struct alarm *alarm, ktime_t interval, bool throttle) { struct alarm_base *base = &alarm_bases[alarm->type]; + ktime_t now = base->get_ktime(); - return alarm_forward(alarm, base->get_ktime(), interval); + if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) && throttle) { + /* + * Same issue as with posix_timer_fn(). Timers which are + * periodic but the signal is ignored can starve the system + * with a very small interval. The real fix which was + * promised in the context of posix_timer_fn() never + * materialized, but someone should really work on it. + * + * To prevent DOS fake @now to be 1 jiffie out which keeps + * the overrun accounting correct but creates an + * inconsistency vs. timer_gettime(2). + */ + ktime_t kj = NSEC_PER_SEC / HZ; + + if (interval < kj) + now = ktime_add(now, kj); + } + + return alarm_forward(alarm, now, interval); +} + +u64 alarm_forward_now(struct alarm *alarm, ktime_t interval) +{ + return __alarm_forward_now(alarm, interval, false); } EXPORT_SYMBOL_GPL(alarm_forward_now); @@ -548,9 +572,10 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, if (posix_timer_event(ptr, si_private) && ptr->it_interval) { /* * Handle ignored signals and rearm the timer. This will go - * away once we handle ignored signals proper. + * away once we handle ignored signals proper. Ensure that + * small intervals cannot starve the system. */ - ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval); + ptr->it_overrun += __alarm_forward_now(alarm, ptr->it_interval, true); ++ptr->it_requeue_pending; ptr->it_active = 1; result = ALARMTIMER_RESTART; From 31167df7c21feb2a74d69a758a5226d83cbfe905 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Feb 2023 18:23:40 +0200 Subject: [PATCH 0055/1017] ASoC: SOF: Intel: hda-dai: fix possible stream_tag leak commit 1f810d2b6b2fbdc5279644d8b2c140b1f7c9d43d upstream. The HDaudio stream allocation is done first, and in a second step the LOSIDV parameter is programmed for the multi-link used by a codec. This leads to a possible stream_tag leak, e.g. if a DisplayAudio link is not used. This would happen when a non-Intel graphics card is used and userspace unconditionally uses the Intel Display Audio PCMs without checking if they are connected to a receiver with jack controls. We should first check that there is a valid multi-link entry to configure before allocating a stream_tag. This change aligns the dma_assign and dma_cleanup phases. Complements: b0cd60f3e9f5 ("ALSA/ASoC: hda: clarify bus_get_link() and bus_link_get() helpers") Link: https://github.com/thesofproject/linux/issues/4151 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Reviewed-by: Bard Liao Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20230216162340.19480-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/sof/intel/hda-dai.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index de80f1b3d7f2..a6275cc92a40 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -212,6 +212,10 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, int stream_tag; int ret; + link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); + if (!link) + return -EINVAL; + /* get stored dma data if resuming from system suspend */ link_dev = snd_soc_dai_get_dma_data(dai, substream); if (!link_dev) { @@ -232,10 +236,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); - if (!link) - return -EINVAL; - /* set the hdac_stream in the codec dai */ snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream); From c00867afe4efd5754e696d5c0a8d3f682efd7ffb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Feb 2023 16:18:32 +0300 Subject: [PATCH 0056/1017] net: sched: sch: Fix off by one in htb_activate_prios() commit 9cec2aaffe969f2a3e18b5ec105fc20bb908e475 upstream. The > needs be >= to prevent an out of bounds access. Fixes: de5ca4c3852f ("net: sched: sch: Bounds check priority") Signed-off-by: Dan Carpenter Reviewed-by: Simon Horman Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/Y+D+KN18FQI2DKLq@kili Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_htb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index c3e773d2ca41..ff84ed531199 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -407,7 +407,7 @@ static void htb_activate_prios(struct htb_sched *q, struct htb_class *cl) while (m) { unsigned int prio = ffz(~m); - if (WARN_ON_ONCE(prio > ARRAY_SIZE(p->inner.clprio))) + if (WARN_ON_ONCE(prio >= ARRAY_SIZE(p->inner.clprio))) break; m &= ~(1 << prio); From e95381034519a8c5a3150f7b03f4664b1da651b2 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Fri, 27 Jan 2023 10:40:14 +0000 Subject: [PATCH 0057/1017] nvmem: core: fix return value commit 0c4862b1c1465e473bc961a02765490578bf5c20 upstream. Dan Carpenter points out that the return code was not set in commit 60c8b4aebd8e ("nvmem: core: fix cleanup after dev_set_name()"), but this is not the only issue - we also need to zero wp_gpio to prevent gpiod_put() being called on an error value. Fixes: 560181d3ace6 ("nvmem: core: fix cleanup after dev_set_name()") Cc: stable@vger.kernel.org Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Russell King (Oracle) Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230127104015.23839-10-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 0ef7b95348b1..1505c745154e 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -638,6 +638,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { rval = PTR_ERR(nvmem->wp_gpio); + nvmem->wp_gpio = NULL; goto err_put_device; } From 2ae73796985b582b79711dfed2941d190b571fb5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 22 Feb 2023 12:56:00 +0100 Subject: [PATCH 0058/1017] Linux 5.10.169 Link: https://lore.kernel.org/r/20230220133549.360169435@linuxfoundation.org Tested-by: Pavel Machek (CIP) Tested-by: Linux Kernel Functional Testing Tested-by: Jon Hunter Tested-by: Sudip Mukherjee Tested-by: Guenter Roeck Tested-by: Salvatore Bonaccorso Tested-by: Florian Fainelli Tested-by: Shuah Khan Tested-by: Hulk Robot Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index af3270277fd0..dbbfaa5d4fe2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 168 +SUBLEVEL = 169 EXTRAVERSION = NAME = Dare mighty things From eb9236d74c8cf2a7d68784018e290a48cebbee2e Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 16 Sep 2022 12:40:31 +0200 Subject: [PATCH 0059/1017] drm/etnaviv: don't truncate physical page address [ Upstream commit d37c120b73128690434cc093952439eef9d56af1 ] While the interface for the MMU mapping takes phys_addr_t to hold a full 64bit address when necessary and MMUv2 is able to map physical addresses with up to 40bit, etnaviv_iommu_map() truncates the address to 32bits. Fix this by using the correct type. Fixes: 931e97f3afd8 ("drm/etnaviv: mmuv2: support 40 bit phys address") Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Signed-off-by: Sasha Levin --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index 9ba2fe48228f..44fbc0a123bf 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -80,10 +80,10 @@ static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 iova, return -EINVAL; for_each_sgtable_dma_sg(sgt, sg, i) { - u32 pa = sg_dma_address(sg) - sg->offset; + phys_addr_t pa = sg_dma_address(sg) - sg->offset; size_t bytes = sg_dma_len(sg) + sg->offset; - VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes); + VERB("map[%d]: %08x %pap(%zx)", i, iova, &pa, bytes); ret = etnaviv_context_map(context, da, pa, bytes, prot); if (ret) From 051d73eb9ab456bcf5214554f1b37d97bedbb6d0 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 28 Sep 2022 23:36:51 +0300 Subject: [PATCH 0060/1017] wifi: rtl8xxxu: gen2: Turn on the rate control [ Upstream commit 791082ec0ab843e0be07c8ce3678e4c2afd2e33d ] Re-enable the function rtl8xxxu_gen2_report_connect. It informs the firmware when connecting to a network. This makes the firmware enable the rate control, which makes the upload faster. It also informs the firmware when disconnecting from a network. In the past this made reconnecting impossible because it was sending the auth on queue 0x7 (TXDESC_QUEUE_VO) instead of queue 0x12 (TXDESC_QUEUE_MGNT): wlp0s20f0u3: send auth to 90:55:de:__:__:__ (try 1/3) wlp0s20f0u3: send auth to 90:55:de:__:__:__ (try 2/3) wlp0s20f0u3: send auth to 90:55:de:__:__:__ (try 3/3) wlp0s20f0u3: authentication with 90:55:de:__:__:__ timed out Probably the firmware disables the unnecessary TX queues when it knows it's disconnected. However, this was fixed in commit edd5747aa12e ("wifi: rtl8xxxu: Fix skb misuse in TX queue selection"). Fixes: c59f13bbead4 ("rtl8xxxu: Work around issue with 8192eu and 8723bu devices not reconnecting") Signed-off-by: Bitterblue Smith Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/43200afc-0c65-ee72-48f8-231edd1df493@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 9a12f1d38007..2cb86c28d11f 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4369,12 +4369,9 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv, void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, u8 macid, bool connect) { -#ifdef RTL8XXXU_GEN2_REPORT_CONNECT /* - * Barry Day reports this causes issues with 8192eu and 8723bu - * devices reconnecting. The reason for this is unclear, but - * until it is better understood, leave the code in place but - * disabled, so it is not lost. + * The firmware turns on the rate control when it knows it's + * connected to a network. */ struct h2c_cmd h2c; @@ -4387,7 +4384,6 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, h2c.media_status_rpt.parm &= ~BIT(0); rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt)); -#endif } void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv) From 072eb5fbd69c1e566e1c9c4b08c199dbbf1dc181 Mon Sep 17 00:00:00 2001 From: Rahul Tanwar Date: Thu, 13 Oct 2022 14:48:30 +0800 Subject: [PATCH 0061/1017] clk: mxl: Switch from direct readl/writel based IO to regmap based IO [ Upstream commit 036177310bac5534de44ff6a7b60a4d2c0b6567c ] Earlier version of driver used direct io remapped register read writes using readl/writel. But we need secure boot access which is only possible when registers are read & written using regmap. This is because the security bus/hook is written & coupled only with regmap layer. Switch the driver from direct readl/writel based register accesses to regmap based register accesses. Additionally, update the license headers to latest status. Reviewed-by: Yi xin Zhu Signed-off-by: Rahul Tanwar Link: https://lore.kernel.org/r/2610331918206e0e3bd18babb39393a558fb34f9.1665642720.git.rtanwar@maxlinear.com Signed-off-by: Stephen Boyd Stable-dep-of: 106ef3bda210 ("clk: mxl: Fix a clk entry by adding relevant flags") Signed-off-by: Sasha Levin --- drivers/clk/x86/Kconfig | 5 +++-- drivers/clk/x86/clk-cgu-pll.c | 10 +++++---- drivers/clk/x86/clk-cgu.c | 5 +++-- drivers/clk/x86/clk-cgu.h | 38 +++++++++++++++++++---------------- drivers/clk/x86/clk-lgm.c | 13 ++++++++---- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/drivers/clk/x86/Kconfig b/drivers/clk/x86/Kconfig index 69642e15fcc1..ced99e082e3d 100644 --- a/drivers/clk/x86/Kconfig +++ b/drivers/clk/x86/Kconfig @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only config CLK_LGM_CGU depends on OF && HAS_IOMEM && (X86 || COMPILE_TEST) + select MFD_SYSCON select OF_EARLY_FLATTREE bool "Clock driver for Lightning Mountain(LGM) platform" help - Clock Generation Unit(CGU) driver for Intel Lightning Mountain(LGM) - network processor SoC. + Clock Generation Unit(CGU) driver for MaxLinear's x86 based + Lightning Mountain(LGM) network processor SoC. diff --git a/drivers/clk/x86/clk-cgu-pll.c b/drivers/clk/x86/clk-cgu-pll.c index 3179557b5f78..c83083affe88 100644 --- a/drivers/clk/x86/clk-cgu-pll.c +++ b/drivers/clk/x86/clk-cgu-pll.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 /* + * Copyright (C) 2020-2022 MaxLinear, Inc. * Copyright (C) 2020 Intel Corporation. - * Zhu YiXin - * Rahul Tanwar + * Zhu Yixin + * Rahul Tanwar */ #include @@ -76,8 +77,9 @@ static int lgm_pll_enable(struct clk_hw *hw) spin_lock_irqsave(&pll->lock, flags); lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1); - ret = readl_poll_timeout_atomic(pll->membase + pll->reg, - val, (val & 0x1), 1, 100); + ret = regmap_read_poll_timeout_atomic(pll->membase, pll->reg, + val, (val & 0x1), 1, 100); + spin_unlock_irqrestore(&pll->lock, flags); return ret; diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index 33de600e0c38..f5f30a18f486 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 /* + * Copyright (C) 2020-2022 MaxLinear, Inc. * Copyright (C) 2020 Intel Corporation. - * Zhu YiXin - * Rahul Tanwar + * Zhu Yixin + * Rahul Tanwar */ #include #include diff --git a/drivers/clk/x86/clk-cgu.h b/drivers/clk/x86/clk-cgu.h index 4e22bfb22312..dbcb66468797 100644 --- a/drivers/clk/x86/clk-cgu.h +++ b/drivers/clk/x86/clk-cgu.h @@ -1,18 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright(c) 2020 Intel Corporation. - * Zhu YiXin - * Rahul Tanwar + * Copyright (C) 2020-2022 MaxLinear, Inc. + * Copyright (C) 2020 Intel Corporation. + * Zhu Yixin + * Rahul Tanwar */ #ifndef __CLK_CGU_H #define __CLK_CGU_H -#include +#include struct lgm_clk_mux { struct clk_hw hw; - void __iomem *membase; + struct regmap *membase; unsigned int reg; u8 shift; u8 width; @@ -22,7 +23,7 @@ struct lgm_clk_mux { struct lgm_clk_divider { struct clk_hw hw; - void __iomem *membase; + struct regmap *membase; unsigned int reg; u8 shift; u8 width; @@ -35,7 +36,7 @@ struct lgm_clk_divider { struct lgm_clk_ddiv { struct clk_hw hw; - void __iomem *membase; + struct regmap *membase; unsigned int reg; u8 shift0; u8 width0; @@ -53,7 +54,7 @@ struct lgm_clk_ddiv { struct lgm_clk_gate { struct clk_hw hw; - void __iomem *membase; + struct regmap *membase; unsigned int reg; u8 shift; unsigned long flags; @@ -77,7 +78,7 @@ enum lgm_clk_type { * @clk_data: array of hw clocks and clk number. */ struct lgm_clk_provider { - void __iomem *membase; + struct regmap *membase; struct device_node *np; struct device *dev; struct clk_hw_onecell_data clk_data; @@ -92,7 +93,7 @@ enum pll_type { struct lgm_clk_pll { struct clk_hw hw; - void __iomem *membase; + struct regmap *membase; unsigned int reg; unsigned long flags; enum pll_type type; @@ -300,29 +301,32 @@ struct lgm_clk_branch { .div = _d, \ } -static inline void lgm_set_clk_val(void __iomem *membase, u32 reg, +static inline void lgm_set_clk_val(struct regmap *membase, u32 reg, u8 shift, u8 width, u32 set_val) { u32 mask = (GENMASK(width - 1, 0) << shift); - u32 regval; - regval = readl(membase + reg); - regval = (regval & ~mask) | ((set_val << shift) & mask); - writel(regval, membase + reg); + regmap_update_bits(membase, reg, mask, set_val << shift); } -static inline u32 lgm_get_clk_val(void __iomem *membase, u32 reg, +static inline u32 lgm_get_clk_val(struct regmap *membase, u32 reg, u8 shift, u8 width) { u32 mask = (GENMASK(width - 1, 0) << shift); u32 val; - val = readl(membase + reg); + if (regmap_read(membase, reg, &val)) { + WARN_ONCE(1, "Failed to read clk reg: 0x%x\n", reg); + return 0; + } + val = (val & mask) >> shift; return val; } + + int lgm_clk_register_branches(struct lgm_clk_provider *ctx, const struct lgm_clk_branch *list, unsigned int nr_clk); diff --git a/drivers/clk/x86/clk-lgm.c b/drivers/clk/x86/clk-lgm.c index 020f4e83a5cc..4fa2bcaf71c8 100644 --- a/drivers/clk/x86/clk-lgm.c +++ b/drivers/clk/x86/clk-lgm.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 /* + * Copyright (C) 2020-2022 MaxLinear, Inc. * Copyright (C) 2020 Intel Corporation. - * Zhu YiXin - * Rahul Tanwar + * Zhu Yixin + * Rahul Tanwar */ #include +#include #include #include #include @@ -433,9 +435,12 @@ static int lgm_cgu_probe(struct platform_device *pdev) ctx->clk_data.num = CLK_NR_CLKS; - ctx->membase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(ctx->membase)) + ctx->membase = syscon_node_to_regmap(np); + if (IS_ERR_OR_NULL(ctx->membase)) { + dev_err(dev, "Failed to get clk CGU iomem\n"); return PTR_ERR(ctx->membase); + } + ctx->np = np; ctx->dev = dev; From 3789e905f4885522ebf37b040eefd62422cff249 Mon Sep 17 00:00:00 2001 From: Rahul Tanwar Date: Thu, 13 Oct 2022 14:48:31 +0800 Subject: [PATCH 0062/1017] clk: mxl: Remove redundant spinlocks [ Upstream commit eaabee88a88a26b108be8d120fc072dfaf462cef ] Patch 1/4 of this patch series switches from direct readl/writel based register access to regmap based register access. Instead of using direct readl/writel, regmap API's are used to read, write & read-modify-write clk registers. Regmap API's already use their own spinlocks to serialize the register accesses across multiple cores in which case additional driver spinlocks becomes redundant. Hence, remove redundant spinlocks from driver in this patch 2/4. Reviewed-by: Yi xin Zhu Signed-off-by: Rahul Tanwar Link: https://lore.kernel.org/r/a8a02c8773b88924503a9fdaacd37dd2e6488bf3.1665642720.git.rtanwar@maxlinear.com Signed-off-by: Stephen Boyd Stable-dep-of: 106ef3bda210 ("clk: mxl: Fix a clk entry by adding relevant flags") Signed-off-by: Sasha Levin --- drivers/clk/x86/clk-cgu-pll.c | 13 ------ drivers/clk/x86/clk-cgu.c | 80 ++++------------------------------- drivers/clk/x86/clk-cgu.h | 6 --- drivers/clk/x86/clk-lgm.c | 1 - 4 files changed, 9 insertions(+), 91 deletions(-) diff --git a/drivers/clk/x86/clk-cgu-pll.c b/drivers/clk/x86/clk-cgu-pll.c index c83083affe88..409dbf55f4ca 100644 --- a/drivers/clk/x86/clk-cgu-pll.c +++ b/drivers/clk/x86/clk-cgu-pll.c @@ -41,13 +41,10 @@ static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate) { struct lgm_clk_pll *pll = to_lgm_clk_pll(hw); unsigned int div, mult, frac; - unsigned long flags; - spin_lock_irqsave(&pll->lock, flags); mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12); div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6); frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24); - spin_unlock_irqrestore(&pll->lock, flags); if (pll->type == TYPE_LJPLL) div *= 4; @@ -58,12 +55,9 @@ static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate) static int lgm_pll_is_enabled(struct clk_hw *hw) { struct lgm_clk_pll *pll = to_lgm_clk_pll(hw); - unsigned long flags; unsigned int ret; - spin_lock_irqsave(&pll->lock, flags); ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1); - spin_unlock_irqrestore(&pll->lock, flags); return ret; } @@ -71,16 +65,13 @@ static int lgm_pll_is_enabled(struct clk_hw *hw) static int lgm_pll_enable(struct clk_hw *hw) { struct lgm_clk_pll *pll = to_lgm_clk_pll(hw); - unsigned long flags; u32 val; int ret; - spin_lock_irqsave(&pll->lock, flags); lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1); ret = regmap_read_poll_timeout_atomic(pll->membase, pll->reg, val, (val & 0x1), 1, 100); - spin_unlock_irqrestore(&pll->lock, flags); return ret; } @@ -88,11 +79,8 @@ static int lgm_pll_enable(struct clk_hw *hw) static void lgm_pll_disable(struct clk_hw *hw) { struct lgm_clk_pll *pll = to_lgm_clk_pll(hw); - unsigned long flags; - spin_lock_irqsave(&pll->lock, flags); lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0); - spin_unlock_irqrestore(&pll->lock, flags); } static const struct clk_ops lgm_pll_ops = { @@ -123,7 +111,6 @@ lgm_clk_register_pll(struct lgm_clk_provider *ctx, return ERR_PTR(-ENOMEM); pll->membase = ctx->membase; - pll->lock = ctx->lock; pll->reg = list->reg; pll->flags = list->flags; pll->type = list->type; diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index f5f30a18f486..1f7e93de67bc 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -25,14 +25,10 @@ static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx, const struct lgm_clk_branch *list) { - unsigned long flags; - if (list->div_flags & CLOCK_FLAG_VAL_INIT) { - spin_lock_irqsave(&ctx->lock, flags); + if (list->div_flags & CLOCK_FLAG_VAL_INIT) lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift, list->div_width, list->div_val); - spin_unlock_irqrestore(&ctx->lock, flags); - } return clk_hw_register_fixed_rate(NULL, list->name, list->parent_data[0].name, @@ -42,33 +38,27 @@ static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx, static u8 lgm_clk_mux_get_parent(struct clk_hw *hw) { struct lgm_clk_mux *mux = to_lgm_clk_mux(hw); - unsigned long flags; u32 val; - spin_lock_irqsave(&mux->lock, flags); if (mux->flags & MUX_CLK_SW) val = mux->reg; else val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift, mux->width); - spin_unlock_irqrestore(&mux->lock, flags); return clk_mux_val_to_index(hw, NULL, mux->flags, val); } static int lgm_clk_mux_set_parent(struct clk_hw *hw, u8 index) { struct lgm_clk_mux *mux = to_lgm_clk_mux(hw); - unsigned long flags; u32 val; val = clk_mux_index_to_val(NULL, mux->flags, index); - spin_lock_irqsave(&mux->lock, flags); if (mux->flags & MUX_CLK_SW) mux->reg = val; else lgm_set_clk_val(mux->membase, mux->reg, mux->shift, mux->width, val); - spin_unlock_irqrestore(&mux->lock, flags); return 0; } @@ -91,7 +81,7 @@ static struct clk_hw * lgm_clk_register_mux(struct lgm_clk_provider *ctx, const struct lgm_clk_branch *list) { - unsigned long flags, cflags = list->mux_flags; + unsigned long cflags = list->mux_flags; struct device *dev = ctx->dev; u8 shift = list->mux_shift; u8 width = list->mux_width; @@ -112,7 +102,6 @@ lgm_clk_register_mux(struct lgm_clk_provider *ctx, init.num_parents = list->num_parents; mux->membase = ctx->membase; - mux->lock = ctx->lock; mux->reg = reg; mux->shift = shift; mux->width = width; @@ -124,11 +113,8 @@ lgm_clk_register_mux(struct lgm_clk_provider *ctx, if (ret) return ERR_PTR(ret); - if (cflags & CLOCK_FLAG_VAL_INIT) { - spin_lock_irqsave(&mux->lock, flags); + if (cflags & CLOCK_FLAG_VAL_INIT) lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val); - spin_unlock_irqrestore(&mux->lock, flags); - } return hw; } @@ -137,13 +123,10 @@ static unsigned long lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct lgm_clk_divider *divider = to_lgm_clk_divider(hw); - unsigned long flags; unsigned int val; - spin_lock_irqsave(÷r->lock, flags); val = lgm_get_clk_val(divider->membase, divider->reg, divider->shift, divider->width); - spin_unlock_irqrestore(÷r->lock, flags); return divider_recalc_rate(hw, parent_rate, val, divider->table, divider->flags, divider->width); @@ -164,7 +147,6 @@ lgm_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) { struct lgm_clk_divider *divider = to_lgm_clk_divider(hw); - unsigned long flags; int value; value = divider_get_val(rate, prate, divider->table, @@ -172,10 +154,8 @@ lgm_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, if (value < 0) return value; - spin_lock_irqsave(÷r->lock, flags); lgm_set_clk_val(divider->membase, divider->reg, divider->shift, divider->width, value); - spin_unlock_irqrestore(÷r->lock, flags); return 0; } @@ -183,12 +163,9 @@ lgm_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable) { struct lgm_clk_divider *div = to_lgm_clk_divider(hw); - unsigned long flags; - spin_lock_irqsave(&div->lock, flags); lgm_set_clk_val(div->membase, div->reg, div->shift_gate, div->width_gate, enable); - spin_unlock_irqrestore(&div->lock, flags); return 0; } @@ -214,7 +191,7 @@ static struct clk_hw * lgm_clk_register_divider(struct lgm_clk_provider *ctx, const struct lgm_clk_branch *list) { - unsigned long flags, cflags = list->div_flags; + unsigned long cflags = list->div_flags; struct device *dev = ctx->dev; struct lgm_clk_divider *div; struct clk_init_data init = {}; @@ -237,7 +214,6 @@ lgm_clk_register_divider(struct lgm_clk_provider *ctx, init.num_parents = 1; div->membase = ctx->membase; - div->lock = ctx->lock; div->reg = reg; div->shift = shift; div->width = width; @@ -252,11 +228,8 @@ lgm_clk_register_divider(struct lgm_clk_provider *ctx, if (ret) return ERR_PTR(ret); - if (cflags & CLOCK_FLAG_VAL_INIT) { - spin_lock_irqsave(&div->lock, flags); + if (cflags & CLOCK_FLAG_VAL_INIT) lgm_set_clk_val(div->membase, reg, shift, width, list->div_val); - spin_unlock_irqrestore(&div->lock, flags); - } return hw; } @@ -265,7 +238,6 @@ static struct clk_hw * lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx, const struct lgm_clk_branch *list) { - unsigned long flags; struct clk_hw *hw; hw = clk_hw_register_fixed_factor(ctx->dev, list->name, @@ -274,12 +246,9 @@ lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx, if (IS_ERR(hw)) return ERR_CAST(hw); - if (list->div_flags & CLOCK_FLAG_VAL_INIT) { - spin_lock_irqsave(&ctx->lock, flags); + if (list->div_flags & CLOCK_FLAG_VAL_INIT) lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift, list->div_width, list->div_val); - spin_unlock_irqrestore(&ctx->lock, flags); - } return hw; } @@ -287,13 +256,10 @@ lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx, static int lgm_clk_gate_enable(struct clk_hw *hw) { struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); - unsigned long flags; unsigned int reg; - spin_lock_irqsave(&gate->lock, flags); reg = GATE_HW_REG_EN(gate->reg); lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); - spin_unlock_irqrestore(&gate->lock, flags); return 0; } @@ -301,25 +267,19 @@ static int lgm_clk_gate_enable(struct clk_hw *hw) static void lgm_clk_gate_disable(struct clk_hw *hw) { struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); - unsigned long flags; unsigned int reg; - spin_lock_irqsave(&gate->lock, flags); reg = GATE_HW_REG_DIS(gate->reg); lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); - spin_unlock_irqrestore(&gate->lock, flags); } static int lgm_clk_gate_is_enabled(struct clk_hw *hw) { struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); unsigned int reg, ret; - unsigned long flags; - spin_lock_irqsave(&gate->lock, flags); reg = GATE_HW_REG_STAT(gate->reg); ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1); - spin_unlock_irqrestore(&gate->lock, flags); return ret; } @@ -334,7 +294,7 @@ static struct clk_hw * lgm_clk_register_gate(struct lgm_clk_provider *ctx, const struct lgm_clk_branch *list) { - unsigned long flags, cflags = list->gate_flags; + unsigned long cflags = list->gate_flags; const char *pname = list->parent_data[0].name; struct device *dev = ctx->dev; u8 shift = list->gate_shift; @@ -355,7 +315,6 @@ lgm_clk_register_gate(struct lgm_clk_provider *ctx, init.num_parents = pname ? 1 : 0; gate->membase = ctx->membase; - gate->lock = ctx->lock; gate->reg = reg; gate->shift = shift; gate->flags = cflags; @@ -367,9 +326,7 @@ lgm_clk_register_gate(struct lgm_clk_provider *ctx, return ERR_PTR(ret); if (cflags & CLOCK_FLAG_VAL_INIT) { - spin_lock_irqsave(&gate->lock, flags); lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val); - spin_unlock_irqrestore(&gate->lock, flags); } return hw; @@ -444,24 +401,18 @@ lgm_clk_ddiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) static int lgm_clk_ddiv_enable(struct clk_hw *hw) { struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw); - unsigned long flags; - spin_lock_irqsave(&ddiv->lock, flags); lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate, ddiv->width_gate, 1); - spin_unlock_irqrestore(&ddiv->lock, flags); return 0; } static void lgm_clk_ddiv_disable(struct clk_hw *hw) { struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw); - unsigned long flags; - spin_lock_irqsave(&ddiv->lock, flags); lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate, ddiv->width_gate, 0); - spin_unlock_irqrestore(&ddiv->lock, flags); } static int @@ -498,32 +449,25 @@ lgm_clk_ddiv_set_rate(struct clk_hw *hw, unsigned long rate, { struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw); u32 div, ddiv1, ddiv2; - unsigned long flags; div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate); - spin_lock_irqsave(&ddiv->lock, flags); if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { div = DIV_ROUND_CLOSEST_ULL((u64)div, 5); div = div * 2; } - if (div <= 0) { - spin_unlock_irqrestore(&ddiv->lock, flags); + if (div <= 0) return -EINVAL; - } - if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) { - spin_unlock_irqrestore(&ddiv->lock, flags); + if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) return -EINVAL; - } lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0, ddiv1 - 1); lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1, ddiv2 - 1); - spin_unlock_irqrestore(&ddiv->lock, flags); return 0; } @@ -534,18 +478,15 @@ lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, { struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw); u32 div, ddiv1, ddiv2; - unsigned long flags; u64 rate64; div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate); /* if predivide bit is enabled, modify div by factor of 2.5 */ - spin_lock_irqsave(&ddiv->lock, flags); if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { div = div * 2; div = DIV_ROUND_CLOSEST_ULL((u64)div, 5); } - spin_unlock_irqrestore(&ddiv->lock, flags); if (div <= 0) return *prate; @@ -559,12 +500,10 @@ lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, do_div(rate64, ddiv2); /* if predivide bit is enabled, modify rounded rate by factor of 2.5 */ - spin_lock_irqsave(&ddiv->lock, flags); if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { rate64 = rate64 * 2; rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5); } - spin_unlock_irqrestore(&ddiv->lock, flags); return rate64; } @@ -601,7 +540,6 @@ int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx, init.num_parents = 1; ddiv->membase = ctx->membase; - ddiv->lock = ctx->lock; ddiv->reg = list->reg; ddiv->shift0 = list->shift0; ddiv->width0 = list->width0; diff --git a/drivers/clk/x86/clk-cgu.h b/drivers/clk/x86/clk-cgu.h index dbcb66468797..0aa0f35d63a0 100644 --- a/drivers/clk/x86/clk-cgu.h +++ b/drivers/clk/x86/clk-cgu.h @@ -18,7 +18,6 @@ struct lgm_clk_mux { u8 shift; u8 width; unsigned long flags; - spinlock_t lock; }; struct lgm_clk_divider { @@ -31,7 +30,6 @@ struct lgm_clk_divider { u8 width_gate; unsigned long flags; const struct clk_div_table *table; - spinlock_t lock; }; struct lgm_clk_ddiv { @@ -49,7 +47,6 @@ struct lgm_clk_ddiv { unsigned int mult; unsigned int div; unsigned long flags; - spinlock_t lock; }; struct lgm_clk_gate { @@ -58,7 +55,6 @@ struct lgm_clk_gate { unsigned int reg; u8 shift; unsigned long flags; - spinlock_t lock; }; enum lgm_clk_type { @@ -82,7 +78,6 @@ struct lgm_clk_provider { struct device_node *np; struct device *dev; struct clk_hw_onecell_data clk_data; - spinlock_t lock; }; enum pll_type { @@ -97,7 +92,6 @@ struct lgm_clk_pll { unsigned int reg; unsigned long flags; enum pll_type type; - spinlock_t lock; }; /** diff --git a/drivers/clk/x86/clk-lgm.c b/drivers/clk/x86/clk-lgm.c index 4fa2bcaf71c8..e312af42e97a 100644 --- a/drivers/clk/x86/clk-lgm.c +++ b/drivers/clk/x86/clk-lgm.c @@ -444,7 +444,6 @@ static int lgm_cgu_probe(struct platform_device *pdev) ctx->np = np; ctx->dev = dev; - spin_lock_init(&ctx->lock); ret = lgm_clk_register_plls(ctx, lgm_pll_clks, ARRAY_SIZE(lgm_pll_clks)); From 9dcf2ca5d30147d56037679432908e4222c5794f Mon Sep 17 00:00:00 2001 From: Rahul Tanwar Date: Thu, 13 Oct 2022 14:48:32 +0800 Subject: [PATCH 0063/1017] clk: mxl: Add option to override gate clks [ Upstream commit a5d49bd369b8588c0ee9d4d0a2c0160558a3ab69 ] In MxL's LGM SoC, gate clocks can be controlled either from CGU clk driver i.e. this driver or directly from power management driver/daemon. It is dependent on the power policy/profile requirements of the end product. To support such use cases, provide option to override gate clks enable/disable by adding a flag GATE_CLK_HW which controls if these gate clks are controlled by HW i.e. this driver or overridden in order to allow it to be controlled by power profiles instead. Reviewed-by: Yi xin Zhu Signed-off-by: Rahul Tanwar Link: https://lore.kernel.org/r/bdc9c89317b5d338a6c4f1d49386b696e947a672.1665642720.git.rtanwar@maxlinear.com [sboyd@kernel.org: Add braces on many line if-else] Signed-off-by: Stephen Boyd Stable-dep-of: 106ef3bda210 ("clk: mxl: Fix a clk entry by adding relevant flags") Signed-off-by: Sasha Levin --- drivers/clk/x86/clk-cgu.c | 16 +++++++++++++++- drivers/clk/x86/clk-cgu.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index 1f7e93de67bc..4278a687076c 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -354,8 +354,22 @@ int lgm_clk_register_branches(struct lgm_clk_provider *ctx, hw = lgm_clk_register_fixed_factor(ctx, list); break; case CLK_TYPE_GATE: - hw = lgm_clk_register_gate(ctx, list); + if (list->gate_flags & GATE_CLK_HW) { + hw = lgm_clk_register_gate(ctx, list); + } else { + /* + * GATE_CLKs can be controlled either from + * CGU clk driver i.e. this driver or directly + * from power management driver/daemon. It is + * dependent on the power policy/profile requirements + * of the end product. To override control of gate + * clks from this driver, provide NULL for this index + * of gate clk provider. + */ + hw = NULL; + } break; + default: dev_err(ctx->dev, "invalid clk type\n"); return -EINVAL; diff --git a/drivers/clk/x86/clk-cgu.h b/drivers/clk/x86/clk-cgu.h index 0aa0f35d63a0..73ce84345f81 100644 --- a/drivers/clk/x86/clk-cgu.h +++ b/drivers/clk/x86/clk-cgu.h @@ -197,6 +197,7 @@ struct lgm_clk_branch { /* clock flags definition */ #define CLOCK_FLAG_VAL_INIT BIT(16) #define MUX_CLK_SW BIT(17) +#define GATE_CLK_HW BIT(18) #define LGM_MUX(_id, _name, _pdata, _f, _reg, \ _shift, _width, _cf, _v) \ From caa47d91738f0e65687733fad53d87cc2048ed98 Mon Sep 17 00:00:00 2001 From: Rahul Tanwar Date: Thu, 13 Oct 2022 14:48:33 +0800 Subject: [PATCH 0064/1017] clk: mxl: Fix a clk entry by adding relevant flags [ Upstream commit 106ef3bda21006fe37b62c85931230a6355d78d3 ] One of the clock entry "dcl" clk has some HW limitations. One is that its rate can only by changed by changing its parent clk's rate & two is that HW does not support enable/disable for this clk. Handle above two limitations by adding relevant flags. Add standard flag CLK_SET_RATE_PARENT to handle rate change and add driver internal flag DIV_CLK_NO_MASK to handle enable/disable. Fixes: d058fd9e8984 ("clk: intel: Add CGU clock driver for a new SoC") Reviewed-by: Yi xin Zhu Signed-off-by: Rahul Tanwar Link: https://lore.kernel.org/r/a4770e7225f8a0c03c8ab2ba80434a4e8e9afb17.1665642720.git.rtanwar@maxlinear.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/x86/clk-cgu.c | 5 +++-- drivers/clk/x86/clk-cgu.h | 1 + drivers/clk/x86/clk-lgm.c | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index 4278a687076c..89b53f280aee 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -164,8 +164,9 @@ static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable) { struct lgm_clk_divider *div = to_lgm_clk_divider(hw); - lgm_set_clk_val(div->membase, div->reg, div->shift_gate, - div->width_gate, enable); + if (div->flags != DIV_CLK_NO_MASK) + lgm_set_clk_val(div->membase, div->reg, div->shift_gate, + div->width_gate, enable); return 0; } diff --git a/drivers/clk/x86/clk-cgu.h b/drivers/clk/x86/clk-cgu.h index 73ce84345f81..bcaf8aec94e5 100644 --- a/drivers/clk/x86/clk-cgu.h +++ b/drivers/clk/x86/clk-cgu.h @@ -198,6 +198,7 @@ struct lgm_clk_branch { #define CLOCK_FLAG_VAL_INIT BIT(16) #define MUX_CLK_SW BIT(17) #define GATE_CLK_HW BIT(18) +#define DIV_CLK_NO_MASK BIT(19) #define LGM_MUX(_id, _name, _pdata, _f, _reg, \ _shift, _width, _cf, _v) \ diff --git a/drivers/clk/x86/clk-lgm.c b/drivers/clk/x86/clk-lgm.c index e312af42e97a..4de77b2c750d 100644 --- a/drivers/clk/x86/clk-lgm.c +++ b/drivers/clk/x86/clk-lgm.c @@ -255,8 +255,8 @@ static const struct lgm_clk_branch lgm_branch_clks[] = { LGM_FIXED(LGM_CLK_SLIC, "slic", NULL, 0, CGU_IF_CLK1, 8, 2, CLOCK_FLAG_VAL_INIT, 8192000, 2), LGM_FIXED(LGM_CLK_DOCSIS, "v_docsis", NULL, 0, 0, 0, 0, 0, 16000000, 0), - LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", 0, CGU_PCMCR, - 25, 3, 0, 0, 0, 0, dcl_div), + LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", CLK_SET_RATE_PARENT, CGU_PCMCR, + 25, 3, 0, 0, DIV_CLK_NO_MASK, 0, dcl_div), LGM_MUX(LGM_CLK_PCM, "pcm", pcm_p, 0, CGU_C55_PCMCR, 0, 1, CLK_MUX_ROUND_CLOSEST, 0), LGM_FIXED_FACTOR(LGM_CLK_DDR_PHY, "ddr_phy", "ddr", From 1423d88753ed4cc9c2564a76ef0858b927dbc5a7 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 17 Oct 2022 16:22:39 -0400 Subject: [PATCH 0065/1017] powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G [ Upstream commit 36926a7d70c2d462fca1ed85bfee000d17fd8662 ] On the T208X SoCs, MAC1 and MAC2 support XGMII. Add some new MAC dtsi fragments, and mark the QMAN ports as 10G. Fixes: da414bb923d9 ("powerpc/mpc85xx: Add FSL QorIQ DPAA FMan support to the SoC device tree(s)") Signed-off-by: Sean Anderson Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi | 44 +++++++++++++++++++ .../boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi | 44 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/t2081si-post.dtsi | 4 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi new file mode 100644 index 000000000000..437dab3fc017 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later +/* + * QorIQ FMan v3 10g port #2 device tree stub [ controller @ offset 0x400000 ] + * + * Copyright 2022 Sean Anderson + * Copyright 2012 - 2015 Freescale Semiconductor Inc. + */ + +fman@400000 { + fman0_rx_0x08: port@88000 { + cell-index = <0x8>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x88000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x28: port@a8000 { + cell-index = <0x28>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa8000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@e0000 { + cell-index = <0>; + compatible = "fsl,fman-memac"; + reg = <0xe0000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy0>; + }; + + mdio@e1000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ + + pcsphy0: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi new file mode 100644 index 000000000000..ad116b17850a --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later +/* + * QorIQ FMan v3 10g port #3 device tree stub [ controller @ offset 0x400000 ] + * + * Copyright 2022 Sean Anderson + * Copyright 2012 - 2015 Freescale Semiconductor Inc. + */ + +fman@400000 { + fman0_rx_0x09: port@89000 { + cell-index = <0x9>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x89000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x29: port@a9000 { + cell-index = <0x29>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa9000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@e2000 { + cell-index = <1>; + compatible = "fsl,fman-memac"; + reg = <0xe2000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy1>; + }; + + mdio@e3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ + + pcsphy1: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi index ecbb447920bc..74e17e134387 100644 --- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi @@ -609,8 +609,8 @@ /include/ "qoriq-bman1.dtsi" /include/ "qoriq-fman3-0.dtsi" -/include/ "qoriq-fman3-0-1g-0.dtsi" -/include/ "qoriq-fman3-0-1g-1.dtsi" +/include/ "qoriq-fman3-0-10g-2.dtsi" +/include/ "qoriq-fman3-0-10g-3.dtsi" /include/ "qoriq-fman3-0-1g-2.dtsi" /include/ "qoriq-fman3-0-1g-3.dtsi" /include/ "qoriq-fman3-0-1g-4.dtsi" From 2da1f95085791ad8912dc4d9584e2ae003616662 Mon Sep 17 00:00:00 2001 From: Rahul Tanwar Date: Tue, 25 Oct 2022 19:03:57 +0800 Subject: [PATCH 0066/1017] clk: mxl: syscon_node_to_regmap() returns error pointers [ Upstream commit 7256d1f4618b40792d1e9b9b6cb1406a13cad2dd ] Commit 036177310bac ("clk: mxl: Switch from direct readl/writel based IO to regmap based IO") introduced code resulting in below warning issued by the smatch static checker. drivers/clk/x86/clk-lgm.c:441 lgm_cgu_probe() warn: passing zero to 'PTR_ERR' Fix the warning by replacing incorrect IS_ERR_OR_NULL() with IS_ERR(). Fixes: 036177310bac ("clk: mxl: Switch from direct readl/writel based IO to regmap based IO") Reported-by: Dan Carpenter Signed-off-by: Rahul Tanwar Link: https://lore.kernel.org/r/49e339d4739e4ae4c92b00c1b2918af0755d4122.1666695221.git.rtanwar@maxlinear.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/x86/clk-lgm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/x86/clk-lgm.c b/drivers/clk/x86/clk-lgm.c index 4de77b2c750d..f69455dd1c98 100644 --- a/drivers/clk/x86/clk-lgm.c +++ b/drivers/clk/x86/clk-lgm.c @@ -436,7 +436,7 @@ static int lgm_cgu_probe(struct platform_device *pdev) ctx->clk_data.num = CLK_NR_CLKS; ctx->membase = syscon_node_to_regmap(np); - if (IS_ERR_OR_NULL(ctx->membase)) { + if (IS_ERR(ctx->membase)) { dev_err(dev, "Failed to get clk CGU iomem\n"); return PTR_ERR(ctx->membase); } From 119e75d8fe4ddc758a04568fdf28f3c3cda130e9 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 1 Jun 2022 22:45:33 +0200 Subject: [PATCH 0067/1017] random: always mix cycle counter in add_latent_entropy() [ Upstream commit d7bf7f3b813e3755226bcb5114ad2ac477514ebf ] add_latent_entropy() is called every time a process forks, in kernel_clone(). This in turn calls add_device_randomness() using the latent entropy global state. add_device_randomness() does two things: 2) Mixes into the input pool the latent entropy argument passed; and 1) Mixes in a cycle counter, a sort of measurement of when the event took place, the high precision bits of which are presumably difficult to predict. (2) is impossible without CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y. But (1) is always possible. However, currently CONFIG_GCC_PLUGIN_LATENT_ENTROPY=n disables both (1) and (2), instead of just (2). This commit causes the CONFIG_GCC_PLUGIN_LATENT_ENTROPY=n case to still do (1) by passing NULL (len 0) to add_device_randomness() when add_latent_ entropy() is called. Cc: Dominik Brodowski Cc: PaX Team Cc: Emese Revfy Fixes: 38addce8b600 ("gcc-plugins: Add latent_entropy plugin") Signed-off-by: Jason A. Donenfeld Signed-off-by: Sasha Levin --- include/linux/random.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/random.h b/include/linux/random.h index 917470c4490a..ed2bac6c7a8a 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -19,14 +19,14 @@ void add_input_randomness(unsigned int type, unsigned int code, void add_interrupt_randomness(int irq) __latent_entropy; void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); -#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__) static inline void add_latent_entropy(void) { +#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__) add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy)); -} #else -static inline void add_latent_entropy(void) { } + add_device_randomness(NULL, 0); #endif +} void get_random_bytes(void *buf, size_t len); size_t __must_check get_random_bytes_arch(void *buf, size_t len); From a7ef904b68f001b1faef6ba324a267b9b5d74000 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 30 Sep 2022 23:36:32 +0000 Subject: [PATCH 0068/1017] KVM: x86: Fail emulation during EMULTYPE_SKIP on any exception [ Upstream commit 17122c06b86c9f77f45b86b8e62c3ed440847a59 ] Treat any exception during instruction decode for EMULTYPE_SKIP as a "full" emulation failure, i.e. signal failure instead of queuing the exception. When decoding purely to skip an instruction, KVM and/or the CPU has already done some amount of emulation that cannot be unwound, e.g. on an EPT misconfig VM-Exit KVM has already processeed the emulated MMIO. KVM already does this if a #UD is encountered, but not for other exceptions, e.g. if a #PF is encountered during fetch. In SVM's soft-injection use case, queueing the exception is particularly problematic as queueing exceptions while injecting events can put KVM into an infinite loop due to bailing from VM-Enter to service the newly pending exception. E.g. multiple warnings to detect such behavior fire: ------------[ cut here ]------------ WARNING: CPU: 3 PID: 1017 at arch/x86/kvm/x86.c:9873 kvm_arch_vcpu_ioctl_run+0x1de5/0x20a0 [kvm] Modules linked in: kvm_amd ccp kvm irqbypass CPU: 3 PID: 1017 Comm: svm_nested_soft Not tainted 6.0.0-rc1+ #220 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:kvm_arch_vcpu_ioctl_run+0x1de5/0x20a0 [kvm] Call Trace: kvm_vcpu_ioctl+0x223/0x6d0 [kvm] __x64_sys_ioctl+0x85/0xc0 do_syscall_64+0x2b/0x50 entry_SYSCALL_64_after_hwframe+0x46/0xb0 ---[ end trace 0000000000000000 ]--- ------------[ cut here ]------------ WARNING: CPU: 3 PID: 1017 at arch/x86/kvm/x86.c:9987 kvm_arch_vcpu_ioctl_run+0x12a3/0x20a0 [kvm] Modules linked in: kvm_amd ccp kvm irqbypass CPU: 3 PID: 1017 Comm: svm_nested_soft Tainted: G W 6.0.0-rc1+ #220 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:kvm_arch_vcpu_ioctl_run+0x12a3/0x20a0 [kvm] Call Trace: kvm_vcpu_ioctl+0x223/0x6d0 [kvm] __x64_sys_ioctl+0x85/0xc0 do_syscall_64+0x2b/0x50 entry_SYSCALL_64_after_hwframe+0x46/0xb0 ---[ end trace 0000000000000000 ]--- Fixes: 6ea6e84309ca ("KVM: x86: inject exceptions produced by x86_decode_insn") Signed-off-by: Sean Christopherson Link: https://lore.kernel.org/r/20220930233632.1725475-1-seanjc@google.com Signed-off-by: Sasha Levin --- arch/x86/kvm/x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 554d37873c25..0ccc8d1b972c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7534,7 +7534,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, write_fault_to_spt, emulation_type)) return 1; - if (ctxt->have_exception) { + + if (ctxt->have_exception && + !(emulation_type & EMULTYPE_SKIP)) { /* * #UD should result in just EMULATION_FAILED, and trap-like * exception should not be encountered during decode. From c41d856b7064e20252e660ff4f2cc49569213b31 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 30 Sep 2022 23:40:31 +0000 Subject: [PATCH 0069/1017] KVM: SVM: Skip WRMSR fastpath on VM-Exit if next RIP isn't valid [ Upstream commit 5c30e8101e8d5d020b1d7119117889756a6ed713 ] Skip the WRMSR fastpath in SVM's VM-Exit handler if the next RIP isn't valid, e.g. because KVM is running with nrips=false. SVM must decode and emulate to skip the WRMSR if the CPU doesn't provide the next RIP. Getting the instruction bytes to decode the WRMSR requires reading guest memory, which in turn means dereferencing memslots, and that isn't safe because KVM doesn't hold SRCU when the fastpath runs. Don't bother trying to enable the fastpath for this case, e.g. by doing only the WRMSR and leaving the "skip" until later. NRIPS is supported on all modern CPUs (KVM has considered making it mandatory), and the next RIP will be valid the vast, vast majority of the time. ============================= WARNING: suspicious RCU usage 6.0.0-smp--4e557fcd3d80-skip #13 Tainted: G O ----------------------------- include/linux/kvm_host.h:954 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 1 lock held by stable/206475: #0: ffff9d9dfebcc0f0 (&vcpu->mutex){+.+.}-{3:3}, at: kvm_vcpu_ioctl+0x8b/0x620 [kvm] stack backtrace: CPU: 152 PID: 206475 Comm: stable Tainted: G O 6.0.0-smp--4e557fcd3d80-skip #13 Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 10.48.0 01/27/2022 Call Trace: dump_stack_lvl+0x69/0xaa dump_stack+0x10/0x12 lockdep_rcu_suspicious+0x11e/0x130 kvm_vcpu_gfn_to_memslot+0x155/0x190 [kvm] kvm_vcpu_gfn_to_hva_prot+0x18/0x80 [kvm] paging64_walk_addr_generic+0x183/0x450 [kvm] paging64_gva_to_gpa+0x63/0xd0 [kvm] kvm_fetch_guest_virt+0x53/0xc0 [kvm] __do_insn_fetch_bytes+0x18b/0x1c0 [kvm] x86_decode_insn+0xf0/0xef0 [kvm] x86_emulate_instruction+0xba/0x790 [kvm] kvm_emulate_instruction+0x17/0x20 [kvm] __svm_skip_emulated_instruction+0x85/0x100 [kvm_amd] svm_skip_emulated_instruction+0x13/0x20 [kvm_amd] handle_fastpath_set_msr_irqoff+0xae/0x180 [kvm] svm_vcpu_run+0x4b8/0x5a0 [kvm_amd] vcpu_enter_guest+0x16ca/0x22f0 [kvm] kvm_arch_vcpu_ioctl_run+0x39d/0x900 [kvm] kvm_vcpu_ioctl+0x538/0x620 [kvm] __se_sys_ioctl+0x77/0xc0 __x64_sys_ioctl+0x1d/0x20 do_syscall_64+0x3d/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: 404d5d7bff0d ("KVM: X86: Introduce more exit_fastpath_completion enum values") Signed-off-by: Sean Christopherson Link: https://lore.kernel.org/r/20220930234031.1732249-1-seanjc@google.com Signed-off-by: Sasha Levin --- arch/x86/kvm/svm/svm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index c34ba034ca11..5775983fec56 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3480,8 +3480,14 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu) static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) { - if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && - to_svm(vcpu)->vmcb->control.exit_info_1) + struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control; + + /* + * Note, the next RIP must be provided as SRCU isn't held, i.e. KVM + * can't read guest memory (dereference memslots) to decode the WRMSR. + */ + if (control->exit_code == SVM_EXIT_MSR && control->exit_info_1 && + nrips && control->next_rip) return handle_fastpath_set_msr_irqoff(vcpu); return EXIT_FASTPATH_NONE; From 1b0cafaae8884726c597caded50af185ffc13349 Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Wed, 19 Oct 2022 14:36:20 -0700 Subject: [PATCH 0070/1017] KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS [ Upstream commit 2e7eab81425ad6c875f2ed47c0ce01e78afc38a5 ] According to Intel's document on Indirect Branch Restricted Speculation, "Enabling IBRS does not prevent software from controlling the predicted targets of indirect branches of unrelated software executed later at the same predictor mode (for example, between two different user applications, or two different virtual machines). Such isolation can be ensured through use of the Indirect Branch Predictor Barrier (IBPB) command." This applies to both basic and enhanced IBRS. Since L1 and L2 VMs share hardware predictor modes (guest-user and guest-kernel), hardware IBRS is not sufficient to virtualize IBRS. (The way that basic IBRS is implemented on pre-eIBRS parts, hardware IBRS is actually sufficient in practice, even though it isn't sufficient architecturally.) For virtual CPUs that support IBRS, add an indirect branch prediction barrier on emulated VM-exit, to ensure that the predicted targets of indirect branches executed in L1 cannot be controlled by software that was executed in L2. Since we typically don't intercept guest writes to IA32_SPEC_CTRL, perform the IBPB at emulated VM-exit regardless of the current IA32_SPEC_CTRL.IBRS value, even though the IBPB could technically be deferred until L1 sets IA32_SPEC_CTRL.IBRS, if IA32_SPEC_CTRL.IBRS is clear at emulated VM-exit. This is CVE-2022-2196. Fixes: 5c911beff20a ("KVM: nVMX: Skip IBPB when switching between vmcs01 and vmcs02") Cc: Sean Christopherson Signed-off-by: Jim Mattson Reviewed-by: Sean Christopherson Link: https://lore.kernel.org/r/20221019213620.1953281-3-jmattson@google.com Signed-off-by: Sean Christopherson Signed-off-by: Sasha Levin --- arch/x86/kvm/vmx/nested.c | 11 +++++++++++ arch/x86/kvm/vmx/vmx.c | 6 ++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index f15ddf58a5bc..91371b01eae0 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4556,6 +4556,17 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, vmx_switch_vmcs(vcpu, &vmx->vmcs01); + /* + * If IBRS is advertised to the vCPU, KVM must flush the indirect + * branch predictors when transitioning from L2 to L1, as L1 expects + * hardware (KVM in this case) to provide separate predictor modes. + * Bare metal isolates VMX root (host) from VMX non-root (guest), but + * doesn't isolate different VMCSs, i.e. in this case, doesn't provide + * separate modes for L2 vs L1. + */ + if (guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) + indirect_branch_prediction_barrier(); + /* Update any VMCS fields that might have changed while L2 ran */ vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, vmx->msr_autoload.host.nr); vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, vmx->msr_autoload.guest.nr); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 8f7152e158e2..c37cbd3fdd85 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1431,8 +1431,10 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, /* * No indirect branch prediction barrier needed when switching - * the active VMCS within a guest, e.g. on nested VM-Enter. - * The L1 VMM can protect itself with retpolines, IBPB or IBRS. + * the active VMCS within a vCPU, unless IBRS is advertised to + * the vCPU. To minimize the number of IBPBs executed, KVM + * performs IBPB on nested VM-Exit (a single nested transition + * may switch the active VMCS multiple times). */ if (!buddy || WARN_ON_ONCE(buddy->vmcs != prev)) indirect_branch_prediction_barrier(); From 6a3fb887da7d85aaf9a32539976b8ceb12a6306d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 19 Dec 2022 11:39:27 +0100 Subject: [PATCH 0071/1017] can: kvaser_usb: hydra: help gcc-13 to figure out cmd_len MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f006229135b7debf4037adb1eb93e358559593db ] Debian's gcc-13 [1] throws the following error in kvaser_usb_hydra_cmd_size(): [1] gcc version 13.0.0 20221214 (experimental) [master r13-4693-g512098a3316] (Debian 13-20221214-1) | drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c:502:65: error: | array subscript ‘struct kvaser_cmd_ext[0]’ is partly outside array | bounds of ‘unsigned char[32]’ [-Werror=array-bounds=] | 502 | ret = le16_to_cpu(((struct kvaser_cmd_ext *)cmd)->len); kvaser_usb_hydra_cmd_size() returns the size of given command. It depends on the command number (cmd->header.cmd_no). For extended commands (cmd->header.cmd_no == CMD_EXTENDED) the above shown code is executed. Help gcc to recognize that this code path is not taken in all cases, by calling kvaser_usb_hydra_cmd_size() directly after assigning the command number. Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family") Cc: Jimmy Assarsson Cc: Anssi Hannula Link: https://lore.kernel.org/all/20221219110104.1073881-1-mkl@pengutronix.de Tested-by: Jimmy Assarsson Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index 2764fdd7e84b..233bbfeaa771 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -518,6 +518,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev, u8 cmd_no, int channel) { struct kvaser_cmd *cmd; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); @@ -525,6 +526,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev, return -ENOMEM; cmd->header.cmd_no = cmd_no; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); if (channel < 0) { kvaser_usb_hydra_set_cmd_dest_he (cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL); @@ -541,7 +543,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev, kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) goto end; @@ -557,6 +559,7 @@ kvaser_usb_hydra_send_simple_cmd_async(struct kvaser_usb_net_priv *priv, { struct kvaser_cmd *cmd; struct kvaser_usb *dev = priv->dev; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_ATOMIC); @@ -564,14 +567,14 @@ kvaser_usb_hydra_send_simple_cmd_async(struct kvaser_usb_net_priv *priv, return -ENOMEM; cmd->header.cmd_no = cmd_no; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); kvaser_usb_hydra_set_cmd_dest_he (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd_async(priv, cmd, - kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd_async(priv, cmd, cmd_len); if (err) kfree(cmd); @@ -715,6 +718,7 @@ static int kvaser_usb_hydra_get_single_capability(struct kvaser_usb *dev, { struct kvaser_usb_dev_card_data *card_data = &dev->card_data; struct kvaser_cmd *cmd; + size_t cmd_len; u32 value = 0; u32 mask = 0; u16 cap_cmd_res; @@ -726,13 +730,14 @@ static int kvaser_usb_hydra_get_single_capability(struct kvaser_usb *dev, return -ENOMEM; cmd->header.cmd_no = CMD_GET_CAPABILITIES_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); cmd->cap_req.cap_cmd = cpu_to_le16(cap_cmd_req); kvaser_usb_hydra_set_cmd_dest_he(cmd, card_data->hydra.sysdbg_he); kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) goto end; @@ -1555,6 +1560,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv, struct kvaser_usb *dev = priv->dev; struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv; struct kvaser_cmd *cmd; + size_t cmd_len; int err; if (!hydra) @@ -1565,6 +1571,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv, return -ENOMEM; cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); kvaser_usb_hydra_set_cmd_dest_he (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); kvaser_usb_hydra_set_cmd_transid @@ -1574,7 +1581,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv, reinit_completion(&priv->get_busparams_comp); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) return err; @@ -1601,6 +1608,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev, struct kvaser_cmd *cmd; struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); @@ -1608,6 +1616,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev, return -ENOMEM; cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); memcpy(&cmd->set_busparams_req.busparams_nominal, busparams, sizeof(cmd->set_busparams_req.busparams_nominal)); @@ -1616,7 +1625,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev, kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); kfree(cmd); @@ -1629,6 +1638,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev, struct kvaser_cmd *cmd; struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); @@ -1636,6 +1646,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev, return -ENOMEM; cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); memcpy(&cmd->set_busparams_req.busparams_data, busparams, sizeof(cmd->set_busparams_req.busparams_data)); @@ -1653,7 +1664,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev, kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); kfree(cmd); @@ -1781,6 +1792,7 @@ static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev) static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev) { struct kvaser_cmd *cmd; + size_t cmd_len; int err; u32 flags; struct kvaser_usb_dev_card_data *card_data = &dev->card_data; @@ -1790,6 +1802,7 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev) return -ENOMEM; cmd->header.cmd_no = CMD_GET_SOFTWARE_DETAILS_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); cmd->sw_detail_req.use_ext_cmd = 1; kvaser_usb_hydra_set_cmd_dest_he (cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL); @@ -1797,7 +1810,7 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev) kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) goto end; @@ -1913,6 +1926,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv) { struct kvaser_usb *dev = priv->dev; struct kvaser_cmd *cmd; + size_t cmd_len; int err; if ((priv->can.ctrlmode & @@ -1928,6 +1942,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv) return -ENOMEM; cmd->header.cmd_no = CMD_SET_DRIVERMODE_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); kvaser_usb_hydra_set_cmd_dest_he (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); kvaser_usb_hydra_set_cmd_transid @@ -1937,7 +1952,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv) else cmd->set_ctrlmode.mode = KVASER_USB_HYDRA_CTRLMODE_NORMAL; - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); kfree(cmd); return err; From b50f6fc9d79f0dc875df004c73b6b3fd31186b0b Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Fri, 16 Dec 2022 12:29:37 -0500 Subject: [PATCH 0072/1017] powerpc: dts: t208x: Disable 10G on MAC1 and MAC2 [ Upstream commit 8d8bee13ae9e316443c6666286360126a19c8d94 ] There aren't enough resources to run these ports at 10G speeds. Disable 10G for these ports, reverting to the previous speed. Fixes: 36926a7d70c2 ("powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G") Reported-by: Camelia Alexandra Groza Signed-off-by: Sean Anderson Reviewed-by: Camelia Groza Tested-by: Camelia Groza Link: https://lore.kernel.org/r/20221216172937.2960054-1-sean.anderson@seco.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- arch/powerpc/boot/dts/fsl/t2081si-post.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi index 74e17e134387..27714dc2f04a 100644 --- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi @@ -659,3 +659,19 @@ interrupts = <16 2 1 9>; }; }; + +&fman0_rx_0x08 { + /delete-property/ fsl,fman-10g-port; +}; + +&fman0_tx_0x28 { + /delete-property/ fsl,fman-10g-port; +}; + +&fman0_rx_0x09 { + /delete-property/ fsl,fman-10g-port; +}; + +&fman0_tx_0x29 { + /delete-property/ fsl,fman-10g-port; +}; From 3d743415c6fb092167df6c23e9c7e9f6df7db625 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Fri, 30 Dec 2022 00:56:41 +0800 Subject: [PATCH 0073/1017] drm/i915/gvt: fix double free bug in split_2MB_gtt_entry commit 4a61648af68f5ba4884f0e3b494ee1cabc4b6620 upstream. If intel_gvt_dma_map_guest_page failed, it will call ppgtt_invalidate_spt, which will finally free the spt. But the caller function ppgtt_populate_spt_by_guest_entry does not notice that, it will free spt again in its error path. Fix this by canceling the mapping of DMA address and freeing sub_spt. Besides, leave the handle of spt destroy to caller function instead of callee function when error occurs. Fixes: b901b252b6cf ("drm/i915/gvt: Add 2M huge gtt support") Signed-off-by: Zheng Wang Reviewed-by: Zhenyu Wang Signed-off-by: Zhenyu Wang Link: http://patchwork.freedesktop.org/patch/msgid/20221229165641.1192455-1-zyytlz.wz@163.com Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/gvt/gtt.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index a3a4305eda01..0201f9b5f87e 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1192,10 +1192,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) { - ppgtt_invalidate_spt(spt); - return ret; - } + if (ret) + goto err; sub_se.val64 = se->val64; /* Copy the PAT field from PDE. */ @@ -1214,6 +1212,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, ops->set_pfn(se, sub_spt->shadow_page.mfn); ppgtt_set_shadow_entry(spt, se, index); return 0; +err: + /* Cancel the existing addess mappings of DMA addr. */ + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(sub_spt, &sub_se); + } + /* Release the new allocated spt. */ + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); + ppgtt_free_spt(sub_spt); + return ret; } static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, From 267f62b7f3ee94bb0242a72a173073e0da04836f Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Thu, 30 Dec 2021 22:55:47 +0300 Subject: [PATCH 0074/1017] mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh commit 8b5cb7e41d9d77ffca036b0239177de123394a55 upstream. Syzbot hit NULL deref in rhashtable_free_and_destroy(). The problem was in mesh_paths and mpp_paths being NULL. mesh_pathtbl_init() could fail in case of memory allocation failure, but nobody cared, since ieee80211_mesh_init_sdata() returns void. It led to leaving 2 pointers as NULL. Syzbot has found null deref on exit path, but it could happen anywhere else, because code assumes these pointers are valid. Since all ieee80211_*_setup_sdata functions are void and do not fail, let's embedd mesh_paths and mpp_paths into parent struct to avoid adding error handling on higher levels and follow the pattern of others setup_sdata functions Fixes: 60854fd94573 ("mac80211: mesh: convert path table to rhashtable") Reported-and-tested-by: syzbot+860268315ba86ea6b96b@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Link: https://lore.kernel.org/r/20211230195547.23977-1-paskripkin@gmail.com Signed-off-by: Johannes Berg [pchelkin@ispras.ru: adapt a comment spell fixing issue] Signed-off-by: Fedor Pchelkin Signed-off-by: Greg Kroah-Hartman --- net/mac80211/ieee80211_i.h | 24 +++++++++- net/mac80211/mesh.h | 22 +-------- net/mac80211/mesh_pathtbl.c | 89 +++++++++++++------------------------ 3 files changed, 54 insertions(+), 81 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 63499db5c63d..bd349ae9ee4b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -644,6 +644,26 @@ struct mesh_csa_settings { struct cfg80211_csa_settings settings; }; +/** + * struct mesh_table + * + * @known_gates: list of known mesh gates and their mpaths by the station. The + * gate's mpath may or may not be resolved and active. + * @gates_lock: protects updates to known_gates + * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr + * @walk_head: linked list containing all mesh_path objects + * @walk_lock: lock protecting walk_head + * @entries: number of entries in the table + */ +struct mesh_table { + struct hlist_head known_gates; + spinlock_t gates_lock; + struct rhashtable rhead; + struct hlist_head walk_head; + spinlock_t walk_lock; + atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ +}; + struct ieee80211_if_mesh { struct timer_list housekeeping_timer; struct timer_list mesh_path_timer; @@ -718,8 +738,8 @@ struct ieee80211_if_mesh { /* offset from skb->data while building IE */ int meshconf_offset; - struct mesh_table *mesh_paths; - struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ + struct mesh_table mesh_paths; + struct mesh_table mpp_paths; /* Store paths for MPP&MAP */ int mesh_paths_generation; int mpp_paths_generation; }; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 40492d1bd8fd..b2b717a78114 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -127,26 +127,6 @@ struct mesh_path { u32 path_change_count; }; -/** - * struct mesh_table - * - * @known_gates: list of known mesh gates and their mpaths by the station. The - * gate's mpath may or may not be resolved and active. - * @gates_lock: protects updates to known_gates - * @rhead: the rhashtable containing struct mesh_paths, keyed by dest addr - * @walk_head: linked list containging all mesh_path objects - * @walk_lock: lock protecting walk_head - * @entries: number of entries in the table - */ -struct mesh_table { - struct hlist_head known_gates; - spinlock_t gates_lock; - struct rhashtable rhead; - struct hlist_head walk_head; - spinlock_t walk_lock; - atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ -}; - /* Recent multicast cache */ /* RMC_BUCKETS must be a power of 2, maximum 256 */ #define RMC_BUCKETS 256 @@ -308,7 +288,7 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); void mesh_path_flush_pending(struct mesh_path *mpath); void mesh_path_tx_pending(struct mesh_path *mpath); -int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata); +void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata); void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata); int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr); void mesh_path_timer(struct timer_list *t); diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index c2b051e0610a..d936ef0c17a3 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -47,32 +47,24 @@ static void mesh_path_rht_free(void *ptr, void *tblptr) mesh_path_free_rcu(tbl, mpath); } -static struct mesh_table *mesh_table_alloc(void) +static void mesh_table_init(struct mesh_table *tbl) { - struct mesh_table *newtbl; + INIT_HLIST_HEAD(&tbl->known_gates); + INIT_HLIST_HEAD(&tbl->walk_head); + atomic_set(&tbl->entries, 0); + spin_lock_init(&tbl->gates_lock); + spin_lock_init(&tbl->walk_lock); - newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC); - if (!newtbl) - return NULL; - - INIT_HLIST_HEAD(&newtbl->known_gates); - INIT_HLIST_HEAD(&newtbl->walk_head); - atomic_set(&newtbl->entries, 0); - spin_lock_init(&newtbl->gates_lock); - spin_lock_init(&newtbl->walk_lock); - if (rhashtable_init(&newtbl->rhead, &mesh_rht_params)) { - kfree(newtbl); - return NULL; - } - - return newtbl; + /* rhashtable_init() may fail only in case of wrong + * mesh_rht_params + */ + WARN_ON(rhashtable_init(&tbl->rhead, &mesh_rht_params)); } static void mesh_table_free(struct mesh_table *tbl) { rhashtable_free_and_destroy(&tbl->rhead, mesh_path_rht_free, tbl); - kfree(tbl); } /** @@ -238,13 +230,13 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst, struct mesh_path * mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) { - return mpath_lookup(sdata->u.mesh.mesh_paths, dst, sdata); + return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata); } struct mesh_path * mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) { - return mpath_lookup(sdata->u.mesh.mpp_paths, dst, sdata); + return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata); } static struct mesh_path * @@ -281,7 +273,7 @@ __mesh_path_lookup_by_idx(struct mesh_table *tbl, int idx) struct mesh_path * mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) { - return __mesh_path_lookup_by_idx(sdata->u.mesh.mesh_paths, idx); + return __mesh_path_lookup_by_idx(&sdata->u.mesh.mesh_paths, idx); } /** @@ -296,7 +288,7 @@ mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) struct mesh_path * mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) { - return __mesh_path_lookup_by_idx(sdata->u.mesh.mpp_paths, idx); + return __mesh_path_lookup_by_idx(&sdata->u.mesh.mpp_paths, idx); } /** @@ -309,7 +301,7 @@ int mesh_path_add_gate(struct mesh_path *mpath) int err; rcu_read_lock(); - tbl = mpath->sdata->u.mesh.mesh_paths; + tbl = &mpath->sdata->u.mesh.mesh_paths; spin_lock_bh(&mpath->state_lock); if (mpath->is_gate) { @@ -418,7 +410,7 @@ struct mesh_path *mesh_path_add(struct ieee80211_sub_if_data *sdata, if (!new_mpath) return ERR_PTR(-ENOMEM); - tbl = sdata->u.mesh.mesh_paths; + tbl = &sdata->u.mesh.mesh_paths; spin_lock_bh(&tbl->walk_lock); mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead, &new_mpath->rhash, @@ -460,7 +452,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, return -ENOMEM; memcpy(new_mpath->mpp, mpp, ETH_ALEN); - tbl = sdata->u.mesh.mpp_paths; + tbl = &sdata->u.mesh.mpp_paths; spin_lock_bh(&tbl->walk_lock); ret = rhashtable_lookup_insert_fast(&tbl->rhead, @@ -489,7 +481,7 @@ int mpp_path_add(struct ieee80211_sub_if_data *sdata, void mesh_plink_broken(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; - struct mesh_table *tbl = sdata->u.mesh.mesh_paths; + struct mesh_table *tbl = &sdata->u.mesh.mesh_paths; static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct mesh_path *mpath; @@ -548,7 +540,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath) void mesh_path_flush_by_nexthop(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; - struct mesh_table *tbl = sdata->u.mesh.mesh_paths; + struct mesh_table *tbl = &sdata->u.mesh.mesh_paths; struct mesh_path *mpath; struct hlist_node *n; @@ -563,7 +555,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata, const u8 *proxy) { - struct mesh_table *tbl = sdata->u.mesh.mpp_paths; + struct mesh_table *tbl = &sdata->u.mesh.mpp_paths; struct mesh_path *mpath; struct hlist_node *n; @@ -597,8 +589,8 @@ static void table_flush_by_iface(struct mesh_table *tbl) */ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) { - table_flush_by_iface(sdata->u.mesh.mesh_paths); - table_flush_by_iface(sdata->u.mesh.mpp_paths); + table_flush_by_iface(&sdata->u.mesh.mesh_paths); + table_flush_by_iface(&sdata->u.mesh.mpp_paths); } /** @@ -644,7 +636,7 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) /* flush relevant mpp entries first */ mpp_flush_by_proxy(sdata, addr); - err = table_path_del(sdata->u.mesh.mesh_paths, sdata, addr); + err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr); sdata->u.mesh.mesh_paths_generation++; return err; } @@ -682,7 +674,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath) struct mesh_path *gate; bool copy = false; - tbl = sdata->u.mesh.mesh_paths; + tbl = &sdata->u.mesh.mesh_paths; rcu_read_lock(); hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) { @@ -762,29 +754,10 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop) mesh_path_tx_pending(mpath); } -int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) +void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) { - struct mesh_table *tbl_path, *tbl_mpp; - int ret; - - tbl_path = mesh_table_alloc(); - if (!tbl_path) - return -ENOMEM; - - tbl_mpp = mesh_table_alloc(); - if (!tbl_mpp) { - ret = -ENOMEM; - goto free_path; - } - - sdata->u.mesh.mesh_paths = tbl_path; - sdata->u.mesh.mpp_paths = tbl_mpp; - - return 0; - -free_path: - mesh_table_free(tbl_path); - return ret; + mesh_table_init(&sdata->u.mesh.mesh_paths); + mesh_table_init(&sdata->u.mesh.mpp_paths); } static @@ -806,12 +779,12 @@ void mesh_path_tbl_expire(struct ieee80211_sub_if_data *sdata, void mesh_path_expire(struct ieee80211_sub_if_data *sdata) { - mesh_path_tbl_expire(sdata, sdata->u.mesh.mesh_paths); - mesh_path_tbl_expire(sdata, sdata->u.mesh.mpp_paths); + mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths); + mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths); } void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) { - mesh_table_free(sdata->u.mesh.mesh_paths); - mesh_table_free(sdata->u.mesh.mpp_paths); + mesh_table_free(&sdata->u.mesh.mesh_paths); + mesh_table_free(&sdata->u.mesh.mpp_paths); } From 3b6ce54cfa2c04f0636fd0c985913af8703b408d Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Tue, 21 Feb 2023 12:30:15 -0800 Subject: [PATCH 0075/1017] uaccess: Add speculation barrier to copy_from_user() commit 74e19ef0ff8061ef55957c3abd71614ef0f42f47 upstream. The results of "access_ok()" can be mis-speculated. The result is that you can end speculatively: if (access_ok(from, size)) // Right here even for bad from/size combinations. On first glance, it would be ideal to just add a speculation barrier to "access_ok()" so that its results can never be mis-speculated. But there are lots of system calls just doing access_ok() via "copy_to_user()" and friends (example: fstat() and friends). Those are generally not problematic because they do not _consume_ data from userspace other than the pointer. They are also very quick and common system calls that should not be needlessly slowed down. "copy_from_user()" on the other hand uses a user-controller pointer and is frequently followed up with code that might affect caches. Take something like this: if (!copy_from_user(&kernelvar, uptr, size)) do_something_with(kernelvar); If userspace passes in an evil 'uptr' that *actually* points to a kernel addresses, and then do_something_with() has cache (or other) side-effects, it could allow userspace to infer kernel data values. Add a barrier to the common copy_from_user() code to prevent mis-speculated values which happen after the copy. Also add a stub for architectures that do not define barrier_nospec(). This makes the macro usable in generic code. Since the barrier is now usable in generic code, the x86 #ifdef in the BPF code can also go away. Reported-by: Jordy Zomer Suggested-by: Linus Torvalds Signed-off-by: Dave Hansen Reviewed-by: Thomas Gleixner Acked-by: Daniel Borkmann # BPF bits Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- include/linux/nospec.h | 4 ++++ kernel/bpf/core.c | 2 -- lib/usercopy.c | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/linux/nospec.h b/include/linux/nospec.h index c1e79f72cd89..9f0af4f116d9 100644 --- a/include/linux/nospec.h +++ b/include/linux/nospec.h @@ -11,6 +11,10 @@ struct task_struct; +#ifndef barrier_nospec +# define barrier_nospec() do { } while (0) +#endif + /** * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise * @index: array element index diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index fd2aa6b9909e..c18aed60ce40 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1642,9 +1642,7 @@ out: * reuse preexisting logic from Spectre v1 mitigation that * happens to produce the required code on x86 for v4 as well. */ -#ifdef CONFIG_X86 barrier_nospec(); -#endif CONT; #define LDST(SIZEOP, SIZE) \ STX_MEM_##SIZEOP: \ diff --git a/lib/usercopy.c b/lib/usercopy.c index 7413dd300516..7ee63df042d7 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -3,6 +3,7 @@ #include #include #include +#include /* out-of-line parts */ @@ -12,6 +13,12 @@ unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n unsigned long res = n; might_fault(); if (!should_fail_usercopy() && likely(access_ok(from, n))) { + /* + * Ensure that bad access_ok() speculation will not + * lead to nasty side effects *after* the copy is + * finished: + */ + barrier_nospec(); instrument_copy_from_user(to, from, n); res = raw_copy_from_user(to, from, n); } From f3f6b33b77bac0bd27f1f1bec05ab58a54948fc9 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Tue, 21 Feb 2023 02:04:46 +0800 Subject: [PATCH 0076/1017] Revert "Revert "block: nbd: add sanity check for first_minor"" This reverts commit 0daa75bf750c400af0a0127fae37cd959d36dee7. These problems such as: https://lore.kernel.org/all/CACPK8XfUWoOHr-0RwRoYoskia4fbAbZ7DYf5wWBnv6qUnGq18w@mail.gmail.com/ It was introduced by introduced by commit b1a811633f73 ("block: nbd: add sanity check for first_minor") and has been have been fixed by commit e4c4871a7394 ("nbd: fix max value for 'first_minor'"). Cc: Joel Stanley Cc: Christoph Hellwig Cc: Pavel Skripkin Cc: Jens Axboe Cc: Sasha Levin Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Wen Yang Signed-off-by: Greg Kroah-Hartman --- drivers/block/nbd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index b0d3dadeb964..bf8148ebd858 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1771,7 +1771,17 @@ static int nbd_dev_add(int index) refcount_set(&nbd->refs, 1); INIT_LIST_HEAD(&nbd->list); disk->major = NBD_MAJOR; + + /* Too big first_minor can cause duplicate creation of + * sysfs files/links, since first_minor will be truncated to + * byte in __device_add_disk(). + */ disk->first_minor = index << part_shift; + if (disk->first_minor > 0xff) { + err = -EINVAL; + goto out_free_idr; + } + disk->fops = &nbd_fops; disk->private_data = nbd; sprintf(disk->disk_name, "nbd%d", index); From fd8107206a672f5a529a819e8930bf81fb54ae0f Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Tue, 2 Nov 2021 09:52:34 +0800 Subject: [PATCH 0077/1017] nbd: fix max value for 'first_minor' commit e4c4871a73944353ea23e319de27ef73ce546623 upstream. commit b1a811633f73 ("block: nbd: add sanity check for first_minor") checks that 'first_minor' should not be greater than 0xff, which is wrong. Whitout the commit, the details that when user pass 0x100000, it ends up create sysfs dir "/sys/block/43:0" are as follows: nbd_dev_add disk->first_minor = index << part_shift -> default part_shift is 5, first_minor is 0x2000000 device_add_disk ddev->devt = MKDEV(disk->major, disk->first_minor) -> (0x2b << 20) | (0x2000000) = 0x2b00000 device_add device_create_sys_dev_entry format_dev_t sprintf(buffer, "%u:%u", MAJOR(dev), MINOR(dev)); -> got 43:0 sysfs_create_link -> /sys/block/43:0 By the way, with the wrong fix, when part_shift is the default value, only 8 ndb devices can be created since 8 << 5 is greater than 0xff. Since the max bits for 'first_minor' should be the same as what MKDEV() does, which is 20. Change the upper bound of 'first_minor' from 0xff to 0xfffff. Fixes: b1a811633f73 ("block: nbd: add sanity check for first_minor") Signed-off-by: Yu Kuai Reviewed-by: Josef Bacik Link: https://lore.kernel.org/r/20211102015237.2309763-2-yebin10@huawei.com Signed-off-by: Jens Axboe Signed-off-by: Wen Yang Signed-off-by: Greg Kroah-Hartman --- drivers/block/nbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index bf8148ebd858..bd05eaf04143 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1773,11 +1773,11 @@ static int nbd_dev_add(int index) disk->major = NBD_MAJOR; /* Too big first_minor can cause duplicate creation of - * sysfs files/links, since first_minor will be truncated to - * byte in __device_add_disk(). + * sysfs files/links, since MKDEV() expect that the max bits of + * first_minor is 20. */ disk->first_minor = index << part_shift; - if (disk->first_minor > 0xff) { + if (disk->first_minor > MINORMASK) { err = -EINVAL; goto out_free_idr; } From 2e0c3e43ebb99c2b495229f8fade4c043fbd06a5 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Tue, 2 Nov 2021 09:52:35 +0800 Subject: [PATCH 0078/1017] nbd: fix possible overflow for 'first_minor' in nbd_dev_add() commit 940c264984fd1457918393c49674f6b39ee16506 upstream. If 'part_shift' is not zero, then 'index << part_shift' might overflow to a value that is not greater than '0xfffff', then sysfs might complains about duplicate creation. Fixes: b0d9111a2d53 ("nbd: use an idr to keep track of nbd devices") Signed-off-by: Yu Kuai Reviewed-by: Josef Bacik Link: https://lore.kernel.org/r/20211102015237.2309763-3-yebin10@huawei.com Signed-off-by: Jens Axboe Signed-off-by: Wen Yang Signed-off-by: Greg Kroah-Hartman --- drivers/block/nbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index bd05eaf04143..1ddae8f768d5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1773,11 +1773,11 @@ static int nbd_dev_add(int index) disk->major = NBD_MAJOR; /* Too big first_minor can cause duplicate creation of - * sysfs files/links, since MKDEV() expect that the max bits of - * first_minor is 20. + * sysfs files/links, since index << part_shift might overflow, or + * MKDEV() expect that the max bits of first_minor is 20. */ disk->first_minor = index << part_shift; - if (disk->first_minor > MINORMASK) { + if (disk->first_minor < index || disk->first_minor > MINORMASK) { err = -EINVAL; goto out_free_idr; } From 4311ad1e7654f9dd569a4d1b0059f838f474e9d3 Mon Sep 17 00:00:00 2001 From: Zhang Wensheng Date: Sat, 21 May 2022 15:37:48 +0800 Subject: [PATCH 0079/1017] nbd: fix possible overflow on 'first_minor' in nbd_dev_add() commit 858f1bf65d3d9c00b5e2d8ca87dc79ed88267c98 upstream. When 'index' is a big numbers, it may become negative which forced to 'int'. then 'index << part_shift' might overflow to a positive value that is not greater than '0xfffff', then sysfs might complains about duplicate creation. Because of this, move the 'index' judgment to the front will fix it and be better. Fixes: b0d9111a2d53 ("nbd: use an idr to keep track of nbd devices") Fixes: 940c264984fd ("nbd: fix possible overflow for 'first_minor' in nbd_dev_add()") Signed-off-by: Zhang Wensheng Signed-off-by: Yu Kuai Reviewed-by: Josef Bacik Link: https://lore.kernel.org/r/20220521073749.3146892-6-yukuai3@huawei.com Signed-off-by: Jens Axboe Signed-off-by: Wen Yang Signed-off-by: Greg Kroah-Hartman --- drivers/block/nbd.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 1ddae8f768d5..dbcd903ba128 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1771,17 +1771,7 @@ static int nbd_dev_add(int index) refcount_set(&nbd->refs, 1); INIT_LIST_HEAD(&nbd->list); disk->major = NBD_MAJOR; - - /* Too big first_minor can cause duplicate creation of - * sysfs files/links, since index << part_shift might overflow, or - * MKDEV() expect that the max bits of first_minor is 20. - */ disk->first_minor = index << part_shift; - if (disk->first_minor < index || disk->first_minor > MINORMASK) { - err = -EINVAL; - goto out_free_idr; - } - disk->fops = &nbd_fops; disk->private_data = nbd; sprintf(disk->disk_name, "nbd%d", index); @@ -1875,8 +1865,19 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) if (!netlink_capable(skb, CAP_SYS_ADMIN)) return -EPERM; - if (info->attrs[NBD_ATTR_INDEX]) + if (info->attrs[NBD_ATTR_INDEX]) { index = nla_get_u32(info->attrs[NBD_ATTR_INDEX]); + + /* + * Too big first_minor can cause duplicate creation of + * sysfs files/links, since index << part_shift might overflow, or + * MKDEV() expect that the max bits of first_minor is 20. + */ + if (index < 0 || index > MINORMASK >> part_shift) { + printk(KERN_ERR "nbd: illegal input index %d\n", index); + return -EINVAL; + } + } if (!info->attrs[NBD_ATTR_SOCKETS]) { printk(KERN_ERR "nbd: must specify at least one socket\n"); return -EINVAL; From e1dc3f102a8127255975ddbdd81fa2525d861d00 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Fri, 27 Jan 2023 15:01:00 +0100 Subject: [PATCH 0080/1017] wifi: mwifiex: Add missing compatible string for SD8787 commit 36dd7a4c6226133b0b7aa92b8e604e688d958d0c upstream. Commit e3fffc1f0b47 ("devicetree: document new marvell-8xxx and pwrseq-sd8787 options") documented a compatible string for SD8787 in the devicetree bindings, but neglected to add it to the mwifiex driver. Fixes: e3fffc1f0b47 ("devicetree: document new marvell-8xxx and pwrseq-sd8787 options") Signed-off-by: Lukas Wunner Cc: stable@vger.kernel.org # v4.11+ Cc: Matt Ranostay Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/320de5005ff3b8fd76be2d2b859fd021689c3681.1674827105.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/marvell/mwifiex/sdio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index bde9e4bbfffe..7fb6eef40928 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -485,6 +485,7 @@ static struct memory_type_mapping mem_type_mapping_tbl[] = { }; static const struct of_device_id mwifiex_sdio_of_match_table[] = { + { .compatible = "marvell,sd8787" }, { .compatible = "marvell,sd8897" }, { .compatible = "marvell,sd8997" }, { } From 01e652f03a865b41cfc44e04dbdbbc1d83f15dd4 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Tue, 7 Feb 2023 10:21:47 -0500 Subject: [PATCH 0081/1017] audit: update the mailing list in MAINTAINERS commit 6c6cd913accd77008f74a1a9d57b816db3651daa upstream. We've moved the upstream Linux Kernel audit subsystem discussions to a new mailing list, this patch updates the MAINTAINERS info with the new list address. Marking this for stable inclusion to help speed uptake of the new list across all of the supported kernel releases. This is a doc only patch so the risk should be close to nil. Cc: stable@vger.kernel.org Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f6c6b403a1b7..6c5efc4013ab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3001,7 +3001,7 @@ F: drivers/net/ieee802154/atusb.h AUDIT SUBSYSTEM M: Paul Moore M: Eric Paris -L: linux-audit@redhat.com (moderated for non-subscribers) +L: audit@vger.kernel.org S: Supported W: https://github.com/linux-audit T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git From 1ba10d3640e9783dad811fe4e24d55465c37c64d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 4 Jan 2023 13:09:12 -0800 Subject: [PATCH 0082/1017] ext4: Fix function prototype mismatch for ext4_feat_ktype commit 118901ad1f25d2334255b3d50512fa20591531cd upstream. With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), indirect call targets are validated against the expected function pointer prototype to make sure the call target is valid to help mitigate ROP attacks. If they are not identical, there is a failure at run time, which manifests as either a kernel panic or thread getting killed. ext4_feat_ktype was setting the "release" handler to "kfree", which doesn't have a matching function prototype. Add a simple wrapper with the correct prototype. This was found as a result of Clang's new -Wcast-function-type-strict flag, which is more sensitive than the simpler -Wcast-function-type, which only checks for type width mismatches. Note that this code is only reached when ext4 is a loadable module and it is being unloaded: CFI failure at kobject_put+0xbb/0x1b0 (target: kfree+0x0/0x180; expected type: 0x7c4aa698) ... RIP: 0010:kobject_put+0xbb/0x1b0 ... Call Trace: ext4_exit_sysfs+0x14/0x60 [ext4] cleanup_module+0x67/0xedb [ext4] Fixes: b99fee58a20a ("ext4: create ext4_feat kobject dynamically") Cc: Theodore Ts'o Cc: Eric Biggers Cc: stable@vger.kernel.org Build-tested-by: Gustavo A. R. Silva Reviewed-by: Gustavo A. R. Silva Reviewed-by: Nathan Chancellor Link: https://lore.kernel.org/r/20230103234616.never.915-kees@kernel.org Signed-off-by: Kees Cook Reviewed-by: Eric Biggers Link: https://lore.kernel.org/r/20230104210908.gonna.388-kees@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/sysfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index f24bef3be48a..ce74cde6d8fa 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -487,6 +487,11 @@ static void ext4_sb_release(struct kobject *kobj) complete(&sbi->s_kobj_unregister); } +static void ext4_feat_release(struct kobject *kobj) +{ + kfree(kobj); +} + static const struct sysfs_ops ext4_attr_ops = { .show = ext4_attr_show, .store = ext4_attr_store, @@ -501,7 +506,7 @@ static struct kobj_type ext4_sb_ktype = { static struct kobj_type ext4_feat_ktype = { .default_groups = ext4_feat_groups, .sysfs_ops = &ext4_attr_ops, - .release = (void (*)(struct kobject *))kfree, + .release = ext4_feat_release, }; static struct kobject *ext4_root; From c44e96d6c31a0937c6b82c3dc3e6500545fb1024 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Wed, 5 Oct 2022 01:01:00 +0300 Subject: [PATCH 0083/1017] Revert "net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs" commit af7b29b1deaac6da3bb7637f0e263dfab7bfc7a3 upstream. taprio_attach() has this logic at the end, which should have been removed with the blamed patch (which is now being reverted): /* access to the child qdiscs is not needed in offload mode */ if (FULL_OFFLOAD_IS_ENABLED(q->flags)) { kfree(q->qdiscs); q->qdiscs = NULL; } because otherwise, we make use of q->qdiscs[] even after this array was deallocated, namely in taprio_leaf(). Therefore, whenever one would try to attach a valid child qdisc to a fully offloaded taprio root, one would immediately dereference a NULL pointer. $ tc qdisc replace dev eno0 handle 8001: parent root taprio \ num_tc 8 \ map 0 1 2 3 4 5 6 7 \ queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \ max-sdu 0 0 0 0 0 200 0 0 \ base-time 200 \ sched-entry S 80 20000 \ sched-entry S a0 20000 \ sched-entry S 5f 60000 \ flags 2 $ max_frame_size=1500 $ data_rate_kbps=20000 $ port_transmit_rate_kbps=1000000 $ idleslope=$data_rate_kbps $ sendslope=$(($idleslope - $port_transmit_rate_kbps)) $ locredit=$(($max_frame_size * $sendslope / $port_transmit_rate_kbps)) $ hicredit=$(($max_frame_size * $idleslope / $port_transmit_rate_kbps)) $ tc qdisc replace dev eno0 parent 8001:7 cbs \ idleslope $idleslope \ sendslope $sendslope \ hicredit $hicredit \ locredit $locredit \ offload 0 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000030 pc : taprio_leaf+0x28/0x40 lr : qdisc_leaf+0x3c/0x60 Call trace: taprio_leaf+0x28/0x40 tc_modify_qdisc+0xf0/0x72c rtnetlink_rcv_msg+0x12c/0x390 netlink_rcv_skb+0x5c/0x130 rtnetlink_rcv+0x1c/0x2c The solution is not as obvious as the problem. The code which deallocates q->qdiscs[] is in fact copied and pasted from mqprio, which also deallocates the array in mqprio_attach() and never uses it afterwards. Therefore, the identical cleanup logic of priv->qdiscs[] that mqprio_destroy() has is deceptive because it will never take place at qdisc_destroy() time, but just at raw ops->destroy() time (otherwise said, priv->qdiscs[] do not last for the entire lifetime of the mqprio root), but rather, this is just the twisted way in which the Qdisc API understands error path cleanup should be done (Qdisc_ops :: destroy() is called even when Qdisc_ops :: init() never succeeded). Side note, in fact this is also what the comment in mqprio_init() says: /* pre-allocate qdisc, attachment can't fail */ Or reworded, mqprio's priv->qdiscs[] scheme is only meant to serve as data passing between Qdisc_ops :: init() and Qdisc_ops :: attach(). [ this comment was also copied and pasted into the initial taprio commit, even though taprio_attach() came way later ] The problem is that taprio also makes extensive use of the q->qdiscs[] array in the software fast path (taprio_enqueue() and taprio_dequeue()), but it does not keep a reference of its own on q->qdiscs[i] (you'd think that since it creates these Qdiscs, it holds the reference, but nope, this is not completely true). To understand the difference between taprio_destroy() and mqprio_destroy() one must look before commit 13511704f8d7 ("net: taprio offload: enforce qdisc to netdev queue mapping"), because that just muddied the waters. In the "original" taprio design, taprio always attached itself (the root Qdisc) to all netdev TX queues, so that dev_qdisc_enqueue() would go through taprio_enqueue(). It also called qdisc_refcount_inc() on itself for as many times as there were netdev TX queues, in order to counter-balance what tc_get_qdisc() does when destroying a Qdisc (simplified for brevity below): if (n->nlmsg_type == RTM_DELQDISC) err = qdisc_graft(dev, parent=NULL, new=NULL, q, extack); qdisc_graft(where "new" is NULL so this deletes the Qdisc): for (i = 0; i < num_q; i++) { struct netdev_queue *dev_queue; dev_queue = netdev_get_tx_queue(dev, i); old = dev_graft_qdisc(dev_queue, new); if (new && i > 0) qdisc_refcount_inc(new); qdisc_put(old); ~~~~~~~~~~~~~~ this decrements taprio's refcount once for each TX queue } notify_and_destroy(net, skb, n, classid, rtnl_dereference(dev->qdisc), new); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and this finally decrements it to zero, making qdisc_put() call qdisc_destroy() The q->qdiscs[] created using qdisc_create_dflt() (or their replacements, if taprio_graft() was ever to get called) were then privately freed by taprio_destroy(). This is still what is happening after commit 13511704f8d7 ("net: taprio offload: enforce qdisc to netdev queue mapping"), but only for software mode. In full offload mode, the per-txq "qdisc_put(old)" calls from qdisc_graft() now deallocate the child Qdiscs rather than decrement taprio's refcount. So when notify_and_destroy(taprio) finally calls taprio_destroy(), the difference is that the child Qdiscs were already deallocated. And this is exactly why the taprio_attach() comment "access to the child qdiscs is not needed in offload mode" is deceptive too. Not only the q->qdiscs[] array is not needed, but it is also necessary to get rid of it as soon as possible, because otherwise, we will also call qdisc_put() on the child Qdiscs in qdisc_destroy() -> taprio_destroy(), and this will cause a nasty use-after-free/refcount-saturate/whatever. In short, the problem is that since the blamed commit, taprio_leaf() needs q->qdiscs[] to not be freed by taprio_attach(), while qdisc_destroy() -> taprio_destroy() does need q->qdiscs[] to be freed by taprio_attach() for full offload. Fixing one problem triggers the other. All of this can be solved by making taprio keep its q->qdiscs[i] with a refcount elevated at 2 (in offloaded mode where they are attached to the netdev TX queues), both in taprio_attach() and in taprio_graft(). The generic qdisc_graft() would just decrement the child qdiscs' refcounts to 1, and taprio_destroy() would give them the final coup de grace. However the rabbit hole of changes is getting quite deep, and the complexity increases. The blamed commit was supposed to be a bug fix in the first place, and the bug it addressed is not so significant so as to justify further rework in stable trees. So I'd rather just revert it. I don't know enough about multi-queue Qdisc design to make a proper judgement right now regarding what is/isn't idiomatic use of Qdisc concepts in taprio. I will try to study the problem more and come with a different solution in net-next. Fixes: 1461d212ab27 ("net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs") Reported-by: Muhammad Husaini Zulkifli Reported-by: Vinicius Costa Gomes Signed-off-by: Vladimir Oltean Reviewed-by: Vinicius Costa Gomes Link: https://lore.kernel.org/r/20221004220100.1650558-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_taprio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index e25fe44899ff..2d842f31ec5a 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1906,14 +1906,12 @@ start_error: static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl) { - struct taprio_sched *q = qdisc_priv(sch); - struct net_device *dev = qdisc_dev(sch); - unsigned int ntx = cl - 1; + struct netdev_queue *dev_queue = taprio_queue_get(sch, cl); - if (ntx >= dev->num_tx_queues) + if (!dev_queue) return NULL; - return q->qdiscs[ntx]; + return dev_queue->qdisc_sleeping; } static unsigned long taprio_find(struct Qdisc *sch, u32 classid) From 12e3119a87627741bd3871c895ce198f21529eb3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 22 Feb 2023 09:52:32 -0800 Subject: [PATCH 0084/1017] bpf: add missing header file include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f3dd0c53370e70c0f9b7e931bbec12916f3bb8cc upstream. Commit 74e19ef0ff80 ("uaccess: Add speculation barrier to copy_from_user()") built fine on x86-64 and arm64, and that's the extent of my local build testing. It turns out those got the include incidentally through other header files ( in particular), but that was not true of other architectures, resulting in build errors kernel/bpf/core.c: In function ‘___bpf_prog_run’: kernel/bpf/core.c:1913:3: error: implicit declaration of function ‘barrier_nospec’ so just make sure to explicitly include the proper header file to make everybody see it. Fixes: 74e19ef0ff80 ("uaccess: Add speculation barrier to copy_from_user()") Reported-by: kernel test robot Reported-by: Viresh Kumar Reported-by: Huacai Chen Tested-by: Geert Uytterhoeven Tested-by: Dave Hansen Acked-by: Alexei Starovoitov Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index c18aed60ce40..73d4b1e32fbd 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include From 22d269bb30db7f5a4e71a8a813a0f4df5255f7de Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 25 Feb 2023 11:55:05 +0100 Subject: [PATCH 0085/1017] Linux 5.10.170 Link: https://lore.kernel.org/r/20230223130426.817998725@linuxfoundation.org Link: https://lore.kernel.org/r/20230223141540.701637224@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Slade Watkins Tested-by: Guenter Roeck Tested-by: Sudip Mukherjee Tested-by: Linux Kernel Functional Testing Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dbbfaa5d4fe2..028fca7ec5cf 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 169 +SUBLEVEL = 170 EXTRAVERSION = NAME = Dare mighty things From bb0ae42d0bea1ce79f5499940c27ea1f7a13c7ac Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 25 Feb 2023 15:27:49 +0000 Subject: [PATCH 0086/1017] Revert "Revert "nvmem: core: Fix a conflict between MTD and NVMEM on wp-gpios property"" This reverts commit b34e092097a727ad3bb2eea81e9b6791dda61280. It needs to come back to handle the 5.10.169 merge properly, it will be reverted again afterward to resolve the abi issues. Bug: 161946584 Change-Id: I8ff6a57edb206a515edd856341e0a916cc4d9c08 Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 2 +- include/linux/nvmem-provider.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 7b281ae540ad..48fbe49e3772 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -629,7 +629,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (config->wp_gpio) nvmem->wp_gpio = config->wp_gpio; - else + else if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 06409a6c40bc..39ec67689898 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -49,7 +49,8 @@ enum nvmem_type { * @word_size: Minimum read/write access granularity. * @stride: Minimum read/write access stride. * @priv: User context passed to read/write callbacks. - * @wp-gpio: Write protect pin + * @wp-gpio: Write protect pin + * @ignore_wp: Write Protect pin is managed by the provider. * * Note: A default "nvmem" name will be assigned to the device if * no name is specified in its configuration. In such case "" is @@ -69,6 +70,7 @@ struct nvmem_config { enum nvmem_type type; bool read_only; bool root_only; + bool ignore_wp; bool no_of_node; nvmem_reg_read_t reg_read; nvmem_reg_write_t reg_write; From 887975834dea744dde636dd73bbd1e597f211d7d Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Thu, 5 Jan 2023 21:28:12 +0000 Subject: [PATCH 0087/1017] Fix XFRM-I support for nested ESP tunnels [ Upstream commit b0355dbbf13c0052931dd14c38c789efed64d3de ] This change adds support for nested IPsec tunnels by ensuring that XFRM-I verifies existing policies before decapsulating a subsequent policies. Addtionally, this clears the secpath entries after policies are verified, ensuring that previous tunnels with no-longer-valid do not pollute subsequent policy checks. This is necessary especially for nested tunnels, as the IP addresses, protocol and ports may all change, thus not matching the previous policies. In order to ensure that packets match the relevant inbound templates, the xfrm_policy_check should be done before handing off to the inner XFRM protocol to decrypt and decapsulate. Notably, raw ESP/AH packets did not perform policy checks inherently, whereas all other encapsulated packets (UDP, TCP encapsulated) do policy checks after calling xfrm_input handling in the respective encapsulation layer. Test: Verified with additional Android Kernel Unit tests Signed-off-by: Benedict Wong Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/xfrm/xfrm_interface.c | 54 ++++++++++++++++++++++++++++++++++++--- net/xfrm/xfrm_policy.c | 3 +++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index da518b4ca84c..e4f21a692415 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -207,6 +207,52 @@ static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet) skb->mark = 0; } +static int xfrmi_input(struct sk_buff *skb, int nexthdr, __be32 spi, + int encap_type, unsigned short family) +{ + struct sec_path *sp; + + sp = skb_sec_path(skb); + if (sp && (sp->len || sp->olen) && + !xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family)) + goto discard; + + XFRM_SPI_SKB_CB(skb)->family = family; + if (family == AF_INET) { + XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL; + } else { + XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); + XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL; + } + + return xfrm_input(skb, nexthdr, spi, encap_type); +discard: + kfree_skb(skb); + return 0; +} + +static int xfrmi4_rcv(struct sk_buff *skb) +{ + return xfrmi_input(skb, ip_hdr(skb)->protocol, 0, 0, AF_INET); +} + +static int xfrmi6_rcv(struct sk_buff *skb) +{ + return xfrmi_input(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], + 0, 0, AF_INET6); +} + +static int xfrmi4_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) +{ + return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET); +} + +static int xfrmi6_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) +{ + return xfrmi_input(skb, nexthdr, spi, encap_type, AF_INET6); +} + static int xfrmi_rcv_cb(struct sk_buff *skb, int err) { const struct xfrm_mode *inner_mode; @@ -780,8 +826,8 @@ static struct pernet_operations xfrmi_net_ops = { }; static struct xfrm6_protocol xfrmi_esp6_protocol __read_mostly = { - .handler = xfrm6_rcv, - .input_handler = xfrm_input, + .handler = xfrmi6_rcv, + .input_handler = xfrmi6_input, .cb_handler = xfrmi_rcv_cb, .err_handler = xfrmi6_err, .priority = 10, @@ -831,8 +877,8 @@ static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = { #endif static struct xfrm4_protocol xfrmi_esp4_protocol __read_mostly = { - .handler = xfrm4_rcv, - .input_handler = xfrm_input, + .handler = xfrmi4_rcv, + .input_handler = xfrmi4_input, .cb_handler = xfrmi_rcv_cb, .err_handler = xfrmi4_err, .priority = 10, diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 0d12bdf59d4c..d15aa62887de 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -3710,6 +3710,9 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, goto reject; } + if (if_id) + secpath_reset(skb); + xfrm_pols_put(pols, npols); return 1; } From 1f3a209b2f4ec238d4b0c77b558527e7dab52aab Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 25 Nov 2022 15:41:34 +0100 Subject: [PATCH 0088/1017] arm64: dts: rockchip: drop unused LED mode property from rk3328-roc-cc [ Upstream commit 1692bffec674551163a7a4be32f59fdde04ecd27 ] GPIO LEDs do not have a 'mode' property: rockchip/rk3328-roc-pc.dtb: leds: led-0: Unevaluated properties are not allowed ('mode' was unexpected) Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221125144135.477144-1-krzysztof.kozlowski@linaro.org Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts index daa9a0c601a9..22ab5e1d7319 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts @@ -91,7 +91,6 @@ linux,default-trigger = "heartbeat"; gpios = <&rk805 1 GPIO_ACTIVE_LOW>; default-state = "on"; - mode = <0x23>; }; user_led: led-1 { @@ -99,7 +98,6 @@ linux,default-trigger = "mmc1"; gpios = <&rk805 0 GPIO_ACTIVE_LOW>; default-state = "off"; - mode = <0x05>; }; }; }; From abbf52efadebc1aba898d4493ffed22de5dc29f6 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Wed, 28 Dec 2022 21:17:32 +0100 Subject: [PATCH 0089/1017] ARM: dts: rockchip: add power-domains property to dp node on rk3288 [ Upstream commit 80422339a75088322b4d3884bd12fa0fe5d11050 ] The clocks in the Rockchip rk3288 DisplayPort node are included in the power-domain@RK3288_PD_VIO logic, but the power-domains property in the dp node is missing, so fix it. Signed-off-by: Johan Jonker Link: https://lore.kernel.org/r/dab85bfb-9f55-86a1-5cd5-7388c43e0ec5@gmail.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm/boot/dts/rk3288.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 9051fb4a267d..aab28161b9ae 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -1203,6 +1203,7 @@ clock-names = "dp", "pclk"; phys = <&edp_phy>; phy-names = "dp"; + power-domains = <&power RK3288_PD_VIO>; resets = <&cru SRST_EDP>; reset-names = "dp"; rockchip,grf = <&grf>; From 8e833fe47f45c4e43f40f8bb6cf7088879dd3139 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Wed, 25 Jan 2023 11:34:18 -0700 Subject: [PATCH 0090/1017] ACPI: NFIT: fix a potential deadlock during NFIT teardown [ Upstream commit fb6df4366f86dd252bfa3049edffa52d17e7b895 ] Lockdep reports that acpi_nfit_shutdown() may deadlock against an opportune acpi_nfit_scrub(). acpi_nfit_scrub () is run from inside a 'work' and therefore has already acquired workqueue-internal locks. It also acquiires acpi_desc->init_mutex. acpi_nfit_shutdown() first acquires init_mutex, and was subsequently attempting to cancel any pending workqueue items. This reversed locking order causes a potential deadlock: ====================================================== WARNING: possible circular locking dependency detected 6.2.0-rc3 #116 Tainted: G O N ------------------------------------------------------ libndctl/1958 is trying to acquire lock: ffff888129b461c0 ((work_completion)(&(&acpi_desc->dwork)->work)){+.+.}-{0:0}, at: __flush_work+0x43/0x450 but task is already holding lock: ffff888129b460e8 (&acpi_desc->init_mutex){+.+.}-{3:3}, at: acpi_nfit_shutdown+0x87/0xd0 [nfit] which lock already depends on the new lock. ... Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&acpi_desc->init_mutex); lock((work_completion)(&(&acpi_desc->dwork)->work)); lock(&acpi_desc->init_mutex); lock((work_completion)(&(&acpi_desc->dwork)->work)); *** DEADLOCK *** Since the workqueue manipulation is protected by its own internal locking, the cancellation of pending work doesn't need to be done under acpi_desc->init_mutex. Move cancel_delayed_work_sync() outside the init_mutex to fix the deadlock. Any work that starts after acpi_nfit_shutdown() drops the lock will see ARS_CANCEL, and the cancel_delayed_work_sync() will safely flush it out. Reported-by: Dan Williams Signed-off-by: Vishal Verma Link: https://lore.kernel.org/r/20230112-acpi_nfit_lockdep-v1-1-660be4dd10be@intel.com Signed-off-by: Dan Williams Signed-off-by: Sasha Levin --- drivers/acpi/nfit/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 99e23a5df026..2306abb09f7f 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -3687,8 +3687,8 @@ void acpi_nfit_shutdown(void *data) mutex_lock(&acpi_desc->init_mutex); set_bit(ARS_CANCEL, &acpi_desc->scrub_flags); - cancel_delayed_work_sync(&acpi_desc->dwork); mutex_unlock(&acpi_desc->init_mutex); + cancel_delayed_work_sync(&acpi_desc->dwork); /* * Bounce the nvdimm bus lock to make sure any in-flight From 6195cea4c738146f6665f71944325766daef1a5f Mon Sep 17 00:00:00 2001 From: David Sterba Date: Tue, 24 Jan 2023 20:32:10 +0100 Subject: [PATCH 0091/1017] btrfs: send: limit number of clones and allocated memory size [ Upstream commit 33e17b3f5ab74af12aca58c515bc8424ff69a343 ] The arg->clone_sources_count is u64 and can trigger a warning when a huge value is passed from user space and a huge array is allocated. Limit the allocated memory to 8MiB (can be increased if needed), which in turn limits the number of clone sources to 8M / sizeof(struct clone_root) = 8M / 40 = 209715. Real world number of clones is from tens to hundreds, so this is future proof. Reported-by: syzbot+4376a9a073770c173269@syzkaller.appspotmail.com Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/send.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 4a6ba0997e39..b081b61e97c8 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -7276,10 +7276,10 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg) /* * Check that we don't overflow at later allocations, we request * clone_sources_count + 1 items, and compare to unsigned long inside - * access_ok. + * access_ok. Also set an upper limit for allocation size so this can't + * easily exhaust memory. Max number of clone sources is about 200K. */ - if (arg->clone_sources_count > - ULONG_MAX / sizeof(struct clone_root) - 1) { + if (arg->clone_sources_count > SZ_8M / sizeof(struct clone_root)) { ret = -EINVAL; goto out; } From 065f6a66339226fe33d18998afa8533076751444 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 14:04:08 -0500 Subject: [PATCH 0092/1017] IB/hfi1: Assign npages earlier [ Upstream commit f9c47b2caa7ffc903ec950b454b59c209afe3182 ] Improve code clarity and enable earlier use of tidbuf->npages by moving its assignment to structure creation time. Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167329104884.1472990.4639750192433251493.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index 897923981855..0e0be6c62e3d 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -202,16 +202,11 @@ static void unpin_rcv_pages(struct hfi1_filedata *fd, static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf) { int pinned; - unsigned int npages; + unsigned int npages = tidbuf->npages; unsigned long vaddr = tidbuf->vaddr; struct page **pages = NULL; struct hfi1_devdata *dd = fd->uctxt->dd; - /* Get the number of pages the user buffer spans */ - npages = num_user_pages(vaddr, tidbuf->length); - if (!npages) - return -EINVAL; - if (npages > fd->uctxt->expected_count) { dd_dev_err(dd, "Expected buffer too big\n"); return -EINVAL; @@ -238,7 +233,6 @@ static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf) return pinned; } tidbuf->pages = pages; - tidbuf->npages = npages; fd->tid_n_pinned += pinned; return pinned; } @@ -316,6 +310,7 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, mutex_init(&tidbuf->cover_mutex); tidbuf->vaddr = tinfo->vaddr; tidbuf->length = tinfo->length; + tidbuf->npages = num_user_pages(tidbuf->vaddr, tidbuf->length); tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets), GFP_KERNEL); if (!tidbuf->psets) { From 2fd5059f4fdf4df813414fe85f732187554528a3 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Thu, 2 Feb 2023 17:25:51 +0200 Subject: [PATCH 0093/1017] neigh: make sure used and confirmed times are valid [ Upstream commit c1d2ecdf5e38e3489ce8328238b558b3b2866fe1 ] Entries can linger in cache without timer for days, thanks to the gc_thresh1 limit. As result, without traffic, the confirmed time can be outdated and to appear to be in the future. Later, on traffic, NUD_STALE entries can switch to NUD_DELAY and start the timer which can see the invalid confirmed time and wrongly switch to NUD_REACHABLE state instead of NUD_PROBE. As result, timer is set many days in the future. This is more visible on 32-bit platforms, with higher HZ value. Why this is a problem? While we expect unused entries to expire, such entries stay in REACHABLE state for too long, locked in cache. They are not expired normally, only when cache is full. Problem and the wrong state change reported by Zhang Changzhong: 172.16.1.18 dev bond0 lladdr 0a:0e:0f:01:12:01 ref 1 used 350521/15994171/350520 probes 4 REACHABLE 350520 seconds have elapsed since this entry was last updated, but it is still in the REACHABLE state (base_reachable_time_ms is 30000), preventing lladdr from being updated through probe. Fix it by ensuring timer is started with valid used/confirmed times. Considering the valid time range is LONG_MAX jiffies, we try not to go too much in the past while we are in DELAY/PROBE state. There are also places that need used/updated times to be validated while timer is not running. Reported-by: Zhang Changzhong Signed-off-by: Julian Anastasov Tested-by: Zhang Changzhong Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/core/neighbour.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index f6f580e9d282..82ccc3eebe71 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -242,7 +242,7 @@ static int neigh_forced_gc(struct neigh_table *tbl) (n->nud_state == NUD_NOARP) || (tbl->is_multicast && tbl->is_multicast(n->primary_key)) || - time_after(tref, n->updated)) + !time_in_range(n->updated, tref, jiffies)) remove = true; write_unlock(&n->lock); @@ -262,7 +262,17 @@ static int neigh_forced_gc(struct neigh_table *tbl) static void neigh_add_timer(struct neighbour *n, unsigned long when) { + /* Use safe distance from the jiffies - LONG_MAX point while timer + * is running in DELAY/PROBE state but still show to user space + * large times in the past. + */ + unsigned long mint = jiffies - (LONG_MAX - 86400 * HZ); + neigh_hold(n); + if (!time_in_range(n->confirmed, mint, jiffies)) + n->confirmed = mint; + if (time_before(n->used, n->confirmed)) + n->used = n->confirmed; if (unlikely(mod_timer(&n->timer, when))) { printk("NEIGH: BUG, double timer add, state is %x\n", n->nud_state); @@ -948,12 +958,14 @@ static void neigh_periodic_work(struct work_struct *work) goto next_elt; } - if (time_before(n->used, n->confirmed)) + if (time_before(n->used, n->confirmed) && + time_is_before_eq_jiffies(n->confirmed)) n->used = n->confirmed; if (refcount_read(&n->refcnt) == 1 && (state == NUD_FAILED || - time_after(jiffies, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { + !time_in_range_open(jiffies, n->used, + n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { *np = n->next; neigh_mark_dead(n); write_unlock(&n->lock); From 75fbe1e43505f3474d6f590314671e0e53a2afa7 Mon Sep 17 00:00:00 2001 From: Xin Zhao Date: Mon, 30 Jan 2023 21:29:47 +0000 Subject: [PATCH 0094/1017] HID: core: Fix deadloop in hid_apply_multiplier. [ Upstream commit ea427a222d8bdf2bc1a8a6da3ebe247f7dced70c ] The initial value of hid->collection[].parent_idx if 0. When Report descriptor doesn't contain "HID Collection", the value remains as 0. In the meanwhile, when the Report descriptor fullfill all following conditions, it will trigger hid_apply_multiplier function call. 1. Usage page is Generic Desktop Ctrls (0x01) 2. Usage is RESOLUTION_MULTIPLIER (0x48) 3. Contain any FEATURE items The while loop in hid_apply_multiplier will search the top-most collection by searching parent_idx == -1. Because all parent_idx is 0. The loop will run forever. There is a Report Descriptor triggerring the deadloop 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) 0x09, 0x48, // Usage (0x48) 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0xB1, 0x01, // Feature Signed-off-by: Xin Zhao Link: https://lore.kernel.org/r/20230130212947.1315941-1-xnzhao@google.com Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index baadead947c8..5f9ec1d1464a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1197,6 +1197,7 @@ int hid_open_report(struct hid_device *device) __u8 *end; __u8 *next; int ret; + int i; static int (*dispatch_type[])(struct hid_parser *parser, struct hid_item *item) = { hid_parser_main, @@ -1247,6 +1248,8 @@ int hid_open_report(struct hid_device *device) goto err; } device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) + device->collection[i].parent_idx = -1; ret = -EINVAL; while ((next = fetch_item(start, end, &item)) != NULL) { From a2957adbf3f5450f7425c545863da4a3287e06a1 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Thu, 16 Feb 2023 16:41:48 -0800 Subject: [PATCH 0095/1017] bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state commit 1fe4850b34ab512ff911e2c035c75fb6438f7307 upstream. The bpf_fib_lookup() helper does not only look up the fib (ie. route) but it also looks up the neigh. Before returning the neigh, the helper does not check for NUD_VALID. When a neigh state (neigh->nud_state) is in NUD_FAILED, its dmac (neigh->ha) could be all zeros. The helper still returns SUCCESS instead of NO_NEIGH in this case. Because of the SUCCESS return value, the bpf prog directly uses the returned dmac and ends up filling all zero in the eth header. This patch checks for NUD_VALID and returns NO_NEIGH if the neigh is not valid. Signed-off-by: Martin KaFai Lau Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20230217004150.2980689-3-martin.lau@linux.dev Signed-off-by: Greg Kroah-Hartman --- net/core/filter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index a5df0cf46bbf..b9c954182b37 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5401,7 +5401,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params, neigh = __ipv6_neigh_lookup_noref_stub(dev, dst); } - if (!neigh) + if (!neigh || !(neigh->nud_state & NUD_VALID)) return BPF_FIB_LKUP_RET_NO_NEIGH; return bpf_fib_set_fwd_params(params, neigh, dev); @@ -5514,7 +5514,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, * not needed here. */ neigh = __ipv6_neigh_lookup_noref_stub(dev, dst); - if (!neigh) + if (!neigh || !(neigh->nud_state & NUD_VALID)) return BPF_FIB_LKUP_RET_NO_NEIGH; return bpf_fib_set_fwd_params(params, neigh, dev); From 3e4bbd1f38a8d35bd2d3aaffdb5f6ada546b669a Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Thu, 9 Feb 2023 16:22:02 -0800 Subject: [PATCH 0096/1017] net: Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues(). commit 62ec33b44e0f7168ff2886520fec6fb62d03b5a3 upstream. Christoph Paasch reported that commit b5fc29233d28 ("inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy().") started triggering WARN_ON_ONCE(sk->sk_forward_alloc) in sk_stream_kill_queues(). [0 - 2] Also, we can reproduce it by a program in [3]. In the commit, we delay freeing ipv6_pinfo.pktoptions from sk->destroy() to sk->sk_destruct(), so sk->sk_forward_alloc is no longer zero in inet_csk_destroy_sock(). The same check has been in inet_sock_destruct() from at least v2.6, we can just remove the WARN_ON_ONCE(). However, among the users of sk_stream_kill_queues(), only CAIF is not calling inet_sock_destruct(). Thus, we add the same WARN_ON_ONCE() to caif_sock_destructor(). [0]: https://lore.kernel.org/netdev/39725AB4-88F1-41B3-B07F-949C5CAEFF4F@icloud.com/ [1]: https://github.com/multipath-tcp/mptcp_net-next/issues/341 [2]: WARNING: CPU: 0 PID: 3232 at net/core/stream.c:212 sk_stream_kill_queues+0x2f9/0x3e0 Modules linked in: CPU: 0 PID: 3232 Comm: syz-executor.0 Not tainted 6.2.0-rc5ab24eb4698afbe147b424149c529e2a43ec24eb5 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:sk_stream_kill_queues+0x2f9/0x3e0 Code: 03 0f b6 04 02 84 c0 74 08 3c 03 0f 8e ec 00 00 00 8b ab 08 01 00 00 e9 60 ff ff ff e8 d0 5f b6 fe 0f 0b eb 97 e8 c7 5f b6 fe <0f> 0b eb a0 e8 be 5f b6 fe 0f 0b e9 6a fe ff ff e8 02 07 e3 fe e9 RSP: 0018:ffff88810570fc68 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: ffff888101f38f40 RSI: ffffffff8285e529 RDI: 0000000000000005 RBP: 0000000000000ce0 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000ce0 R11: 0000000000000001 R12: ffff8881009e9488 R13: ffffffff84af2cc0 R14: 0000000000000000 R15: ffff8881009e9458 FS: 00007f7fdfbd5800(0000) GS:ffff88811b600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b32923000 CR3: 00000001062fc006 CR4: 0000000000170ef0 Call Trace: inet_csk_destroy_sock+0x1a1/0x320 __tcp_close+0xab6/0xe90 tcp_close+0x30/0xc0 inet_release+0xe9/0x1f0 inet6_release+0x4c/0x70 __sock_release+0xd2/0x280 sock_close+0x15/0x20 __fput+0x252/0xa20 task_work_run+0x169/0x250 exit_to_user_mode_prepare+0x113/0x120 syscall_exit_to_user_mode+0x1d/0x40 do_syscall_64+0x48/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7f7fdf7ae28d Code: c1 20 00 00 75 10 b8 03 00 00 00 0f 05 48 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 ee fb ff ff 48 89 04 24 b8 03 00 00 00 0f 05 <48> 8b 3c 24 48 89 c2 e8 37 fc ff ff 48 89 d0 48 83 c4 08 48 3d 01 RSP: 002b:00000000007dfbb0 EFLAGS: 00000293 ORIG_RAX: 0000000000000003 RAX: 0000000000000000 RBX: 0000000000000004 RCX: 00007f7fdf7ae28d RDX: 0000000000000000 RSI: ffffffffffffffff RDI: 0000000000000003 RBP: 0000000000000000 R08: 000000007f338e0f R09: 0000000000000e0f R10: 000000007f338e13 R11: 0000000000000293 R12: 00007f7fdefff000 R13: 00007f7fdefffcd8 R14: 00007f7fdefffce0 R15: 00007f7fdefffcd8 [3]: https://lore.kernel.org/netdev/20230208004245.83497-1-kuniyu@amazon.com/ Fixes: b5fc29233d28 ("inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy().") Reported-by: syzbot Reported-by: Christoph Paasch Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/caif/caif_socket.c | 1 + net/core/stream.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 9d26c5e9da05..d35ea927ca8a 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -1020,6 +1020,7 @@ static void caif_sock_destructor(struct sock *sk) return; } sk_stream_kill_queues(&cf_sk->sk); + WARN_ON(sk->sk_forward_alloc); caif_free_client(&cf_sk->layer); } diff --git a/net/core/stream.c b/net/core/stream.c index d7c5413d16d5..cd60746877b1 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -209,7 +209,6 @@ void sk_stream_kill_queues(struct sock *sk) sk_mem_reclaim(sk); WARN_ON(sk->sk_wmem_queued); - WARN_ON(sk->sk_forward_alloc); /* It is _impossible_ for the backlog to contain anything * when we get here. All user references to this socket From 80653a6e6e287eb982be9aa9f60f94382b6767b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Mon, 20 Feb 2023 06:46:12 +0000 Subject: [PATCH 0097/1017] vc_screen: don't clobber return value in vcs_read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ae3419fbac845b4d3f3a9fae4cc80c68d82cdf6e upstream. Commit 226fae124b2d ("vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF") moved the call to vcs_vc() into the loop. While doing this it also moved the unconditional assignment of ret = -ENXIO; This unconditional assignment was valid outside the loop but within it it clobbers the actual value of ret. To avoid this only assign "ret = -ENXIO" when actually needed. [ Also, the 'goto unlock_out" needs to be just a "break", so that it does the right thing when it exits on later iterations when partial success has happened - Linus ] Reported-by: Storm Dragon Link: https://lore.kernel.org/lkml/Y%2FKS6vdql2pIsCiI@hotmail.com/ Fixes: 226fae124b2d ("vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF") Signed-off-by: Thomas Weißschuh Link: https://lore.kernel.org/lkml/64981d94-d00c-4b31-9063-43ad0a384bde@t-8ch.de/ Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index f566eb1839dc..71e091f879f0 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -403,10 +403,11 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) unsigned int this_round, skip = 0; int size; - ret = -ENXIO; vc = vcs_vc(inode, &viewed); - if (!vc) - goto unlock_out; + if (!vc) { + ret = -ENXIO; + break; + } /* Check whether we are above size each round, * as copy_to_user at the end of this loop From 1c44109c30946e4e8dfad785bb006fafad9b3caf Mon Sep 17 00:00:00 2001 From: David Sloan Date: Thu, 11 Aug 2022 11:14:13 -0600 Subject: [PATCH 0098/1017] md: Flush workqueue md_rdev_misc_wq in md_alloc() commit 5e8daf906f890560df430d30617c692a794acb73 upstream. A race condition still exists when removing and re-creating md devices in test cases. However, it is only seen on some setups. The race condition was tracked down to a reference still being held to the kobject by the rdev in the md_rdev_misc_wq which will be released in rdev_delayed_delete(). md_alloc() waits for previous deletions by waiting on the md_misc_wq, but the md_rdev_misc_wq may still be holding a reference to a recently removed device. To fix this, also flush the md_rdev_misc_wq in md_alloc(). Signed-off-by: David Sloan [logang@deltatee.com: rewrote commit message] Signed-off-by: Logan Gunthorpe Signed-off-by: Song Liu Signed-off-by: Hou Tao Signed-off-by: Greg Kroah-Hartman --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index 3038e7ecb7e1..c0b34637bd66 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5683,6 +5683,7 @@ static int md_alloc(dev_t dev, char *name) * completely removed (mddev_delayed_delete). */ flush_workqueue(md_misc_wq); + flush_workqueue(md_rdev_misc_wq); mutex_lock(&disks_mutex); error = -EEXIST; From 65c07e15f2ce7f9e2cf68ea02bd2631cca53594e Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 17 May 2022 02:46:46 +0300 Subject: [PATCH 0099/1017] scripts/tags.sh: Invoke 'realpath' via 'xargs' commit 7394d2ebb651a9f62e08c6ab864aac015d27c64d upstream. When COMPILED_SOURCE is set, running make ARCH=x86_64 COMPILED_SOURCE=1 cscope tags could throw the following errors: scripts/tags.sh: line 98: /usr/bin/realpath: Argument list too long cscope: no source files found scripts/tags.sh: line 98: /usr/bin/realpath: Argument list too long ctags: No files specified. Try "ctags --help". This is most likely to happen when the kernel is configured to build a large number of modules, which has the consequence of passing too many arguments when calling 'realpath' in 'all_compiled_sources()'. Let's improve this by invoking 'realpath' through 'xargs', which takes care of properly limiting the argument list. Signed-off-by: Cristian Ciocaltea Link: https://lore.kernel.org/r/20220516234646.531208-1-cristian.ciocaltea@collabora.com Cc: Carlos Llamas Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index fd96734deff1..c15f3b4ea2a4 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -95,10 +95,13 @@ all_sources() all_compiled_sources() { - realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) \ - include/generated/autoconf.h $(find $ignore -name "*.cmd" -exec \ - grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | - awk '!a[$0]++') | sort -u + { + echo include/generated/autoconf.h + find $ignore -name "*.cmd" -exec \ + grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | + awk '!a[$0]++' + } | xargs realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) | + sort -u } all_target_sources() From a401ef0557da5b7f5b9c4baf0d861b33883d9228 Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Wed, 15 Feb 2023 18:38:50 +0000 Subject: [PATCH 0100/1017] scripts/tags.sh: fix incompatibility with PCRE2 commit 6ec363fc6142226b9ab5a6528f65333d729d2b6b upstream. Starting with release 10.38 PCRE2 drops default support for using \K in lookaround patterns as described in [1]. Unfortunately, scripts/tags.sh relies on such functionality to collect all_compiled_soures() leading to the following error: $ make COMPILED_SOURCE=1 tags GEN tags grep: \K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) The usage of \K for this pattern was introduced in commit 4f491bb6ea2a ("scripts/tags.sh: collect compiled source precisely") which speeds up the generation of tags significantly. In order to fix this issue without compromising the performance we can switch over to an equivalent sed expression. The same matching pattern is preserved here except \K is replaced with a backreference \1. [1] https://www.pcre.org/current/doc/html/pcre2syntax.html#SEC11 Cc: Greg Kroah-Hartman Cc: Cristian Ciocaltea Cc: Masahiro Yamada Cc: Jialu Xu Cc: Vipin Sharma Cc: stable@vger.kernel.org Fixes: 4f491bb6ea2a ("scripts/tags.sh: collect compiled source precisely") Signed-off-by: Carlos Llamas Link: https://lore.kernel.org/r/20230215183850.3353198-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index c15f3b4ea2a4..b82aebb0c995 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -98,7 +98,7 @@ all_compiled_sources() { echo include/generated/autoconf.h find $ignore -name "*.cmd" -exec \ - grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ | + sed -n -E 's/^source_.* (.*)/\1/p; s/^ (\S.*) \\/\1/p' {} \+ | awk '!a[$0]++' } | xargs realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) | sort -u From 0a4181b23acf53e9c95b351df6a7891116b98f9b Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 2 Jun 2022 14:42:22 +0400 Subject: [PATCH 0101/1017] drm/virtio: Fix NULL vs IS_ERR checking in virtio_gpu_object_shmem_init commit c24968734abfed81c8f93dc5f44a7b7a9aecadfa upstream. Since drm_prime_pages_to_sg() function return error pointers. The drm_gem_shmem_get_sg_table() function returns error pointers too. Using IS_ERR() to check the return value to fix this. Fixes: 2f2aa13724d5 ("drm/virtio: move virtio_gpu_mem_entry initialization to new function") Signed-off-by: Miaoqian Lin Link: http://patchwork.freedesktop.org/patch/msgid/20220602104223.54527-1-linmq006@gmail.com Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ovidiu Panait --- drivers/gpu/drm/virtio/virtgpu_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 0c98978e2e55..d4fab3361d2c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -157,9 +157,9 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, * since virtio_gpu doesn't support dma-buf import from other devices. */ shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base); - if (!shmem->pages) { + if (IS_ERR(shmem->pages)) { drm_gem_shmem_unpin(&bo->base.base); - return -EINVAL; + return PTR_ERR(shmem->pages); } if (use_dma_api) { From 87c647def389354c95263d6635c62ca0de7d12ca Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 30 Jun 2022 23:07:18 +0300 Subject: [PATCH 0102/1017] drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling commit 64b88afbd92fbf434759d1896a7cf705e1c00e79 upstream. Previous commit fixed checking of the ERR_PTR value returned by drm_gem_shmem_get_sg_table(), but it missed to zero out the shmem->pages, which will crash virtio_gpu_cleanup_object(). Add the missing zeroing of the shmem->pages. Fixes: c24968734abf ("drm/virtio: Fix NULL vs IS_ERR checking in virtio_gpu_object_shmem_init") Reviewed-by: Emil Velikov Signed-off-by: Dmitry Osipenko Link: http://patchwork.freedesktop.org/patch/msgid/20220630200726.1884320-2-dmitry.osipenko@collabora.com Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ovidiu Panait --- drivers/gpu/drm/virtio/virtgpu_object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index d4fab3361d2c..168148686001 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -159,6 +159,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base); if (IS_ERR(shmem->pages)) { drm_gem_shmem_unpin(&bo->base.base); + shmem->pages = NULL; return PTR_ERR(shmem->pages); } From cebcd4300af9074e0e831090ca6c1b3154ef942a Mon Sep 17 00:00:00 2001 From: Florian Zumbiehl Date: Mon, 6 Feb 2023 02:04:28 +0100 Subject: [PATCH 0103/1017] USB: serial: option: add support for VW/Skoda "Carstick LTE" commit 617c331d91077f896111044628c096802551dc66 upstream. Add support for VW/Skoda "Carstick LTE" D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1c9e ProdID=7605 Rev=02.00 S: Manufacturer=USB Modem S: Product=USB Modem C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#=0x1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) The stick has AT command interfaces on interfaces 1, 2, and 3, and does PPP on interface 3. Signed-off-by: Florian Zumbiehl Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2fc65cbbfea9..14a7af7f3bcd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -402,6 +402,8 @@ static void option_instat_callback(struct urb *urb); #define LONGCHEER_VENDOR_ID 0x1c9e /* 4G Systems products */ +/* This one was sold as the VW and Skoda "Carstick LTE" */ +#define FOUR_G_SYSTEMS_PRODUCT_CARSTICK_LTE 0x7605 /* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick * * It seems to contain a Qualcomm QSC6240/6290 chipset */ #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 @@ -1976,6 +1978,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(2) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_CARSTICK_LTE), + .driver_info = RSVD(0) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), .driver_info = NCTRL(0) | NCTRL(1) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100), From c5360eec648bd506afa304ae4a71f82e13d41897 Mon Sep 17 00:00:00 2001 From: Prashanth K Date: Mon, 13 Feb 2023 23:00:38 +0530 Subject: [PATCH 0104/1017] usb: gadget: u_serial: Add null pointer check in gserial_resume commit 5ec63fdbca604568890c577753c6f66c5b3ef0b5 upstream. Consider a case where gserial_disconnect has already cleared gser->ioport. And if a wakeup interrupt triggers afterwards, gserial_resume gets called, which will lead to accessing of gser->ioport and thus causing null pointer dereference.Add a null pointer check to prevent this. Added a static spinlock to prevent gser->ioport from becoming null after the newly added check. Fixes: aba3a8d01d62 ("usb: gadget: u_serial: add suspend resume callbacks") Cc: stable Signed-off-by: Prashanth K Acked-by: Alan Stern Link: https://lore.kernel.org/r/1676309438-14922-1-git-send-email-quic_prashk@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/u_serial.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 2caccbb6e014..7b54e814aefb 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -81,6 +81,9 @@ #define WRITE_BUF_SIZE 8192 /* TX only */ #define GS_CONSOLE_BUF_SIZE 8192 +/* Prevents race conditions while accessing gser->ioport */ +static DEFINE_SPINLOCK(serial_port_lock); + /* console info */ struct gs_console { struct console console; @@ -1376,8 +1379,10 @@ void gserial_disconnect(struct gserial *gser) if (!port) return; + spin_lock_irqsave(&serial_port_lock, flags); + /* tell the TTY glue not to do I/O here any more */ - spin_lock_irqsave(&port->port_lock, flags); + spin_lock(&port->port_lock); gs_console_disconnect(port); @@ -1392,7 +1397,8 @@ void gserial_disconnect(struct gserial *gser) tty_hangup(port->port.tty); } port->suspended = false; - spin_unlock_irqrestore(&port->port_lock, flags); + spin_unlock(&port->port_lock); + spin_unlock_irqrestore(&serial_port_lock, flags); /* disable endpoints, aborting down any active I/O */ usb_ep_disable(gser->out); @@ -1426,10 +1432,19 @@ EXPORT_SYMBOL_GPL(gserial_suspend); void gserial_resume(struct gserial *gser) { - struct gs_port *port = gser->ioport; + struct gs_port *port; unsigned long flags; - spin_lock_irqsave(&port->port_lock, flags); + spin_lock_irqsave(&serial_port_lock, flags); + port = gser->ioport; + + if (!port) { + spin_unlock_irqrestore(&serial_port_lock, flags); + return; + } + + spin_lock(&port->port_lock); + spin_unlock(&serial_port_lock); port->suspended = false; if (!port->start_delayed) { spin_unlock_irqrestore(&port->port_lock, flags); From 218925bfd5d1436e337c4f961e9c149fbe32de6d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 31 Jan 2023 15:49:04 -0500 Subject: [PATCH 0105/1017] USB: core: Don't hold device lock while reading the "descriptors" sysfs file commit 45bf39f8df7f05efb83b302c65ae3b9bc92b7065 upstream. Ever since commit 83e83ecb79a8 ("usb: core: get config and string descriptors for unauthorized devices") was merged in 2013, there has been no mechanism for reallocating the rawdescriptors buffers in struct usb_device after the initial enumeration. Before that commit, the buffers would be deallocated when a device was deauthorized and reallocated when it was authorized and enumerated. This means that the locking in the read_descriptors() routine is not needed, since the buffers it reads will never be reallocated while the routine is running. This locking can interfere with user programs trying to read a hub's descriptors via sysfs while new child devices of the hub are being initialized, since the hub is locked during this procedure. Since the locking in read_descriptors() hasn't been needed for over nine years, we can remove it. Reported-and-tested-by: Troels Liebe Bentsen Signed-off-by: Alan Stern CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/Y9l+wDTRbuZABzsE@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 5 ++--- drivers/usb/core/sysfs.c | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5925b8eb9ee3..7af2def631a2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2380,9 +2380,8 @@ static int usb_enumerate_device_otg(struct usb_device *udev) * usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal) * @udev: newly addressed device (in ADDRESS state) * - * This is only called by usb_new_device() and usb_authorize_device() - * and FIXME -- all comments that apply to them apply here wrt to - * environment. + * This is only called by usb_new_device() -- all comments that apply there + * apply here wrt to environment. * * If the device is WUSB and not authorized, we don't attempt to read * the string descriptors, as they will be errored out by the device diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 8d134193fa0c..a2ca38e25e0c 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -889,11 +889,7 @@ read_descriptors(struct file *filp, struct kobject *kobj, size_t srclen, n; int cfgno; void *src; - int retval; - retval = usb_lock_device_interruptible(udev); - if (retval < 0) - return -EINTR; /* The binary attribute begins with the device descriptor. * Following that are the raw descriptor entries for all the * configurations (config plus subsidiary descriptors). @@ -918,7 +914,6 @@ read_descriptors(struct file *filp, struct kobject *kobj, off -= srclen; } } - usb_unlock_device(udev); return count - nleft; } From 08681391b84da27133deefaaddefd0acfa90c2be Mon Sep 17 00:00:00 2001 From: Bing-Jhong Billy Jheng Date: Thu, 2 Mar 2023 21:00:06 +0800 Subject: [PATCH 0106/1017] io_uring: add missing lock in io_get_file_fixed io_get_file_fixed will access io_uring's context. Lock it if it is invoked unlocked (eg via io-wq) to avoid a race condition with fixed files getting unregistered. No single upstream patch exists for this issue, it was fixed as part of the file assignment changes that went into the 5.18 cycle. Signed-off-by: Jheng, Bing-Jhong Billy Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 642e1a0560c6..0c27b81ee1eb 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1092,7 +1092,8 @@ static int __io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type, unsigned nr_args); static void io_clean_op(struct io_kiocb *req); static struct file *io_file_get(struct io_ring_ctx *ctx, - struct io_kiocb *req, int fd, bool fixed); + struct io_kiocb *req, int fd, bool fixed, + unsigned int issue_flags); static void __io_queue_sqe(struct io_kiocb *req); static void io_rsrc_put_work(struct work_struct *work); @@ -3975,7 +3976,7 @@ static int io_tee(struct io_kiocb *req, unsigned int issue_flags) return -EAGAIN; in = io_file_get(req->ctx, req, sp->splice_fd_in, - (sp->flags & SPLICE_F_FD_IN_FIXED)); + (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags); if (!in) { ret = -EBADF; goto done; @@ -4015,7 +4016,7 @@ static int io_splice(struct io_kiocb *req, unsigned int issue_flags) return -EAGAIN; in = io_file_get(req->ctx, req, sp->splice_fd_in, - (sp->flags & SPLICE_F_FD_IN_FIXED)); + (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags); if (!in) { ret = -EBADF; goto done; @@ -6876,13 +6877,16 @@ static void io_fixed_file_set(struct io_fixed_file *file_slot, struct file *file } static inline struct file *io_file_get_fixed(struct io_ring_ctx *ctx, - struct io_kiocb *req, int fd) + struct io_kiocb *req, int fd, + unsigned int issue_flags) { - struct file *file; + struct file *file = NULL; unsigned long file_ptr; + io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK)); + if (unlikely((unsigned int)fd >= ctx->nr_user_files)) - return NULL; + goto out; fd = array_index_nospec(fd, ctx->nr_user_files); file_ptr = io_fixed_file_slot(&ctx->file_table, fd)->file_ptr; file = (struct file *) (file_ptr & FFS_MASK); @@ -6890,6 +6894,8 @@ static inline struct file *io_file_get_fixed(struct io_ring_ctx *ctx, /* mask in overlapping REQ_F and FFS bits */ req->flags |= (file_ptr << REQ_F_NOWAIT_READ_BIT); io_req_set_rsrc_node(req); +out: + io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK)); return file; } @@ -6907,10 +6913,11 @@ static struct file *io_file_get_normal(struct io_ring_ctx *ctx, } static inline struct file *io_file_get(struct io_ring_ctx *ctx, - struct io_kiocb *req, int fd, bool fixed) + struct io_kiocb *req, int fd, bool fixed, + unsigned int issue_flags) { if (fixed) - return io_file_get_fixed(ctx, req, fd); + return io_file_get_fixed(ctx, req, fd, issue_flags); else return io_file_get_normal(ctx, req, fd); } @@ -7132,7 +7139,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, if (io_op_defs[req->opcode].needs_file) { req->file = io_file_get(ctx, req, READ_ONCE(sqe->fd), - (sqe_flags & IOSQE_FIXED_FILE)); + (sqe_flags & IOSQE_FIXED_FILE), 0); if (unlikely(!req->file)) ret = -EBADF; } From a25aa776b0c49b17c67ee047e58537552f16776f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Mar 2023 11:44:52 +0100 Subject: [PATCH 0107/1017] Linux 5.10.171 Link: https://lore.kernel.org/r/20230301180652.316428563@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Slade Watkins Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Jon Hunter Tested-by: Sudip Mukherjee Tested-by: Salvatore Bonaccorso Tested-by: Linux Kernel Functional Testing Tested-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 028fca7ec5cf..9dde2c230789 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 170 +SUBLEVEL = 171 EXTRAVERSION = NAME = Dare mighty things From 365c551e77e7c1d2861f53f836ae4fc7b51cfcca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Mar 2023 12:46:48 +0000 Subject: [PATCH 0108/1017] Revert "nvmem: core: fix return value" This reverts commit e95381034519a8c5a3150f7b03f4664b1da651b2 which is commit 0c4862b1c1465e473bc961a02765490578bf5c20 upstream. It breaks the Android kernel api, and isn't even really needed in the 5.10.y kernel tree yet, as there are no users of the new field. So revert it for now. If it is needed, it can be brought back in an abi-safe way in the future. Bug: 161946584 Change-Id: I4e335c73a46ba291c790e54f40350a754ff6376b Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 1505c745154e..0ef7b95348b1 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -638,7 +638,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { rval = PTR_ERR(nvmem->wp_gpio); - nvmem->wp_gpio = NULL; goto err_put_device; } From 07d89b34a942934a67b1bfed01a618cdce96bb68 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Mar 2023 12:47:15 +0000 Subject: [PATCH 0109/1017] Revert "nvmem: core: fix registration vs use race" This reverts commit 2dcb474af1d5d06c1e343a0d7248219bb87a08b7 which is commit ab3428cfd9aa2f3463ee4b2909b5bb2193bd0c4a upstream. It breaks the Android kernel api, and isn't even really needed in the 5.10.y kernel tree yet, as there are no users of the new field. So revert it for now. If it is needed, it can be brought back in an abi-safe way in the future. Bug: 161946584 Change-Id: Ibff0d5602c36121fdb31767fd37a013bd26f94cb Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 0ef7b95348b1..de356cdde4ce 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -682,10 +682,16 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->dev.groups = nvmem_dev_groups; #endif + dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); + + rval = device_add(&nvmem->dev); + if (rval) + goto err_put_device; + if (config->compat) { rval = nvmem_sysfs_setup_compat(nvmem, config); if (rval) - goto err_put_device; + goto err_device_del; } if (config->cells) { @@ -702,12 +708,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (rval) goto err_remove_cells; - dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - - rval = device_add(&nvmem->dev); - if (rval) - goto err_remove_cells; - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); return nvmem; @@ -716,6 +716,8 @@ err_remove_cells: nvmem_device_remove_all_cells(nvmem); if (config->compat) nvmem_sysfs_remove_compat(nvmem, config); +err_device_del: + device_del(&nvmem->dev); err_put_device: put_device(&nvmem->dev); From a4160f76c75807d2d55ffc651e6bea3787d8e6be Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Mar 2023 12:48:27 +0000 Subject: [PATCH 0110/1017] Revert "nvmem: core: fix cleanup after dev_set_name()" This reverts commit 23676ecd2eb377f7c24a6ff578b0f4c7135658b6 which is commit 560181d3ace61825f4ca9dd3481d6c0ee6709fa8 upstream. It breaks the Android kernel api, and isn't even really needed in the 5.10.y kernel tree yet, as there are no users of the new field. So revert it for now. If it is needed, it can be brought back in an abi-safe way in the future. Bug: 161946584 Change-Id: Ie5f1017d74bcf014b0ba5fe2f9e91eed8b735af4 Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index de356cdde4ce..38c05fce7d74 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -627,18 +627,14 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->id = rval; - nvmem->dev.type = &nvmem_provider_type; - nvmem->dev.bus = &nvmem_bus_type; - nvmem->dev.parent = config->dev; - - device_initialize(&nvmem->dev); - if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { + ida_free(&nvmem_ida, nvmem->id); rval = PTR_ERR(nvmem->wp_gpio); - goto err_put_device; + kfree(nvmem); + return ERR_PTR(rval); } kref_init(&nvmem->refcnt); @@ -650,6 +646,9 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->stride = config->stride ?: 1; nvmem->word_size = config->word_size ?: 1; nvmem->size = config->size; + nvmem->dev.type = &nvmem_provider_type; + nvmem->dev.bus = &nvmem_bus_type; + nvmem->dev.parent = config->dev; nvmem->root_only = config->root_only; nvmem->priv = config->priv; nvmem->type = config->type; @@ -672,8 +671,11 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) break; } - if (rval) - goto err_put_device; + if (rval) { + ida_free(&nvmem_ida, nvmem->id); + kfree(nvmem); + return ERR_PTR(rval); + } nvmem->read_only = device_property_present(config->dev, "read-only") || config->read_only || !nvmem->reg_write; @@ -684,7 +686,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - rval = device_add(&nvmem->dev); + rval = device_register(&nvmem->dev); if (rval) goto err_put_device; From d480976b056c3089ac12e2b463f66a5c8ed36dca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Mar 2023 12:48:31 +0000 Subject: [PATCH 0111/1017] Revert "nvmem: core: remove nvmem_config wp_gpio" This reverts commit 89991ededcb557dcfe6398fa37eb182d01cfe257 which is commit 569653f022a29a1a44ea9de5308b657228303fa5 upstream. It breaks the Android kernel api, and isn't even really needed in the 5.10.y kernel tree yet, as there are no users of the new field. So revert it for now. If it is needed, it can be brought back in an abi-safe way in the future. Bug: 161946584 Change-Id: Ib69df930ea19f91d0d35d792e3b90dc1d391980b Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 4 +++- include/linux/nvmem-provider.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 38c05fce7d74..9da4edbabfe7 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -627,7 +627,9 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->id = rval; - if (!config->ignore_wp) + if (config->wp_gpio) + nvmem->wp_gpio = config->wp_gpio; + else if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 5e07f3cfad30..39ec67689898 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -49,6 +49,7 @@ enum nvmem_type { * @word_size: Minimum read/write access granularity. * @stride: Minimum read/write access stride. * @priv: User context passed to read/write callbacks. + * @wp-gpio: Write protect pin * @ignore_wp: Write Protect pin is managed by the provider. * * Note: A default "nvmem" name will be assigned to the device if @@ -63,6 +64,7 @@ struct nvmem_config { const char *name; int id; struct module *owner; + struct gpio_desc *wp_gpio; const struct nvmem_cell_info *cells; int ncells; enum nvmem_type type; From a02b4a8660e1889e334db7b75e28078ee40f0d50 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 18 Feb 2023 09:12:29 +0000 Subject: [PATCH 0112/1017] Revert "nvmem: core: Fix a conflict between MTD and NVMEM on wp-gpios property" This reverts commit 34ec4c7831c416ac56619477f1701986634a7efc which is commit f6c052afe6f802d87c74153b7a57c43b2e9faf07 upstream. It breaks the Android kernel api, and isn't even really needed in the 5.10.y kernel tree yet, as there are no users of the new field. So revert it for now. If it is needed, it can be brought back in an abi-safe way in the future. Bug: 161946584 Change-Id: Ib1df4adb89fa493d044d1108da6ce6e667a5e0c7 Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 2 +- include/linux/nvmem-provider.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 9da4edbabfe7..1c17c5d09228 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -629,7 +629,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (config->wp_gpio) nvmem->wp_gpio = config->wp_gpio; - else if (!config->ignore_wp) + else nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 39ec67689898..06409a6c40bc 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -49,8 +49,7 @@ enum nvmem_type { * @word_size: Minimum read/write access granularity. * @stride: Minimum read/write access stride. * @priv: User context passed to read/write callbacks. - * @wp-gpio: Write protect pin - * @ignore_wp: Write Protect pin is managed by the provider. + * @wp-gpio: Write protect pin * * Note: A default "nvmem" name will be assigned to the device if * no name is specified in its configuration. In such case "" is @@ -70,7 +69,6 @@ struct nvmem_config { enum nvmem_type type; bool read_only; bool root_only; - bool ignore_wp; bool no_of_node; nvmem_reg_read_t reg_read; nvmem_reg_write_t reg_write; From da24142b1ef9fd5d36b76e36bab328a5b27523e8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 3 Mar 2023 06:49:57 -0700 Subject: [PATCH 0113/1017] io_uring: ensure that io_init_req() passes in the right issue_flags We can't use 0 here, as io_init_req() is always invoked with the ctx uring_lock held. Newer kernels have IO_URING_F_UNLOCKED for this, but previously we used IO_URING_F_NONBLOCK to indicate this as well. Fixes: 08681391b84d ("io_uring: add missing lock in io_get_file_fixed") Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 0c27b81ee1eb..cf6f8aeb450d 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -7139,7 +7139,8 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, if (io_op_defs[req->opcode].needs_file) { req->file = io_file_get(ctx, req, READ_ONCE(sqe->fd), - (sqe_flags & IOSQE_FIXED_FILE), 0); + (sqe_flags & IOSQE_FIXED_FILE), + IO_URING_F_NONBLOCK); if (unlikely(!req->file)) ret = -EBADF; } From 9fd42770b50756c08f04b4070ab6572adb2d6e1b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Mar 2023 15:13:15 +0100 Subject: [PATCH 0114/1017] Linux 5.10.172 Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9dde2c230789..447ed158d6bc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 171 +SUBLEVEL = 172 EXTRAVERSION = NAME = Dare mighty things From cb8382c3714540e404fa62bb9440f5387f8dd8f0 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Mon, 5 Jul 2021 10:26:59 +1200 Subject: [PATCH 0115/1017] HID: asus: Remove check for same LED brightness on set commit 3fdcf7cdfc229346d028242e73562704ad644dd0 upstream. Remove the early return on LED brightness set so that any controller application, daemon, or desktop may set the same brightness at any stage. This is required because many ASUS ROG keyboards will default to max brightness on laptop resume if the LEDs were set to off before sleep. Signed-off-by: Luke D Jones Signed-off-by: Jiri Kosina Signed-off-by: Stefan Ghinea Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-asus.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index f85c6e3309a0..9a6b63828634 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -402,9 +402,6 @@ static void asus_kbd_backlight_set(struct led_classdev *led_cdev, { struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, cdev); - if (led->brightness == brightness) - return; - led->brightness = brightness; schedule_work(&led->work); } From 6a63a3334acad9821b21e2dabcf67d82cdcbc44e Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sun, 12 Feb 2023 19:00:02 +0000 Subject: [PATCH 0116/1017] HID: asus: use spinlock to protect concurrent accesses commit 315c537068a13f0b5681d33dd045a912f4bece6f upstream. asus driver has a worker that may access data concurrently. Proct the accesses using a spinlock. Fixes: af22a610bc38 ("HID: asus: support backlight on USB keyboards") Signed-off-by: Pietro Borrello Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-4-7860c5763c38@diag.uniroma1.it Signed-off-by: Benjamin Tissoires Signed-off-by: Stefan Ghinea Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-asus.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 9a6b63828634..112c0c25a77f 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -95,6 +95,7 @@ struct asus_kbd_leds { struct hid_device *hdev; struct work_struct work; unsigned int brightness; + spinlock_t lock; bool removed; }; @@ -402,7 +403,12 @@ static void asus_kbd_backlight_set(struct led_classdev *led_cdev, { struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, cdev); + unsigned long flags; + + spin_lock_irqsave(&led->lock, flags); led->brightness = brightness; + spin_unlock_irqrestore(&led->lock, flags); + schedule_work(&led->work); } @@ -410,8 +416,14 @@ static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev) { struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, cdev); + enum led_brightness brightness; + unsigned long flags; - return led->brightness; + spin_lock_irqsave(&led->lock, flags); + brightness = led->brightness; + spin_unlock_irqrestore(&led->lock, flags); + + return brightness; } static void asus_kbd_backlight_work(struct work_struct *work) @@ -419,11 +431,14 @@ static void asus_kbd_backlight_work(struct work_struct *work) struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work); u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 }; int ret; + unsigned long flags; if (led->removed) return; + spin_lock_irqsave(&led->lock, flags); buf[4] = led->brightness; + spin_unlock_irqrestore(&led->lock, flags); ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf)); if (ret < 0) @@ -485,6 +500,7 @@ static int asus_kbd_register_leds(struct hid_device *hdev) drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set; drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get; INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work); + spin_lock_init(&drvdata->kbd_backlight->lock); ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev); if (ret < 0) { @@ -1013,9 +1029,13 @@ err_stop_hw: static void asus_remove(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + unsigned long flags; if (drvdata->kbd_backlight) { + spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags); drvdata->kbd_backlight->removed = true; + spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags); + cancel_work_sync(&drvdata->kbd_backlight->work); } From 21a2eec4a440060a6eb294dc890eaf553101ba09 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sun, 12 Feb 2023 19:00:03 +0000 Subject: [PATCH 0117/1017] HID: asus: use spinlock to safely schedule workers commit 4ab3a086d10eeec1424f2e8a968827a6336203df upstream. Use spinlocks to deal with workers introducing a wrapper asus_schedule_work(), and several spinlock checks. Otherwise, asus_kbd_backlight_set() may schedule led->work after the structure has been freed, causing a use-after-free. Fixes: af22a610bc38 ("HID: asus: support backlight on USB keyboards") Signed-off-by: Pietro Borrello Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-5-7860c5763c38@diag.uniroma1.it Signed-off-by: Benjamin Tissoires Signed-off-by: Stefan Ghinea Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-asus.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 112c0c25a77f..6865cab33cf8 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -398,6 +398,16 @@ static int asus_kbd_get_functions(struct hid_device *hdev, return ret; } +static void asus_schedule_work(struct asus_kbd_leds *led) +{ + unsigned long flags; + + spin_lock_irqsave(&led->lock, flags); + if (!led->removed) + schedule_work(&led->work); + spin_unlock_irqrestore(&led->lock, flags); +} + static void asus_kbd_backlight_set(struct led_classdev *led_cdev, enum led_brightness brightness) { @@ -409,7 +419,7 @@ static void asus_kbd_backlight_set(struct led_classdev *led_cdev, led->brightness = brightness; spin_unlock_irqrestore(&led->lock, flags); - schedule_work(&led->work); + asus_schedule_work(led); } static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev) @@ -433,9 +443,6 @@ static void asus_kbd_backlight_work(struct work_struct *work) int ret; unsigned long flags; - if (led->removed) - return; - spin_lock_irqsave(&led->lock, flags); buf[4] = led->brightness; spin_unlock_irqrestore(&led->lock, flags); From e1bb97947cac54822c92816dcb483544765c10ca Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Wed, 10 Aug 2022 13:43:18 +0200 Subject: [PATCH 0118/1017] powerpc/mm: Rearrange if-else block to avoid clang warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d78c8e32890ef7eca79ffd67c96022c7f9d8cce4 upstream. Clang warns: arch/powerpc/mm/book3s64/radix_tlb.c:1191:23: error: variable 'hstart' is uninitialized when used here __tlbiel_va_range(hstart, hend, pid, ^~~~~~ arch/powerpc/mm/book3s64/radix_tlb.c:1191:31: error: variable 'hend' is uninitialized when used here __tlbiel_va_range(hstart, hend, pid, ^~~~ Rework the 'if (IS_ENABLE(CONFIG_TRANSPARENT_HUGEPAGE))' so hstart/hend is always initialized to silence the warnings. That will also simplify the 'else' path. Clang is getting confused with these warnings, but the warnings is a false-positive. Suggested-by: Arnd Bergmann Suggested-by: Nathan Chancellor Reviewed-by: Christophe Leroy Reviewed-by: Nathan Chancellor Signed-off-by: Anders Roxell Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220810114318.3220630-1-anders.roxell@linaro.org Signed-off-by: Daniel Díaz Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/mm/book3s64/radix_tlb.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 4c2f75916a7e..abbfd5cc40c9 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -941,15 +941,12 @@ is_local: } } } else { - bool hflush = false; + bool hflush; unsigned long hstart, hend; - if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { - hstart = (start + PMD_SIZE - 1) & PMD_MASK; - hend = end & PMD_MASK; - if (hstart < hend) - hflush = true; - } + hstart = (start + PMD_SIZE - 1) & PMD_MASK; + hend = end & PMD_MASK; + hflush = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hstart < hend; if (local) { asm volatile("ptesync": : :"memory"); From 4862c41d5f3bee1ec64c979c82bd8cfe96b78f7d Mon Sep 17 00:00:00 2001 From: Chen Hui Date: Tue, 8 Nov 2022 22:19:17 +0800 Subject: [PATCH 0119/1017] ARM: OMAP2+: Fix memory leak in realtime_counter_init() [ Upstream commit ed8167cbf65c2b6ff6faeb0f96ded4d6d581e1ac ] The "sys_clk" resource is malloced by clk_get(), it is not released when the function return. Fixes: fa6d79d27614 ("ARM: OMAP: Add initialisation for the real-time counter.") Signed-off-by: Chen Hui Message-Id: <20221108141917.46796-1-judy.chenhui@huawei.com> Signed-off-by: Tony Lindgren Signed-off-by: Sasha Levin --- arch/arm/mach-omap2/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 620ba69c8f11..5677c4a08f37 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -76,6 +76,7 @@ static void __init realtime_counter_init(void) } rate = clk_get_rate(sys_clk); + clk_put(sys_clk); if (soc_is_dra7xx()) { /* From 644688a92162781d887a7d858617f056fc5b2946 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 26 Dec 2022 06:21:51 +0200 Subject: [PATCH 0120/1017] arm64: dts: qcom: qcs404: use symbol names for PCIe resets [ Upstream commit 41a37d157a613444c97e8f71a5fb2a21116b70d7 ] The commit e5bbbff5b7d7 ("clk: gcc-qcs404: Add PCIe resets") added names for PCIe resets, but it did not change the existing qcs404.dtsi to use these names. Do it now and use symbol names to make it easier to check and modify the dtsi in future. Fixes: e5bbbff5b7d7 ("clk: gcc-qcs404: Add PCIe resets") Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221226042154.2666748-14-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/qcs404.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index 7bddc5ebc6aa..d41f068dde16 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -775,7 +775,7 @@ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; resets = <&gcc GCC_PCIEPHY_0_PHY_BCR>, - <&gcc 21>; + <&gcc GCC_PCIE_0_PIPE_ARES>; reset-names = "phy", "pipe"; clock-output-names = "pcie_0_pipe_clk"; @@ -1305,12 +1305,12 @@ <&gcc GCC_PCIE_0_SLV_AXI_CLK>; clock-names = "iface", "aux", "master_bus", "slave_bus"; - resets = <&gcc 18>, - <&gcc 17>, - <&gcc 15>, - <&gcc 19>, + resets = <&gcc GCC_PCIE_0_AXI_MASTER_ARES>, + <&gcc GCC_PCIE_0_AXI_SLAVE_ARES>, + <&gcc GCC_PCIE_0_AXI_MASTER_STICKY_ARES>, + <&gcc GCC_PCIE_0_CORE_STICKY_ARES>, <&gcc GCC_PCIE_0_BCR>, - <&gcc 16>; + <&gcc GCC_PCIE_0_AHB_ARES>; reset-names = "axi_m", "axi_s", "axi_m_sticky", From 227f8c1c5c4b3d131b66e57e58d38054f441b915 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Tue, 29 Nov 2022 22:05:44 +0800 Subject: [PATCH 0121/1017] ARM: zynq: Fix refcount leak in zynq_early_slcr_init [ Upstream commit 9eedb910a3be0005b88c696a8552c0d4c9937cd4 ] of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on error path. Add missing of_node_put() to avoid refcount leak. Fixes: 3329659df030 ("ARM: zynq: Simplify SLCR initialization") Signed-off-by: Qiheng Lin Link: https://lore.kernel.org/r/20221129140544.41293-1-linqiheng@huawei.com Signed-off-by: Michal Simek Signed-off-by: Sasha Levin --- arch/arm/mach-zynq/slcr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index 37707614885a..9765b3f4c2fc 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -213,6 +213,7 @@ int __init zynq_early_slcr_init(void) zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr"); if (IS_ERR(zynq_slcr_regmap)) { pr_err("%s: failed to find zynq-slcr\n", __func__); + of_node_put(np); return -ENODEV; } From 717aa39846524ce1790f1130c4a0fc560fcecc89 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 1 Dec 2022 16:42:26 +0800 Subject: [PATCH 0122/1017] arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description [ Upstream commit ce8a06b5bac75ccce99c0cf91b96b767d64f28a7 ] The systimer block derives its 13 MHz clock by dividing the main 26 MHz oscillator clock by 2 internally, not through the TOPCKGEN clock controller. On the MT8183 this divider is set either by power-on-reset or by the bootloader. The bootloader may then make the divider unconfigurable to, but can be read out by, the operating system. Making the systimer block take the 26 MHz clock directly requires changing the implementations. As an ABI compatible fix, change the input clock of the systimer block a fixed factor divide-by-2 clock that takes the 26 MHz oscillator as its input. Fixes: 5bc8e2875ffb ("arm64: dts: mt8183: add systimer0 device node") Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20221201084229.3464449-2-wenst@chromium.org Signed-off-by: Matthias Brugger Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 08a914d3a643..31bc8bae8cff 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -205,6 +205,15 @@ method = "smc"; }; + clk13m: fixed-factor-clock-13m { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clocks = <&clk26m>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "clk13m"; + }; + clk26m: oscillator { compatible = "fixed-clock"; #clock-cells = <0>; @@ -355,8 +364,7 @@ "mediatek,mt6765-timer"; reg = <0 0x10017000 0 0x1000>; interrupts = ; - clocks = <&topckgen CLK_TOP_CLK13M>; - clock-names = "clk13m"; + clocks = <&clk13m>; }; gce: mailbox@10238000 { From 64b69cb420c5b6a185e72fb6e685d3736734f763 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 22 Dec 2022 16:13:16 +0100 Subject: [PATCH 0123/1017] arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name [ Upstream commit 740862bb5f59b93efb390a417995f88a64bdc323 ] The pin config entry should have a string, not number, for the GPIO used as WCD9340 audio codec interrupt. Fixes: 89a32a4e769c ("arm64: dts: qcom: db845c: add analog audio support") Reported-by: Doug Anderson Signed-off-by: Krzysztof Kozlowski Reviewed-by: Douglas Anderson Reviewed-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221222151319.122398-1-krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index c6691bdc8100..1e889ca932e4 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -896,7 +896,7 @@ }; wcd_intr_default: wcd_intr_default { - pins = <54>; + pins = "gpio54"; function = "gpio"; input-enable; From 2df155a114475359f3383c4547bb67a0b83147c4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 13 Dec 2022 11:19:17 +0100 Subject: [PATCH 0124/1017] arm64: dts: qcom: sc7180: correct SPMI bus address cells [ Upstream commit 1f75745537222172f84783d369bbd1fb2d4b6414 ] The SPMI bus uses two address cells and zero size cells (second reg entry - SPMI_USID - is not the size): spmi@c440000: #address-cells:0:0: 2 was expected Fixes: 0f9dc5f09fbd ("arm64: dts: qcom: sc7180: Add SPMI PMIC arbiter device") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Konrad Dybcio Reviewed-by: Stephen Boyd Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221213101921.47924-1-krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/sc7180.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index c71f3afc1cc9..eb07a882d43b 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -3066,8 +3066,8 @@ interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; qcom,ee = <0>; qcom,channel = <0>; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <0>; interrupt-controller; #interrupt-cells = <4>; cell-index = <0>; From 8303a34fce2ae22381d4a2dae0806bc75b707693 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 11 Jan 2023 22:13:48 +0100 Subject: [PATCH 0125/1017] arm64: dts: meson-gx: Fix Ethernet MAC address unit name [ Upstream commit 8ed5310356bfa47cc6bb4221ae6b21258c52e3d1 ] Unit names should use hyphens instead of underscores to not cause warnings. Fixes: bfe59f92d306 ("ARM64: dts: amlogic: gxbb: Enable NVMEM") Suggested-by: Vyacheslav Bocharov Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230111211350.1461860-5-martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 88a7db5c55a0..46018df13cc2 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -226,7 +226,7 @@ reg = <0x14 0x10>; }; - eth_mac: eth_mac@34 { + eth_mac: eth-mac@34 { reg = <0x34 0x10>; }; From bd55aa16bf34231e128d1f1540a29bf27d6df7e6 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 11 Jan 2023 22:13:49 +0100 Subject: [PATCH 0126/1017] arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name [ Upstream commit e7303651bbc76c848007f1cfac1fbeaa65f600d1 ] Documentation/devicetree/bindings/net/ethernet-phy.yaml defines that the node name for Ethernet PHYs should match the following pattern: ^ethernet-phy(@[a-f0-9]+)?$ Replace the underscore with a hyphen to adhere to this binding. Fixes: 280c17df8fbf ("arm64: dts: meson: g12a: add mdio multiplexer") Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230111211350.1461860-6-martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index 2091db7c9b8a..c0defb36592d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -1727,7 +1727,7 @@ #address-cells = <1>; #size-cells = <0>; - internal_ephy: ethernet_phy@8 { + internal_ephy: ethernet-phy@8 { compatible = "ethernet-phy-id0180.3301", "ethernet-phy-ieee802.3-c22"; interrupts = ; From 5633e86cce6a653d69919a2a8827d2911d16fa09 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Wed, 11 Jan 2023 22:13:50 +0100 Subject: [PATCH 0127/1017] arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address [ Upstream commit f189c869ad92787ddd753558bcbae89d75825bb6 ] Node names should be generic and use hyphens instead of underscores to not cause warnings. Also nodes without a reg property should not have a unit-address. Change the scpi_dvfs node to use clock-controller as node name without a unit address (since it does not have a reg property). Fixes: 70db166a2baa ("ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes") Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20230111211350.1461860-7-martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 46018df13cc2..85f4876c509a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -243,7 +243,7 @@ scpi_clocks: clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: scpi_clocks@0 { + scpi_dvfs: clock-controller { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>; From 7ee2ca51e35715fafd4ad27dc2eb2129055efdae Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sun, 8 Jan 2023 14:04:40 +0100 Subject: [PATCH 0128/1017] arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names [ Upstream commit 877cff3568c0f54511d77918ae16b2d6e9a0dfce ] It seems that clock-output-names for the USB3 QMP PHY-s where set without actually checking what is the GCC clock driver expecting, so clock core could never actually find the parents for usb0_pipe_clk_src and usb1_pipe_clk_src clocks in the GCC driver. So, correct the names to be what the driver expects so that parenting works. Before: gcc_usb0_pipe_clk_src 0 0 0 125000000 0 0 50000 Y gcc_usb1_pipe_clk_src 0 0 0 125000000 0 0 50000 Y After: usb3phy_0_cc_pipe_clk 1 1 0 125000000 0 0 50000 Y usb0_pipe_clk_src 1 1 0 125000000 0 0 50000 Y gcc_usb0_pipe_clk 1 1 0 125000000 0 0 50000 Y usb3phy_1_cc_pipe_clk 1 1 0 125000000 0 0 50000 Y usb1_pipe_clk_src 1 1 0 125000000 0 0 50000 Y gcc_usb1_pipe_clk 1 1 0 125000000 0 0 50000 Y Fixes: 5e09bc51d07b ("arm64: dts: ipq8074: enable USB support") Signed-off-by: Robert Marko Reviewed-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230108130440.670181-2-robimarko@gmail.com Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 99e2488b92dc..9114402c044b 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -108,7 +108,7 @@ #phy-cells = <0>; clocks = <&gcc GCC_USB1_PIPE_CLK>; clock-names = "pipe0"; - clock-output-names = "gcc_usb1_pipe_clk_src"; + clock-output-names = "usb3phy_1_cc_pipe_clk"; }; }; @@ -151,7 +151,7 @@ #phy-cells = <0>; clocks = <&gcc GCC_USB0_PIPE_CLK>; clock-names = "pipe0"; - clock-output-names = "gcc_usb0_pipe_clk_src"; + clock-output-names = "usb3phy_0_cc_pipe_clk"; }; }; From 8f1cb871f948f616af395c18f34ae1479806d1cd Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 29 Sep 2021 11:42:51 +0800 Subject: [PATCH 0129/1017] arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes [ Upstream commit 942bcd33ed455ad40b71a59901bd926bbf4a500e ] IPQ8074 PCIe PHY nodes are broken in the many ways: - '#address-cells', '#size-cells' and 'ranges' are missing. - Child phy/lane node is missing, and the child properties like '#phy-cells' and 'clocks' are mistakenly put into parent node. - The clocks properties for parent node are missing. Fix them to get the nodes comply with the bindings schema. Signed-off-by: Shawn Guo Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210929034253.24570-9-shawn.guo@linaro.org Stable-dep-of: 7ba33591b45f ("arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 46 +++++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 9114402c044b..5b17dbefe5cf 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -167,34 +167,60 @@ resets = <&gcc GCC_QUSB2_0_PHY_BCR>; }; - pcie_phy0: phy@86000 { + pcie_qmp0: phy@86000 { compatible = "qcom,ipq8074-qmp-pcie-phy"; reg = <0x00086000 0x1000>; - #phy-cells = <0>; - clocks = <&gcc GCC_PCIE0_PIPE_CLK>; - clock-names = "pipe_clk"; - clock-output-names = "pcie20_phy0_pipe_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clocks = <&gcc GCC_PCIE0_AUX_CLK>, + <&gcc GCC_PCIE0_AHB_CLK>; + clock-names = "aux", "cfg_ahb"; resets = <&gcc GCC_PCIE0_PHY_BCR>, <&gcc GCC_PCIE0PHY_PHY_BCR>; reset-names = "phy", "common"; status = "disabled"; + + pcie_phy0: phy@86200 { + reg = <0x86200 0x16c>, + <0x86400 0x200>, + <0x86800 0x4f4>; + #phy-cells = <0>; + #clock-cells = <0>; + clocks = <&gcc GCC_PCIE0_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "pcie_0_pipe_clk"; + }; }; - pcie_phy1: phy@8e000 { + pcie_qmp1: phy@8e000 { compatible = "qcom,ipq8074-qmp-pcie-phy"; reg = <0x0008e000 0x1000>; - #phy-cells = <0>; - clocks = <&gcc GCC_PCIE1_PIPE_CLK>; - clock-names = "pipe_clk"; - clock-output-names = "pcie20_phy1_pipe_clk"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clocks = <&gcc GCC_PCIE1_AUX_CLK>, + <&gcc GCC_PCIE1_AHB_CLK>; + clock-names = "aux", "cfg_ahb"; resets = <&gcc GCC_PCIE1_PHY_BCR>, <&gcc GCC_PCIE1PHY_PHY_BCR>; reset-names = "phy", "common"; status = "disabled"; + + pcie_phy1: phy@8e200 { + reg = <0x8e200 0x16c>, + <0x8e400 0x200>, + <0x8e800 0x4f4>; + #phy-cells = <0>; + #clock-cells = <0>; + clocks = <&gcc GCC_PCIE1_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "pcie_1_pipe_clk"; + }; }; tlmm: pinctrl@1000000 { From 9b5b1652e330f463f90e7a06846a750c3bc08633 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 15 Sep 2022 16:34:30 +0200 Subject: [PATCH 0130/1017] arm64: dts: qcom: ipq8074: fix PCIe PHY serdes size [ Upstream commit ed22cc93abae68f9d3fc4957c20a1d902cf28882 ] The size of the PCIe PHY serdes register region is 0x1c4 and the corresponding 'reg' property should specifically not include the adjacent regions that are defined in the child node (e.g. tx and rx). Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes") Signed-off-by: Johan Hovold Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220915143431.19842-1-johan+linaro@kernel.org Stable-dep-of: 7ba33591b45f ("arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY") Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 5b17dbefe5cf..555f633ef20e 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -169,7 +169,7 @@ pcie_qmp0: phy@86000 { compatible = "qcom,ipq8074-qmp-pcie-phy"; - reg = <0x00086000 0x1000>; + reg = <0x00086000 0x1c4>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -197,7 +197,7 @@ pcie_qmp1: phy@8e000 { compatible = "qcom,ipq8074-qmp-pcie-phy"; - reg = <0x0008e000 0x1000>; + reg = <0x0008e000 0x1c4>; #address-cells = <1>; #size-cells = <1>; ranges; From 77970cf38954b790a51fcfe3bf85d487a944053f Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 13 Jan 2023 17:44:42 +0100 Subject: [PATCH 0131/1017] arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY [ Upstream commit 7ba33591b45f9d547a317e42f1c2acd19c925eb6 ] IPQ8074 comes in 2 silicon versions: * v1 with 2x Gen2 PCIe ports and QMP PHY-s * v2 with 1x Gen3 and 1x Gen2 PCIe ports and QMP PHY-s v2 is the final and production version that is actually supported by the kernel, however it looks like PCIe related nodes were added for the v1 SoC. Now that we have Gen3 QMP PHY support, we can start fixing the PCIe support by fixing the Gen3 QMP PHY node first. Change the compatible to the Gen3 QMP PHY, correct the register space start and size, add the missing misc PCS register space. Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes") Signed-off-by: Robert Marko Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230113164449.906002-2-robimarko@gmail.com Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 555f633ef20e..98f0001fc709 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -167,9 +167,9 @@ resets = <&gcc GCC_QUSB2_0_PHY_BCR>; }; - pcie_qmp0: phy@86000 { - compatible = "qcom,ipq8074-qmp-pcie-phy"; - reg = <0x00086000 0x1c4>; + pcie_qmp0: phy@84000 { + compatible = "qcom,ipq8074-qmp-gen3-pcie-phy"; + reg = <0x00084000 0x1bc>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -183,10 +183,11 @@ "common"; status = "disabled"; - pcie_phy0: phy@86200 { - reg = <0x86200 0x16c>, - <0x86400 0x200>, - <0x86800 0x4f4>; + pcie_phy0: phy@84200 { + reg = <0x84200 0x16c>, + <0x84400 0x200>, + <0x84800 0x1f0>, + <0x84c00 0xf4>; #phy-cells = <0>; #clock-cells = <0>; clocks = <&gcc GCC_PCIE0_PIPE_CLK>; From e839d027d71a8f20ba4218dd039c6d28431ccd27 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 13 Jan 2023 17:44:43 +0100 Subject: [PATCH 0132/1017] arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges [ Upstream commit 2055cb7dccea16bafa3adf9c5e3216949512c34a ] Current ranges property set in Gen2 PCIe node is incorrect, replace it with the downstream 5.4 QCA kernel value. Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes") Signed-off-by: Robert Marko Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230113164449.906002-3-robimarko@gmail.com Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 98f0001fc709..1dbae9c73c59 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -610,9 +610,9 @@ phy-names = "pciephy"; ranges = <0x81000000 0 0x10200000 0x10200000 - 0 0x100000 /* downstream I/O */ - 0x82000000 0 0x10300000 0x10300000 - 0 0xd00000>; /* non-prefetchable memory */ + 0 0x10000>, /* downstream I/O */ + <0x82000000 0 0x10220000 0x10220000 + 0 0xfde0000>; /* non-prefetchable memory */ interrupts = ; interrupt-names = "msi"; From 192cb335d89b9bb6fdc96f1108916a9ac5235054 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 13 Jan 2023 17:44:48 +0100 Subject: [PATCH 0133/1017] arm64: dts: qcom: ipq8074: fix Gen3 PCIe node [ Upstream commit 3e83a9c41ab0244a45a4a2800b9adb8de0d15f82 ] IPQ8074 comes in 2 silicon versions: * v1 with 2x Gen2 PCIe ports and QMP PHY-s * v2 with 1x Gen3 and 1x Gen2 PCIe ports and QMP PHY-s v2 is the final and production version that is actually supported by the kernel, however it looks like PCIe related nodes were added for the v1 SoC. Finish the PCIe fixup by using the correct compatible, adding missing ATU register space, declaring max-link-speed, use correct ranges, add missing clocks and resets. Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes") Signed-off-by: Robert Marko Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230113164449.906002-8-robimarko@gmail.com Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 30 +++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 1dbae9c73c59..4ef364c01012 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -655,16 +655,18 @@ }; pcie0: pci@20000000 { - compatible = "qcom,pcie-ipq8074"; + compatible = "qcom,pcie-ipq8074-gen3"; reg = <0x20000000 0xf1d>, <0x20000f20 0xa8>, - <0x00080000 0x2000>, + <0x20001000 0x1000>, + <0x00080000 0x4000>, <0x20100000 0x1000>; - reg-names = "dbi", "elbi", "parf", "config"; + reg-names = "dbi", "elbi", "atu", "parf", "config"; device_type = "pci"; linux,pci-domain = <0>; bus-range = <0x00 0xff>; num-lanes = <1>; + max-link-speed = <3>; #address-cells = <3>; #size-cells = <2>; @@ -672,9 +674,9 @@ phy-names = "pciephy"; ranges = <0x81000000 0 0x20200000 0x20200000 - 0 0x100000 /* downstream I/O */ - 0x82000000 0 0x20300000 0x20300000 - 0 0xd00000>; /* non-prefetchable memory */ + 0 0x10000>, /* downstream I/O */ + <0x82000000 0 0x20220000 0x20220000 + 0 0xfde0000>; /* non-prefetchable memory */ interrupts = ; interrupt-names = "msi"; @@ -692,28 +694,30 @@ clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>, <&gcc GCC_PCIE0_AXI_M_CLK>, <&gcc GCC_PCIE0_AXI_S_CLK>, - <&gcc GCC_PCIE0_AHB_CLK>, - <&gcc GCC_PCIE0_AUX_CLK>; - + <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>, + <&gcc GCC_PCIE0_RCHNG_CLK>; clock-names = "iface", "axi_m", "axi_s", - "ahb", - "aux"; + "axi_bridge", + "rchng"; + resets = <&gcc GCC_PCIE0_PIPE_ARES>, <&gcc GCC_PCIE0_SLEEP_ARES>, <&gcc GCC_PCIE0_CORE_STICKY_ARES>, <&gcc GCC_PCIE0_AXI_MASTER_ARES>, <&gcc GCC_PCIE0_AXI_SLAVE_ARES>, <&gcc GCC_PCIE0_AHB_ARES>, - <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>; + <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>, + <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>; reset-names = "pipe", "sleep", "sticky", "axi_m", "axi_s", "ahb", - "axi_m_sticky"; + "axi_m_sticky", + "axi_s_sticky"; status = "disabled"; }; }; From c56595b948ad42de867c9e64e3540b151e7c77dc Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 13 Jan 2023 17:44:49 +0100 Subject: [PATCH 0134/1017] arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names [ Upstream commit 0e8b90c0256cf9c9589e2cee517dedc987a34355 ] Current PCIe QMP PHY output name were changed in ("arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes") however it did not account for the fact that GCC driver is relying on the old names to match them as they are being used as the parent for the gcc_pcie0_pipe_clk and gcc_pcie1_pipe_clk. This broke parenting as GCC could not find the parent clock, so fix it by changing to the names that driver is expecting. Fixes: 942bcd33ed45 ("arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes") Signed-off-by: Robert Marko Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230113164449.906002-9-robimarko@gmail.com Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 4ef364c01012..25f78c71e010 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -192,7 +192,7 @@ #clock-cells = <0>; clocks = <&gcc GCC_PCIE0_PIPE_CLK>; clock-names = "pipe0"; - clock-output-names = "pcie_0_pipe_clk"; + clock-output-names = "pcie20_phy0_pipe_clk"; }; }; @@ -220,7 +220,7 @@ #clock-cells = <0>; clocks = <&gcc GCC_PCIE1_PIPE_CLK>; clock-names = "pipe0"; - clock-output-names = "pcie_1_pipe_clk"; + clock-output-names = "pcie20_phy1_pipe_clk"; }; }; From 1fa673af0af8f70f244d3c534b361898e2960ab3 Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Thu, 19 Jan 2023 05:30:31 +0000 Subject: [PATCH 0135/1017] arm64: dts: meson: remove CPU opps below 1GHz for G12A boards [ Upstream commit 3cbd431c2b34d84605d358c8c57654193fd661fb ] Amlogic G12A devices experience CPU stalls and random board wedges when the system idles and CPU cores clock down to lower opp points. Recent vendor kernels include a change to remove 100-250MHz and other distro sources also remove the 500/667MHz points. Unless all 100-667Mhz opps are removed or the CPU governor forced to performance stalls are still observed, so let's remove them to improve stability and uptime. Fixes: b190056fa9ee ("arm64: dts: meson-g12a: add cpus OPP table") Signed-off-by: Christian Hewitt Link: https://lore.kernel.org/r/20230119053031.21400-1-christianshewitt@gmail.com Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi index fb0ab27d1f64..6eaceb717d61 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi @@ -57,26 +57,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <731000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <731000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <731000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <666666666>; - opp-microvolt = <731000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <731000>; From 66315db914aab58a55b3648baad645314f8993b5 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 19 Jan 2023 11:57:54 +0200 Subject: [PATCH 0136/1017] ARM: OMAP1: call platform_device_put() in error case in omap1_dm_timer_init() [ Upstream commit 0414a100d6ab32721efa70ab55524540fdfe0ede ] If platform_device_add() is not called or failed, it should call platform_device_put() in error case. Fixes: 97933d6ced60 ("ARM: OMAP1: dmtimer: conversion to platform devices") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Message-Id: <20220701094602.2365099-1-yangyingliang@huawei.com> Signed-off-by: Tony Lindgren Signed-off-by: Sasha Levin --- arch/arm/mach-omap1/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 97fc2096b970..05f016d5e9f6 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -165,7 +165,7 @@ err_free_pdata: kfree(pdata); err_free_pdev: - platform_device_unregister(pdev); + platform_device_put(pdev); return ret; } From 4811cfd28622d1c2f29779ba1e1554d57b7dfb24 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Jan 2023 10:02:12 +0100 Subject: [PATCH 0137/1017] ARM: s3c: fix s3c64xx_set_timer_source prototype [ Upstream commit 5bf52f5e4d12b8109f348cab60cb7d51092c4270 ] The prototype does not match the definition, as gcc-13 points out: arch/arm/mach-s3c/s3c64xx.c:169:13: error: conflicting types for 's3c64xx_set_timer_source' due to enum/integer mismatch; have 'void(unsigned int, unsigned int)' [-Werror=enum-int-mismatch] 169 | void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source) | ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/arm/mach-s3c/s3c64xx.c:50: arch/arm/mach-s3c/s3c64xx.h:62:20: note: previous declaration of 's3c64xx_set_timer_source' with type 'void(enum s3c64xx_timer_mode, enum s3c64xx_timer_mode)' 62 | extern void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event, | ^~~~~~~~~~~~~~~~~~~~~~~~ Fixes: 4280506ac9bb ("ARM: SAMSUNG: Move all platforms to new clocksource driver") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230118090224.2162863-1-arnd@kernel.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin --- arch/arm/mach-s3c/s3c64xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-s3c/s3c64xx.c b/arch/arm/mach-s3c/s3c64xx.c index 4dfb648142f2..17f006503149 100644 --- a/arch/arm/mach-s3c/s3c64xx.c +++ b/arch/arm/mach-s3c/s3c64xx.c @@ -173,7 +173,8 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = { .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5), }; -void __init s3c64xx_set_timer_source(unsigned int event, unsigned int source) +void __init s3c64xx_set_timer_source(enum s3c64xx_timer_mode event, + enum s3c64xx_timer_mode source) { s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1; s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source)); From 5325b8a1208c864b8bd2a94892da6ab73543e389 Mon Sep 17 00:00:00 2001 From: Vaishnav Achath Date: Thu, 19 Jan 2023 09:56:22 +0530 Subject: [PATCH 0138/1017] arm64: dts: ti: k3-j7200: Fix wakeup pinmux range [ Upstream commit 9ae21ac445e911e3541985c20052fc05d60f6879 ] The WKUP_PADCONFIG register region in J7200 has multiple non-addressable regions, split the existing wkup_pmx region as follows to avoid the non-addressable regions and include all valid WKUP_PADCONFIG registers. Also update references to old nodes with new ones. wkup_pmx0 -> 13 pins (WKUP_PADCONFIG 0 - 12) wkup_pmx1 -> 2 pins (WKUP_PADCONFIG 14 - 15) wkup_pmx2 -> 59 pins (WKUP_PADCONFIG 26 - 84) wkup_pmx3 -> 8 pins (WKUP_PADCONFIG 93 - 100) J7200 Datasheet (Table 6-106, Section 6.4 Pin Multiplexing) : https://www.ti.com/lit/ds/symlink/dra821u.pdf Fixes: d361ed88455f ("arm64: dts: ti: Add support for J7200 SoC") Signed-off-by: Vaishnav Achath Reviewed-by: Jayesh Choudhary Signed-off-by: Vignesh Raghavendra Link: https://lore.kernel.org/r/20230119042622.22310-1-vaishnav.a@ti.com Signed-off-by: Sasha Levin --- .../dts/ti/k3-j7200-common-proc-board.dts | 2 +- .../boot/dts/ti/k3-j7200-mcu-wakeup.dtsi | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index e8a4143e1c24..909ab6661aef 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -16,7 +16,7 @@ }; }; -&wkup_pmx0 { +&wkup_pmx2 { mcu_cpsw_pins_default: mcu-cpsw-pins-default { pinctrl-single,pins = < J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi index eb2a78a53512..7f252cc6eb37 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi @@ -56,7 +56,34 @@ wkup_pmx0: pinctrl@4301c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ - reg = <0x00 0x4301c000 0x00 0x178>; + reg = <0x00 0x4301c000 0x00 0x34>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + wkup_pmx1: pinctrl@0x4301c038 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c038 0x00 0x8>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + wkup_pmx2: pinctrl@0x4301c068 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c068 0x00 0xec>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + wkup_pmx3: pinctrl@0x4301c174 { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x4301c174 0x00 0x20>; #pinctrl-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xffffffff>; From 23134f7a5429153a61d976aa727a92b05b045a11 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 20 Jan 2023 16:53:54 +0100 Subject: [PATCH 0139/1017] ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato [ Upstream commit d15d2a617499882971ddb773a583015bf36fa492 ] The property is wr-active: exynos3250-rinato.dtb: fimd@11c00000: i80-if-timings: 'wr-act' does not match any of the regexes: 'pinctrl-[0-9]+' Fixes: b59b3afb94d4 ("ARM: dts: add fimd device support for exynos3250-rinato") Link: https://lore.kernel.org/r/20230120155404.323386-2-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin --- arch/arm/boot/dts/exynos3250-rinato.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index f9e3b13d3aac..bbf01f76ce3b 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -249,7 +249,7 @@ i80-if-timings { cs-setup = <0>; wr-setup = <0>; - wr-act = <1>; + wr-active = <1>; wr-hold = <0>; }; }; From 14736f2eaec5e3fe812c50031400293fd11b3608 Mon Sep 17 00:00:00 2001 From: Angus Chen Date: Thu, 5 Jan 2023 14:11:23 +0800 Subject: [PATCH 0140/1017] ARM: imx: Call ida_simple_remove() for ida_simple_get [ Upstream commit ebeb49f43c8952f12aa20f03f00d7009edc2d1c5 ] The function call ida_simple_get maybe fail,we should deal with it. And if ida_simple_get success ,it need to call ida_simple_remove also. BTW,devm_kasprintf can handle id is zero for consistency. Fixes: e76bdfd7403a ("ARM: imx: Added perf functionality to mmdc driver") Signed-off-by: Angus Chen Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/mach-imx/mmdc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index af12668d0bf5..b9efe9da06e0 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -99,6 +99,7 @@ struct mmdc_pmu { cpumask_t cpu; struct hrtimer hrtimer; unsigned int active_events; + int id; struct device *dev; struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; struct hlist_node node; @@ -433,8 +434,6 @@ static enum hrtimer_restart mmdc_pmu_timer_handler(struct hrtimer *hrtimer) static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, void __iomem *mmdc_base, struct device *dev) { - int mmdc_num; - *pmu_mmdc = (struct mmdc_pmu) { .pmu = (struct pmu) { .task_ctx_nr = perf_invalid_context, @@ -452,15 +451,16 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, .active_events = 0, }; - mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); + pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); - return mmdc_num; + return pmu_mmdc->id; } static int imx_mmdc_remove(struct platform_device *pdev) { struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev); + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); perf_pmu_unregister(&pmu_mmdc->pmu); iounmap(pmu_mmdc->mmdc_base); @@ -474,7 +474,6 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b { struct mmdc_pmu *pmu_mmdc; char *name; - int mmdc_num; int ret; const struct of_device_id *of_id = of_match_device(imx_mmdc_dt_ids, &pdev->dev); @@ -497,14 +496,14 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b cpuhp_mmdc_state = ret; } - mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); - pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; - if (mmdc_num == 0) - name = "mmdc"; - else - name = devm_kasprintf(&pdev->dev, - GFP_KERNEL, "mmdc%d", mmdc_num); + ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); + if (ret < 0) + goto pmu_free; + name = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "mmdc%d", ret); + + pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, @@ -525,6 +524,7 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b pmu_register_err: pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); hrtimer_cancel(&pmu_mmdc->hrtimer); pmu_free: From a7163b258ae8ab4013bb6feaca3f3c000ff210ca Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:22 +0100 Subject: [PATCH 0141/1017] arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name [ Upstream commit 127f79212b07c5d9a6657a87e3eafdd889335814 ] Fixes: scpi: clocks: 'clock-controller' does not match any of the regexes: '^clocks-[0-9a-f]+$', 'pinctrl-[0-9]+' Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-1-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 85f4876c509a..39293450135a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -243,7 +243,7 @@ scpi_clocks: clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: clock-controller { + scpi_dvfs: clocks-0 { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>; From eb5f2c56577920f28b4defa3731b06cecc09097b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:23 +0100 Subject: [PATCH 0142/1017] arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name [ Upstream commit 5b7069d72f03c92a0ab919725017394ebce03a81 ] Fixes: scpi: clocks: 'clock-controller' does not match any of the regexes: '^clocks-[0-9a-f]+$', 'pinctrl-[0-9]+' Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-2-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index 5c75fbf0d470..ddf9eb79e493 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -151,7 +151,7 @@ scpi_clocks: clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: clock-controller { + scpi_dvfs: clocks-0 { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>; From 6a46320f2ae7372003b333f45019709334405e9f Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:24 +0100 Subject: [PATCH 0143/1017] arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible [ Upstream commit 2ff650051493d5bdb6dd09d4c2850bb37db6be31 ] Fixes: scpi: sensors:compatible: 'oneOf' conditional failed, one must be fixed: ['amlogic,meson-gxbb-scpi-sensors'] is too short 'arm,scpi-sensors' was expected Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-3-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index ddf9eb79e493..c892b252e5b0 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -160,7 +160,7 @@ }; scpi_sensors: sensors { - compatible = "amlogic,meson-gxbb-scpi-sensors"; + compatible = "amlogic,meson-gxbb-scpi-sensors", "arm,scpi-sensors"; #thermal-sensor-cells = <1>; }; }; From 436060c1b6684815eb7219ce3af034feeedbe4da Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:26 +0100 Subject: [PATCH 0144/1017] arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names property [ Upstream commit e3bd275ccbacf5eb18eaa311cea39f8bf8655feb ] Fixes: bluetooth: 'clock-names' does not match any of the regexes: 'pinctrl-[0-9]+' Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-5-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts index 0b95e9ecbef0..ca3fd6b67b94 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-sml5442tw.dts @@ -75,6 +75,5 @@ enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; max-speed = <2000000>; clocks = <&wifi32k>; - clock-names = "lpo"; }; }; From 1c30db46dd1d4a4f45600cc88fa92d1373855f2b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:27 +0100 Subject: [PATCH 0145/1017] arm64: dts: amlogic: meson-gx: add missing unit address to rng node name [ Upstream commit 61ff70708b98a85516eccb3755084ac97b42cf48 ] Fixes: bus@c8834000: rng: {...} should not be valid under {'type': 'object'} Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-6-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 39293450135a..4c7131526c4d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -524,7 +524,7 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>; - hwrng: rng { + hwrng: rng@0 { compatible = "amlogic,meson-rng"; reg = <0x0 0x0 0x0 0x4>; }; From 373bb505ffe605086fa470790d806d661ac111fa Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:30 +0100 Subject: [PATCH 0146/1017] arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node name [ Upstream commit d19189f70ba596798ea49166d2d1ef36a8df5289 ] Fixes: bus@c8834000: eth-phy-mux: {...} should not be valid under {'type': 'object'} Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-9-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index c3ac531c4f84..350022935052 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -759,7 +759,7 @@ }; }; - eth-phy-mux { + eth-phy-mux@55c { compatible = "mdio-mux-mmioreg", "mdio-mux"; #address-cells = <1>; #size-cells = <0>; From 269fd2fb043e01aaf1b59e730319397f56099edf Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:31 +0100 Subject: [PATCH 0147/1017] arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name [ Upstream commit 6bb506ed36968207a8832f0143ebc127f0770eef ] Fixes: adc-keys: 'update-button' does not match any of the regexes: '^button-', 'pinctrl-[0-9]+' Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-10-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi index c2480bab8d33..27e964bfa947 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi @@ -17,7 +17,7 @@ io-channel-names = "buttons"; keyup-threshold-microvolt = <1800000>; - update-button { + button-update { label = "update"; linux,code = ; press-threshold-microvolt = <1300000>; From c39c3ed4a3b9d4f1667f7966a60b3ec6abdacf37 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:33 +0100 Subject: [PATCH 0148/1017] arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name [ Upstream commit eee64d8fbbdaab72bbab3e462f3a7b742d20c8c2 ] Fixes: leds: status: {...} is not of type 'array' Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-12-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts index 9ef210f17b4a..393d3cb33b9e 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts @@ -18,7 +18,7 @@ leds { compatible = "gpio-leds"; - status { + led { label = "n1:white:status"; gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; default-state = "on"; From 4c37a37743a6bc52e79b758599552cdb18912d82 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 24 Jan 2023 11:34:34 +0100 Subject: [PATCH 0149/1017] arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name [ Upstream commit afdef3b188c934f79ad4b0a7bd8c692742f9b5af ] Fixes: leds: status: {...} is not of type 'array' Link: https://lore.kernel.org/r/20230124-b4-amlogic-bindings-fixups-v1-13-44351528957e@linaro.org Signed-off-by: Neil Armstrong Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts index e8394a8269ee..802faf7e4e3c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts @@ -16,7 +16,7 @@ leds { compatible = "gpio-leds"; - status { + led { gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>; default-state = "off"; color = ; From a451c1377aa89ab9b503b846cc1e6e434b2401d3 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 14 Jan 2023 16:56:45 -0600 Subject: [PATCH 0150/1017] arm64: dts: renesas: beacon-renesom: Fix gpio expander reference [ Upstream commit d7f9492dfc03153ac56ab59066a196558748f575 ] The board used to originally introduce the Beacon Embedded RZ/G2[M/N/H] boards had a GPIO expander with address 20, but this was changed when the final board went to production. The production boards changed both the part itself and the address. With the incorrect address, the LCD cannot come up. If the LCD fails, the rcar-du driver fails to come up, and that also breaks HDMI. Pre-release board were not shipped to the general public, so it should be safe to push this as a fix. Anyone with a production board would have video fail due to this GPIO expander change. Fixes: a1d8a344f1ca ("arm64: dts: renesas: Introduce r8a774a1-beacon-rzg2m-kit") Signed-off-by: Adam Ford Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230114225647.227972-1-aford173@gmail.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- .../dts/renesas/beacon-renesom-baseboard.dtsi | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi index 53e1d43cbecf..663adf79471b 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi @@ -399,20 +399,6 @@ }; }; - /* 0 - lcd_reset */ - /* 1 - lcd_pwr */ - /* 2 - lcd_select */ - /* 3 - backlight-enable */ - /* 4 - Touch_shdwn */ - /* 5 - LCD_H_pol */ - /* 6 - lcd_V_pol */ - gpio_exp1: gpio@20 { - compatible = "onnn,pca9654"; - reg = <0x20>; - gpio-controller; - #gpio-cells = <2>; - }; - touchscreen@26 { compatible = "ilitek,ili2117"; reg = <0x26>; @@ -445,6 +431,16 @@ }; }; }; + + gpio_exp1: gpio@70 { + compatible = "nxp,pca9538"; + reg = <0x70>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "lcd_reset", "lcd_pwr", "lcd_select", + "backlight-enable", "Touch_shdwn", + "LCD_H_pol", "lcd_V_pol"; + }; }; &lvds0 { From bbddc7c708704df61451e759bd3f530d68a86ee2 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 31 Dec 2022 16:58:54 -0600 Subject: [PATCH 0151/1017] ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference [ Upstream commit 2177d4ae971f79b4a9a3c411f2fb8ae6113d1430 ] The property named in the schema is 'enable-gpios', not 'enable-gpio'. This makes no difference at runtime, because the regulator is marked as always-on, but it breaks validation. Fixes: 4701fc6e5dd9 ("ARM: dts: sun8i: add FriendlyARM NanoPi Duo2") Reviewed-by: Andre Przywara Acked-by: Jernej Skrabec Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20221231225854.16320-2-samuel@sholland.org Signed-off-by: Jernej Skrabec Signed-off-by: Sasha Levin --- arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts index 6b149271ef13..8722fdf77ebc 100644 --- a/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts @@ -57,7 +57,7 @@ regulator-ramp-delay = <50>; /* 4ms */ enable-active-high; - enable-gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ gpios-states = <0x1>; states = <1100000 0>, <1300000 1>; From e874629c5fb77ac1a09190f0c2352791f5f8e844 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 23 Dec 2022 11:04:33 +0800 Subject: [PATCH 0152/1017] ARM: dts: imx7s: correct iomuxc gpr mux controller cells [ Upstream commit 0e3e1946606a2919b1dda9967ab2e1c5af2fedd6 ] Per binding doc reg-mux.yaml, the #mux-control-cells should be 1 Signed-off-by: Peng Fan Reviewed-by: Marco Felsch Fixes: 94a905a79f2c ("ARM: dts: imx7s: add multiplexer controls") Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx7s.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 9e1b0af0aa43..43b39ad9ddce 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -494,7 +494,7 @@ mux: mux-controller { compatible = "mmio-mux"; - #mux-control-cells = <0>; + #mux-control-cells = <1>; mux-reg-masks = <0x14 0x00000010>; }; From d7cf3864d781469cb8b323c6d8606890758afaee Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Mon, 28 Nov 2022 12:20:27 +0100 Subject: [PATCH 0153/1017] arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node [ Upstream commit 22925af785fa3470efdf566339616d801119d348 ] Specify #pwm-cells on pwm@11006000 to make it actually usable. Fixes: ae457b7679c4 ("arm64: dts: mt7622: add SoC and peripheral related device nodes") Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20221128112028.58021-2-angelogioacchino.delregno@collabora.com Signed-off-by: Matthias Brugger Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/mediatek/mt7622.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi index 7c6d871538a6..884930a5849a 100644 --- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -428,6 +428,7 @@ pwm: pwm@11006000 { compatible = "mediatek,mt7622-pwm"; reg = <0 0x11006000 0 0x1000>; + #pwm-cells = <2>; interrupts = ; clocks = <&topckgen CLK_TOP_PWM_SEL>, <&pericfg CLK_PERI_PWM_PD>, From 12bcc4ec54967c3169e702d1179c2b618039e4b5 Mon Sep 17 00:00:00 2001 From: Kemeng Shi Date: Wed, 18 Jan 2023 17:37:13 +0800 Subject: [PATCH 0154/1017] blk-mq: avoid sleep in blk_mq_alloc_request_hctx [ Upstream commit 6ee858a3d3270a68902d66bb47c151a83622535c ] Commit 1f5bd336b9150 ("blk-mq: add blk_mq_alloc_request_hctx") add blk_mq_alloc_request_hctx to send commands to a specific queue. If BLK_MQ_REQ_NOWAIT is not set in tag allocation, we may change to different hctx after sleep and get tag from unexpected hctx. So BLK_MQ_REQ_NOWAIT must be set in flags for blk_mq_alloc_request_hctx. After commit 600c3b0cea784 ("blk-mq: open code __blk_mq_alloc_request in blk_mq_alloc_request_hctx"), blk_mq_alloc_request_hctx return -EINVAL if both BLK_MQ_REQ_NOWAIT and BLK_MQ_REQ_RESERVED are not set instead of if BLK_MQ_REQ_NOWAIT is not set. So if BLK_MQ_REQ_NOWAIT is not set and BLK_MQ_REQ_RESERVED is set, blk_mq_alloc_request_hctx could alloc tag from unexpected hctx. I guess what we need here is that return -EINVAL if either BLK_MQ_REQ_NOWAIT or BLK_MQ_REQ_RESERVED is not set. Currently both BLK_MQ_REQ_NOWAIT and BLK_MQ_REQ_RESERVED will be set if specific hctx is needed in nvme_auth_submit, nvmf_connect_io_queue and nvmf_connect_admin_queue. Fix the potential BLK_MQ_REQ_NOWAIT missed case in future. Fixes: 600c3b0cea78 ("blk-mq: open code __blk_mq_alloc_request in blk_mq_alloc_request_hctx") Reviewed-by: Christoph Hellwig Signed-off-by: Kemeng Shi Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/blk-mq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index e37ba792902a..cf66de0f00fd 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -448,7 +448,8 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, * allocator for this for the rare use case of a command tied to * a specific queue. */ - if (WARN_ON_ONCE(!(flags & (BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED)))) + if (WARN_ON_ONCE(!(flags & BLK_MQ_REQ_NOWAIT)) || + WARN_ON_ONCE(!(flags & BLK_MQ_REQ_RESERVED))) return ERR_PTR(-EINVAL); if (hctx_idx >= q->nr_hw_queues) From 2c58012d9656491392cdf60191492874c11ecc43 Mon Sep 17 00:00:00 2001 From: Kemeng Shi Date: Wed, 18 Jan 2023 17:37:14 +0800 Subject: [PATCH 0155/1017] blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx [ Upstream commit c31e76bcc379182fe67a82c618493b7b8868c672 ] Commit 97889f9ac24f8 ("blk-mq: remove synchronize_rcu() from blk_mq_del_queue_tag_set()") remove handle of TAG_SHARED in restart, then shared_hctx_restart counted for how many hardware queues are marked for restart is removed too. Remove the stale comment that we still count hardware queues need restart. Fixes: 97889f9ac24f ("blk-mq: remove synchronize_rcu() from blk_mq_del_queue_tag_set()") Reviewed-by: Christoph Hellwig Signed-off-by: Kemeng Shi Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/blk-mq-sched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index 72e64ba661fc..862acb5a8452 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -45,8 +45,7 @@ void blk_mq_sched_assign_ioc(struct request *rq) } /* - * Mark a hardware queue as needing a restart. For shared queues, maintain - * a count of how many hardware queues are marked for restart. + * Mark a hardware queue as needing a restart. */ void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx) { From a33c33593b66d37d3eb4027a4f03645bde31262e Mon Sep 17 00:00:00 2001 From: Kemeng Shi Date: Wed, 18 Jan 2023 17:37:26 +0800 Subject: [PATCH 0156/1017] blk-mq: correct stale comment of .get_budget [ Upstream commit 01542f651a9f58a9b176c3d3dc3eefbacee53b78 ] Commit 88022d7201e96 ("blk-mq: don't handle failure in .get_budget") remove BLK_STS_RESOURCE return value and we only check if we can get the budget from .get_budget() now. Correct stale comment that ".get_budget() returns BLK_STS_NO_RESOURCE" to ".get_budget() fails to get the budget". Fixes: 88022d7201e9 ("blk-mq: don't handle failure in .get_budget") Signed-off-by: Kemeng Shi Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/blk-mq-sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index 862acb5a8452..7858c5a3535e 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -109,7 +109,7 @@ dispatch: /* * Only SCSI implements .get_budget and .put_budget, and SCSI restarts * its queue by itself in its completion handler, so we don't need to - * restart queue if .get_budget() returns BLK_STS_NO_RESOURCE. + * restart queue if .get_budget() fails to get the budget. * * Returns -EAGAIN if hctx->dispatch was found non-empty and run_work has to * be run again. This is necessary to avoid starving flushes. @@ -223,7 +223,7 @@ static struct blk_mq_ctx *blk_mq_next_ctx(struct blk_mq_hw_ctx *hctx, /* * Only SCSI implements .get_budget and .put_budget, and SCSI restarts * its queue by itself in its completion handler, so we don't need to - * restart queue if .get_budget() returns BLK_STS_NO_RESOURCE. + * restart queue if .get_budget() fails to get the budget. * * Returns -EAGAIN if hctx->dispatch was found non-empty and run_work has to * be run again. This is necessary to avoid starving flushes. From 72aebdac390bf0dc04c0385d2db7ee522f4ffa3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Thu, 8 Oct 2020 15:13:35 +0200 Subject: [PATCH 0157/1017] s390/dasd: Prepare for additional path event handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b72949328869dfd45f6452c2410647afd7db5f1a ] As more path events need to be handled for ECKD the current path verification infrastructure can be reused. Rename all path verifcation code to fit the more broadly based task of path event handling and put the path verification in a new separate function. Signed-off-by: Jan Höppner Signed-off-by: Stefan Haberland Reviewed-by: Stefan Haberland Reviewed-by: Cornelia Huck Signed-off-by: Jens Axboe Stable-dep-of: 460e9bed82e4 ("s390/dasd: Fix potential memleak in dasd_eckd_init()") Signed-off-by: Sasha Levin --- drivers/s390/block/dasd.c | 4 +- drivers/s390/block/dasd_eckd.c | 78 +++++++++++++++++++--------------- drivers/s390/block/dasd_int.h | 1 + 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index f4edfe383e9d..9f26f55e4988 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2128,8 +2128,8 @@ static void __dasd_device_check_path_events(struct dasd_device *device) if (device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM)) return; - rc = device->discipline->verify_path(device, - dasd_path_get_tbvpm(device)); + rc = device->discipline->pe_handler(device, + dasd_path_get_tbvpm(device)); if (rc) dasd_device_set_timer(device, 50); else diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 53d22975a32f..d1429936f38c 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -103,7 +103,7 @@ struct ext_pool_exhaust_work_data { }; /* definitions for the path verification worker */ -struct path_verification_work_data { +struct pe_handler_work_data { struct work_struct worker; struct dasd_device *device; struct dasd_ccw_req cqr; @@ -112,8 +112,8 @@ struct path_verification_work_data { int isglobal; __u8 tbvpm; }; -static struct path_verification_work_data *path_verification_worker; -static DEFINE_MUTEX(dasd_path_verification_mutex); +static struct pe_handler_work_data *pe_handler_worker; +static DEFINE_MUTEX(dasd_pe_handler_mutex); struct check_attention_work_data { struct work_struct worker; @@ -1219,7 +1219,7 @@ static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm) } static int rebuild_device_uid(struct dasd_device *device, - struct path_verification_work_data *data) + struct pe_handler_work_data *data) { struct dasd_eckd_private *private = device->private; __u8 lpm, opm = dasd_path_get_opm(device); @@ -1257,10 +1257,9 @@ static int rebuild_device_uid(struct dasd_device *device, return rc; } -static void do_path_verification_work(struct work_struct *work) +static void dasd_eckd_path_available_action(struct dasd_device *device, + struct pe_handler_work_data *data) { - struct path_verification_work_data *data; - struct dasd_device *device; struct dasd_eckd_private path_private; struct dasd_uid *uid; __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; @@ -1269,19 +1268,6 @@ static void do_path_verification_work(struct work_struct *work) char print_uid[60]; int rc; - data = container_of(work, struct path_verification_work_data, worker); - device = data->device; - - /* delay path verification until device was resumed */ - if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { - schedule_work(work); - return; - } - /* check if path verification already running and delay if so */ - if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) { - schedule_work(work); - return; - } opm = 0; npm = 0; ppm = 0; @@ -1418,30 +1404,54 @@ static void do_path_verification_work(struct work_struct *work) dasd_path_add_nohpfpm(device, hpfpm); spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); } +} + +static void do_pe_handler_work(struct work_struct *work) +{ + struct pe_handler_work_data *data; + struct dasd_device *device; + + data = container_of(work, struct pe_handler_work_data, worker); + device = data->device; + + /* delay path verification until device was resumed */ + if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { + schedule_work(work); + return; + } + /* check if path verification already running and delay if so */ + if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) { + schedule_work(work); + return; + } + + dasd_eckd_path_available_action(device, data); + clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags); dasd_put_device(device); if (data->isglobal) - mutex_unlock(&dasd_path_verification_mutex); + mutex_unlock(&dasd_pe_handler_mutex); else kfree(data); } -static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm) +static int dasd_eckd_pe_handler(struct dasd_device *device, __u8 lpm) { - struct path_verification_work_data *data; + struct pe_handler_work_data *data; data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA); if (!data) { - if (mutex_trylock(&dasd_path_verification_mutex)) { - data = path_verification_worker; + if (mutex_trylock(&dasd_pe_handler_mutex)) { + data = pe_handler_worker; data->isglobal = 1; - } else + } else { return -ENOMEM; + } } else { memset(data, 0, sizeof(*data)); data->isglobal = 0; } - INIT_WORK(&data->worker, do_path_verification_work); + INIT_WORK(&data->worker, do_pe_handler_work); dasd_get_device(device); data->device = device; data->tbvpm = lpm; @@ -6694,7 +6704,7 @@ static struct dasd_discipline dasd_eckd_discipline = { .check_device = dasd_eckd_check_characteristics, .uncheck_device = dasd_eckd_uncheck_device, .do_analysis = dasd_eckd_do_analysis, - .verify_path = dasd_eckd_verify_path, + .pe_handler = dasd_eckd_pe_handler, .basic_to_ready = dasd_eckd_basic_to_ready, .online_to_ready = dasd_eckd_online_to_ready, .basic_to_known = dasd_eckd_basic_to_known, @@ -6755,16 +6765,16 @@ dasd_eckd_init(void) GFP_KERNEL | GFP_DMA); if (!dasd_vol_info_req) return -ENOMEM; - path_verification_worker = kmalloc(sizeof(*path_verification_worker), - GFP_KERNEL | GFP_DMA); - if (!path_verification_worker) { + pe_handler_worker = kmalloc(sizeof(*pe_handler_worker), + GFP_KERNEL | GFP_DMA); + if (!pe_handler_worker) { kfree(dasd_reserve_req); kfree(dasd_vol_info_req); return -ENOMEM; } rawpadpage = (void *)__get_free_page(GFP_KERNEL); if (!rawpadpage) { - kfree(path_verification_worker); + kfree(pe_handler_worker); kfree(dasd_reserve_req); kfree(dasd_vol_info_req); return -ENOMEM; @@ -6773,7 +6783,7 @@ dasd_eckd_init(void) if (!ret) wait_for_device_probe(); else { - kfree(path_verification_worker); + kfree(pe_handler_worker); kfree(dasd_reserve_req); kfree(dasd_vol_info_req); free_page((unsigned long)rawpadpage); @@ -6785,7 +6795,7 @@ static void __exit dasd_eckd_cleanup(void) { ccw_driver_unregister(&dasd_eckd_driver); - kfree(path_verification_worker); + kfree(pe_handler_worker); kfree(dasd_reserve_req); free_page((unsigned long)rawpadpage); } diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 9d9685c25253..e8a06d85d6f7 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -299,6 +299,7 @@ struct dasd_discipline { * configuration. */ int (*verify_path)(struct dasd_device *, __u8); + int (*pe_handler)(struct dasd_device *, __u8); /* * Last things to do when a device is set online, and first things From a50e28d433acf22258f9f34831057387f04ef074 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Fri, 10 Feb 2023 01:02:53 +0100 Subject: [PATCH 0158/1017] s390/dasd: Fix potential memleak in dasd_eckd_init() [ Upstream commit 460e9bed82e49db1b823dcb4e421783854d86c40 ] `dasd_reserve_req` is allocated before `dasd_vol_info_req`, and it also needs to be freed before the error returns, just like the other cases in this function. Fixes: 9e12e54c7a8f ("s390/dasd: Handle out-of-space constraint") Signed-off-by: Qiheng Lin Link: https://lore.kernel.org/r/20221208133809.16796-1-linqiheng@huawei.com Signed-off-by: Stefan Haberland Link: https://lore.kernel.org/r/20230210000253.1644903-3-sth@linux.ibm.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/s390/block/dasd_eckd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index d1429936f38c..c6930c159d2a 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -6763,8 +6763,10 @@ dasd_eckd_init(void) return -ENOMEM; dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req), GFP_KERNEL | GFP_DMA); - if (!dasd_vol_info_req) + if (!dasd_vol_info_req) { + kfree(dasd_reserve_req); return -ENOMEM; + } pe_handler_worker = kmalloc(sizeof(*pe_handler_worker), GFP_KERNEL | GFP_DMA); if (!pe_handler_worker) { From 53dbbe36340d602017b435e67c3ce5f80ab9df98 Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Wed, 2 Mar 2022 19:34:33 +0100 Subject: [PATCH 0159/1017] sched/deadline,rt: Remove unused parameter from pick_next_[rt|dl]_entity() [ Upstream commit 821aecd09e5ad2f8d4c3d8195333d272b392f7d3 ] The `struct rq *rq` parameter isn't used. Remove it. Signed-off-by: Dietmar Eggemann Signed-off-by: Peter Zijlstra (Intel) Acked-by: Juri Lelli Link: https://lore.kernel.org/r/20220302183433.333029-7-dietmar.eggemann@arm.com Stable-dep-of: 7c4a5b89a0b5 ("sched/rt: pick_next_rt_entity(): check list_entry") Signed-off-by: Sasha Levin --- kernel/sched/deadline.c | 5 ++--- kernel/sched/rt.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index aaf98771f935..f59cb3e8a613 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1847,8 +1847,7 @@ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first) deadline_queue_push_tasks(rq); } -static struct sched_dl_entity *pick_next_dl_entity(struct rq *rq, - struct dl_rq *dl_rq) +static struct sched_dl_entity *pick_next_dl_entity(struct dl_rq *dl_rq) { struct rb_node *left = rb_first_cached(&dl_rq->root); @@ -1867,7 +1866,7 @@ static struct task_struct *pick_next_task_dl(struct rq *rq) if (!sched_dl_runnable(rq)) return NULL; - dl_se = pick_next_dl_entity(rq, dl_rq); + dl_se = pick_next_dl_entity(dl_rq); BUG_ON(!dl_se); p = dl_task_of(dl_se); set_next_task_dl(rq, p, true); diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index e6f22836c600..e1ce5d1868b5 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1605,8 +1605,7 @@ static inline void set_next_task_rt(struct rq *rq, struct task_struct *p, bool f rt_queue_push_tasks(rq); } -static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, - struct rt_rq *rt_rq) +static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq) { struct rt_prio_array *array = &rt_rq->active; struct sched_rt_entity *next = NULL; @@ -1628,7 +1627,7 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq) struct rt_rq *rt_rq = &rq->rt; do { - rt_se = pick_next_rt_entity(rq, rt_rq); + rt_se = pick_next_rt_entity(rt_rq); BUG_ON(!rt_se); rt_rq = group_rt_rq(rt_se); } while (rt_rq); From 80a1751730b302d8ab63a084b2fa52c820ad0273 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Mon, 6 Feb 2023 22:33:54 +0000 Subject: [PATCH 0160/1017] sched/rt: pick_next_rt_entity(): check list_entry [ Upstream commit 7c4a5b89a0b5a57a64b601775b296abf77a9fe97 ] Commit 326587b84078 ("sched: fix goto retry in pick_next_task_rt()") removed any path which could make pick_next_rt_entity() return NULL. However, BUG_ON(!rt_se) in _pick_next_task_rt() (the only caller of pick_next_rt_entity()) still checks the error condition, which can never happen, since list_entry() never returns NULL. Remove the BUG_ON check, and instead emit a warning in the only possible error condition here: the queue being empty which should never happen. Fixes: 326587b84078 ("sched: fix goto retry in pick_next_task_rt()") Signed-off-by: Pietro Borrello Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Phil Auld Reviewed-by: Steven Rostedt (Google) Link: https://lore.kernel.org/r/20230128-list-entry-null-check-sched-v3-1-b1a71bd1ac6b@diag.uniroma1.it Signed-off-by: Sasha Levin --- kernel/sched/rt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index e1ce5d1868b5..f690f901b6cc 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1616,6 +1616,8 @@ static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq) BUG_ON(idx >= MAX_RT_PRIO); queue = array->queue + idx; + if (SCHED_WARN_ON(list_empty(queue))) + return NULL; next = list_entry(queue->next, struct sched_rt_entity, run_list); return next; @@ -1628,7 +1630,8 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq) do { rt_se = pick_next_rt_entity(rt_rq); - BUG_ON(!rt_se); + if (unlikely(!rt_se)) + return NULL; rt_rq = group_rt_rq(rt_se); } while (rt_rq); From 895cb50196ab4bcd53959385aafec593bbd23755 Mon Sep 17 00:00:00 2001 From: silviazhao Date: Wed, 8 Feb 2023 16:27:22 +0800 Subject: [PATCH 0161/1017] x86/perf/zhaoxin: Add stepping check for ZXC [ Upstream commit fd636b6a9bc6034f2e5bb869658898a2b472c037 ] Some of Nano series processors will lead GP when accessing PMC fixed counter. Meanwhile, their hardware support for PMC has not announced externally. So exclude Nano CPUs from ZXC by checking stepping information. This is an unambiguous way to differentiate between ZXC and Nano CPUs. Following are Nano and ZXC FMS information: Nano FMS: Family=6, Model=F, Stepping=[0-A][C-D] ZXC FMS: Family=6, Model=F, Stepping=E-F OR Family=6, Model=0x19, Stepping=0-3 Fixes: 3a4ac121c2ca ("x86/perf: Add hardware performance events support for Zhaoxin CPU.") Reported-by: Arjan <8vvbbqzo567a@nospam.xutrox.com> Reported-by: Kevin Brace Signed-off-by: silviazhao Signed-off-by: Peter Zijlstra (Intel) Link: https://bugzilla.kernel.org/show_bug.cgi?id=212389 Signed-off-by: Sasha Levin --- arch/x86/events/zhaoxin/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/events/zhaoxin/core.c b/arch/x86/events/zhaoxin/core.c index e68827e604ad..e92734696030 100644 --- a/arch/x86/events/zhaoxin/core.c +++ b/arch/x86/events/zhaoxin/core.c @@ -541,7 +541,13 @@ __init int zhaoxin_pmu_init(void) switch (boot_cpu_data.x86) { case 0x06: - if (boot_cpu_data.x86_model == 0x0f || boot_cpu_data.x86_model == 0x19) { + /* + * Support Zhaoxin CPU from ZXC series, exclude Nano series through FMS. + * Nano FMS: Family=6, Model=F, Stepping=[0-A][C-D] + * ZXC FMS: Family=6, Model=F, Stepping=E-F OR Family=6, Model=0x19, Stepping=0-3 + */ + if ((boot_cpu_data.x86_model == 0x0f && boot_cpu_data.x86_stepping >= 0x0e) || + boot_cpu_data.x86_model == 0x19) { x86_pmu.max_period = x86_pmu.cntval_mask >> 1; From 0a82c1e0573b87bf32f96165a76d19e2ebd23c35 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 15 Feb 2023 12:18:01 -0500 Subject: [PATCH 0162/1017] block: bio-integrity: Copy flags when bio_integrity_payload is cloned [ Upstream commit b6a4bdcda430e3ca43bbb9cb1d4d4d34ebe15c40 ] Make sure to copy the flags when a bio_integrity_payload is cloned. Otherwise per-I/O properties such as IP checksum flag will not be passed down to the HBA driver. Since the integrity buffer is owned by the original bio, the BIP_BLOCK_INTEGRITY flag needs to be masked off to avoid a double free in the completion path. Fixes: aae7df50190a ("block: Integrity checksum flag") Fixes: b1f01388574c ("block: Relocate bio integrity flags") Reported-by: Saurav Kashyap Tested-by: Saurav Kashyap Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Chaitanya Kulkarni Link: https://lore.kernel.org/r/20230215171801.21062-1-martin.petersen@oracle.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/bio-integrity.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 4f6f140a44e0..a4cfc97275df 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -428,6 +428,7 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src, bip->bip_vcnt = bip_src->bip_vcnt; bip->bip_iter = bip_src->bip_iter; + bip->bip_flags = bip_src->bip_flags & ~BIP_BLOCK_INTEGRITY; return 0; } From efc8df970561ff708379b89b348e16d3b410cc7b Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Mon, 5 Dec 2022 06:14:41 +0000 Subject: [PATCH 0163/1017] wifi: rsi: Fix memory leak in rsi_coex_attach() [ Upstream commit 956fb851a6e19da5ab491e19c1bc323bb2c2cf6f ] The coex_cb needs to be freed when rsi_create_kthread() failed in rsi_coex_attach(). Fixes: 2108df3c4b18 ("rsi: add coex support") Signed-off-by: Yuan Can Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221205061441.114632-1-yuancan@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/rsi/rsi_91x_coex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rsi/rsi_91x_coex.c b/drivers/net/wireless/rsi/rsi_91x_coex.c index a0c5d02ae88c..7395359b43b7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_coex.c +++ b/drivers/net/wireless/rsi/rsi_91x_coex.c @@ -160,6 +160,7 @@ int rsi_coex_attach(struct rsi_common *common) rsi_coex_scheduler_thread, "Coex-Tx-Thread")) { rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__); + kfree(coex_cb); return -EINVAL; } return 0; From d85d0b1a6135bb218d140052e291a3f1292b976f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 22:14:09 +0800 Subject: [PATCH 0164/1017] wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 106031c1f4a850915190d7ec1026696282f9359b ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. All the SKBs have been dequeued from the old queue, so it's safe to enqueue these SKBs to a free queue, then free them after spin_unlock_irqrestore() at once. Compile tested only. Fixes: 5c99f04fec93 ("rtlwifi: rtl8723be: Update driver to match Realtek release of 06/28/14") Signed-off-by: Yang Yingliang Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207141411.46098-2-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 33ffc24d3675..c4ee65cc2d5e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -26,8 +26,10 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; unsigned long flags; + skb_queue_head_init(&free_list); spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); while (skb_queue_len(&ring->queue)) { struct rtl_tx_desc *entry = &ring->desc[ring->idx]; @@ -37,10 +39,12 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw) rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR), skb->len, DMA_TO_DEVICE); - kfree_skb(skb); + __skb_queue_tail(&free_list, skb); ring->idx = (ring->idx + 1) % ring->entries; } spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); } static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw, From 97018e737bd0d3391c3a8c6fcce652fa1dff64b7 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 22:14:10 +0800 Subject: [PATCH 0165/1017] wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 2611687fa7ffc84190f92292de0b80468de17220 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. All the SKBs have been dequeued from the old queue, so it's safe to enqueue these SKBs to a free queue, then free them after spin_unlock_irqrestore() at once. Compile tested only. Fixes: 7fe3b3abb5da ("rtlwifi: rtl8188ee: rtl8821ae: Fix a queue locking problem") Signed-off-by: Yang Yingliang Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207141411.46098-3-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c index 63f9ea21962f..335a3c9cdbab 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -68,8 +68,10 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; unsigned long flags; + skb_queue_head_init(&free_list); spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); while (skb_queue_len(&ring->queue)) { struct rtl_tx_desc *entry = &ring->desc[ring->idx]; @@ -79,10 +81,12 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw) rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR), skb->len, DMA_TO_DEVICE); - kfree_skb(skb); + __skb_queue_tail(&free_list, skb); ring->idx = (ring->idx + 1) % ring->entries; } spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); } static void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw) From 0e5b782c1c728546642a5d4e518a822cb7050a31 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 22:14:11 +0800 Subject: [PATCH 0166/1017] wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 313950c2114e7051c4e3020fd82495fa1fb526a8 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. All the SKBs have been dequeued from the old queue, so it's safe to enqueue these SKBs to a free queue, then free them after spin_unlock_irqrestore() at once. Compile tested only. Fixes: 5c99f04fec93 ("rtlwifi: rtl8723be: Update driver to match Realtek release of 06/28/14") Signed-off-by: Yang Yingliang Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207141411.46098-4-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c index 0748aedce2ad..ccbb082d5e92 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c @@ -30,8 +30,10 @@ static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; unsigned long flags; + skb_queue_head_init(&free_list); spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); while (skb_queue_len(&ring->queue)) { struct rtl_tx_desc *entry = &ring->desc[ring->idx]; @@ -41,10 +43,12 @@ static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw) rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR), skb->len, DMA_TO_DEVICE); - kfree_skb(skb); + __skb_queue_tail(&free_list, skb); ring->idx = (ring->idx + 1) % ring->entries; } spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); } static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw, From e9ef5631dd43d3cdcd55c2c7c6e0be9bff41552c Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 22:40:13 +0800 Subject: [PATCH 0167/1017] wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave() [ Upstream commit 0c1528675d7a9787cb516b64d8f6c0f6f8efcb48 ] It is not allowed to call consume_skb() from hardware interrupt context or with interrupts being disabled. So replace dev_kfree_skb() with dev_consume_skb_irq() under spin_lock_irqsave(). Compile tested only. Fixes: 4bc85c1324aa ("Revert "iwlwifi: split the drivers for agn and legacy devices 3945/4965"") Signed-off-by: Yang Yingliang Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207144013.70210-1-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlegacy/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index 0651a6a416d1..4b55779de00a 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -5176,7 +5176,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) memset(&il->current_ht_config, 0, sizeof(struct il_ht_config)); /* new association get rid of ibss beacon skb */ - dev_kfree_skb(il->beacon_skb); + dev_consume_skb_irq(il->beacon_skb); il->beacon_skb = NULL; il->timestamp = 0; @@ -5295,7 +5295,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) } spin_lock_irqsave(&il->lock, flags); - dev_kfree_skb(il->beacon_skb); + dev_consume_skb_irq(il->beacon_skb); il->beacon_skb = skb; timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; From 9c8f50c7433bdfba1588831c413136ecc3f29f99 Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Thu, 8 Dec 2022 20:14:48 +0800 Subject: [PATCH 0168/1017] wifi: libertas: fix memory leak in lbs_init_adapter() [ Upstream commit 16a03958618fb91bb1bc7077cf3211055162cc2f ] When kfifo_alloc() failed in lbs_init_adapter(), cmd buffer is not released. Add free memory to processing error path. Fixes: 7919b89c8276 ("libertas: convert libertas driver to use an event/cmdresp queue") Signed-off-by: Zhengchao Shao Reviewed-by: Jiri Pirko Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221208121448.2845986-1-shaozhengchao@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/libertas/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c index ee4cf3437e28..36237457d136 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -870,6 +870,7 @@ static int lbs_init_adapter(struct lbs_private *priv) ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); if (ret) { pr_err("Out of memory allocating event FIFO buffer\n"); + lbs_free_cmd_buffer(priv); goto out; } From 75f4eed70a519717ea91347370207e57b97a632f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 8 Dec 2022 22:35:17 +0800 Subject: [PATCH 0169/1017] wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave() [ Upstream commit 4c2005ac87685907b3719b4f40215b578efd27c4 ] It is not allowed to call kfree_skb() or consume_skb() from hardware interrupt context or with hardware interrupts being disabled. It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead. The difference between them is free reason, dev_kfree_skb_irq() means the SKB is dropped in error and dev_consume_skb_irq() means the SKB is consumed in normal. In this case, dev_kfree_skb() is called to free and drop the SKB when it's shutdown, so replace it with dev_kfree_skb_irq(). Compile tested only. Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") Signed-off-by: Yang Yingliang Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221208143517.2383424-1-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 2cb86c28d11f..f8b1871fe290 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -5184,7 +5184,7 @@ static void rtl8xxxu_queue_rx_urb(struct rtl8xxxu_priv *priv, pending = priv->rx_urb_pending_count; } else { skb = (struct sk_buff *)rx_urb->urb.context; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); usb_free_urb(&rx_urb->urb); } From d4fddfd7282f57c63c8099c246a4b852a0e7020c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 26 Oct 2020 22:29:53 +0100 Subject: [PATCH 0170/1017] rtlwifi: fix -Wpointer-sign warning [ Upstream commit ef41937631bfee855e2b406e1d536efdaa9ce512 ] There are thousands of warnings in a W=2 build from just one file: drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c:3788:15: warning: pointer targets in initialization of 'u8 *' {aka 'unsigned char *'} from 'char *' differ in signedness [-Wpointer-sign] Change the types to consistently use 'const char *' for the strings. Signed-off-by: Arnd Bergmann Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201026213040.3889546-6-arnd@kernel.org Stable-dep-of: 117dbeda22ec ("wifi: rtlwifi: Fix global-out-of-bounds bug in _rtl8812ae_phy_set_txpower_limit()") Signed-off-by: Sasha Levin --- .../wireless/realtek/rtlwifi/rtl8821ae/phy.c | 81 ++++++++++--------- .../realtek/rtlwifi/rtl8821ae/table.c | 4 +- .../realtek/rtlwifi/rtl8821ae/table.h | 4 +- 3 files changed, 45 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c index f41a7643b9c4..119e0f799826 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c @@ -1581,7 +1581,7 @@ static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw } /* string is in decimal */ -static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint) +static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint) { u16 i = 0; *pint = 0; @@ -1599,7 +1599,7 @@ static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint) return true; } -static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num) +static bool _rtl8812ae_eq_n_byte(const char *str1, const char *str2, u32 num) { if (num == 0) return false; @@ -1637,10 +1637,11 @@ static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, return channel_index; } -static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, - u8 *pband, u8 *pbandwidth, - u8 *prate_section, u8 *prf_path, - u8 *pchannel, u8 *ppower_limit) +static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, + const char *pregulation, + const char *pband, const char *pbandwidth, + const char *prate_section, const char *prf_path, + const char *pchannel, const char *ppower_limit) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &rtlpriv->phy; @@ -1648,8 +1649,8 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul u8 channel_index; s8 power_limit = 0, prev_power_limit, ret; - if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) || - !_rtl8812ae_get_integer_from_string((char *)ppower_limit, + if (!_rtl8812ae_get_integer_from_string(pchannel, &channel) || + !_rtl8812ae_get_integer_from_string(ppower_limit, &power_limit)) { rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Illegal index of pwr_lmt table [chnl %d][val %d]\n", @@ -1659,42 +1660,42 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul power_limit = power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit; - if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3)) + if (_rtl8812ae_eq_n_byte(pregulation, "FCC", 3)) regulation = 0; - else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3)) + else if (_rtl8812ae_eq_n_byte(pregulation, "MKK", 3)) regulation = 1; - else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4)) + else if (_rtl8812ae_eq_n_byte(pregulation, "ETSI", 4)) regulation = 2; - else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4)) + else if (_rtl8812ae_eq_n_byte(pregulation, "WW13", 4)) regulation = 3; - if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3)) + if (_rtl8812ae_eq_n_byte(prate_section, "CCK", 3)) rate_section = 0; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4)) + else if (_rtl8812ae_eq_n_byte(prate_section, "OFDM", 4)) rate_section = 1; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) && + _rtl8812ae_eq_n_byte(prf_path, "1T", 2)) rate_section = 2; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) && + _rtl8812ae_eq_n_byte(prf_path, "2T", 2)) rate_section = 3; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) && + _rtl8812ae_eq_n_byte(prf_path, "1T", 2)) rate_section = 4; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) && + _rtl8812ae_eq_n_byte(prf_path, "2T", 2)) rate_section = 5; - if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3)) + if (_rtl8812ae_eq_n_byte(pbandwidth, "20M", 3)) bandwidth = 0; - else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3)) + else if (_rtl8812ae_eq_n_byte(pbandwidth, "40M", 3)) bandwidth = 1; - else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3)) + else if (_rtl8812ae_eq_n_byte(pbandwidth, "80M", 3)) bandwidth = 2; - else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4)) + else if (_rtl8812ae_eq_n_byte(pbandwidth, "160M", 4)) bandwidth = 3; - if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) { + if (_rtl8812ae_eq_n_byte(pband, "2.4G", 4)) { ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G, channel); @@ -1718,7 +1719,7 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul regulation, bandwidth, rate_section, channel_index, rtlphy->txpwr_limit_2_4g[regulation][bandwidth] [rate_section][channel_index][RF90_PATH_A]); - } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) { + } else if (_rtl8812ae_eq_n_byte(pband, "5G", 2)) { ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G, channel); @@ -1749,10 +1750,10 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregul } static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw, - u8 *regulation, u8 *band, - u8 *bandwidth, u8 *rate_section, - u8 *rf_path, u8 *channel, - u8 *power_limit) + const char *regulation, const char *band, + const char *bandwidth, const char *rate_section, + const char *rf_path, const char *channel, + const char *power_limit) { _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth, rate_section, rf_path, channel, @@ -1765,7 +1766,7 @@ static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtlpriv); u32 i = 0; u32 array_len; - u8 **array; + const char **array; if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN; @@ -1778,13 +1779,13 @@ static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw) rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); for (i = 0; i < array_len; i += 7) { - u8 *regulation = array[i]; - u8 *band = array[i+1]; - u8 *bandwidth = array[i+2]; - u8 *rate = array[i+3]; - u8 *rf_path = array[i+4]; - u8 *chnl = array[i+5]; - u8 *val = array[i+6]; + const char *regulation = array[i]; + const char *band = array[i+1]; + const char *bandwidth = array[i+2]; + const char *rate = array[i+3]; + const char *rf_path = array[i+4]; + const char *chnl = array[i+5]; + const char *val = array[i+6]; _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band, bandwidth, rate, rf_path, diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c index ed72a2aeb6c8..fcaaf664cbec 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c @@ -2894,7 +2894,7 @@ u32 RTL8821AE_AGC_TAB_1TARRAYLEN = ARRAY_SIZE(RTL8821AE_AGC_TAB_ARRAY); * TXPWR_LMT.TXT ******************************************************************************/ -u8 *RTL8812AE_TXPWR_LMT[] = { +const char *RTL8812AE_TXPWR_LMT[] = { "FCC", "2.4G", "20M", "CCK", "1T", "01", "36", "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32", "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", @@ -3463,7 +3463,7 @@ u8 *RTL8812AE_TXPWR_LMT[] = { u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8812AE_TXPWR_LMT); -u8 *RTL8821AE_TXPWR_LMT[] = { +const char *RTL8821AE_TXPWR_LMT[] = { "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32", "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h index 540159c25078..76c62b7c0fb2 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h @@ -28,7 +28,7 @@ extern u32 RTL8821AE_AGC_TAB_ARRAY[]; extern u32 RTL8812AE_AGC_TAB_1TARRAYLEN; extern u32 RTL8812AE_AGC_TAB_ARRAY[]; extern u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN; -extern u8 *RTL8812AE_TXPWR_LMT[]; +extern const char *RTL8812AE_TXPWR_LMT[]; extern u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN; -extern u8 *RTL8821AE_TXPWR_LMT[]; +extern const char *RTL8821AE_TXPWR_LMT[]; #endif From 1e950b9a841bc96e98ee25680d5c7aa305120be1 Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Mon, 12 Dec 2022 10:58:12 +0800 Subject: [PATCH 0171/1017] wifi: rtlwifi: Fix global-out-of-bounds bug in _rtl8812ae_phy_set_txpower_limit() [ Upstream commit 117dbeda22ec5ea0918254d03b540ef8b8a64d53 ] There is a global-out-of-bounds reported by KASAN: BUG: KASAN: global-out-of-bounds in _rtl8812ae_eq_n_byte.part.0+0x3d/0x84 [rtl8821ae] Read of size 1 at addr ffffffffa0773c43 by task NetworkManager/411 CPU: 6 PID: 411 Comm: NetworkManager Tainted: G D 6.1.0-rc8+ #144 e15588508517267d37 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), Call Trace: ... kasan_report+0xbb/0x1c0 _rtl8812ae_eq_n_byte.part.0+0x3d/0x84 [rtl8821ae] rtl8821ae_phy_bb_config.cold+0x346/0x641 [rtl8821ae] rtl8821ae_hw_init+0x1f5e/0x79b0 [rtl8821ae] ... The root cause of the problem is that the comparison order of "prate_section" in _rtl8812ae_phy_set_txpower_limit() is wrong. The _rtl8812ae_eq_n_byte() is used to compare the first n bytes of the two strings from tail to head, which causes the problem. In the _rtl8812ae_phy_set_txpower_limit(), it was originally intended to meet this requirement by carefully designing the comparison order. For example, "pregulation" and "pbandwidth" are compared in order of length from small to large, first is 3 and last is 4. However, the comparison order of "prate_section" dose not obey such order requirement, therefore when "prate_section" is "HT", when comparing from tail to head, it will lead to access out of bounds in _rtl8812ae_eq_n_byte(). As mentioned above, the _rtl8812ae_eq_n_byte() has the same function as strcmp(), so just strcmp() is enough. Fix it by removing _rtl8812ae_eq_n_byte() and use strcmp() barely. Although it can be fixed by adjusting the comparison order of "prate_section", this may cause the value of "rate_section" to not be from 0 to 5. In addition, commit "21e4b0726dc6" not only moved driver from staging to regular tree, but also added setting txpower limit function during the driver config phase, so the problem was introduced by this commit. Fixes: 21e4b0726dc6 ("rtlwifi: rtl8821ae: Move driver from staging to regular tree") Signed-off-by: Li Zetao Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221212025812.1541311-1-lizetao1@huawei.com Signed-off-by: Sasha Levin --- .../wireless/realtek/rtlwifi/rtl8821ae/phy.c | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c index 119e0f799826..c0c06ab6d3e7 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c @@ -1599,18 +1599,6 @@ static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint) return true; } -static bool _rtl8812ae_eq_n_byte(const char *str1, const char *str2, u32 num) -{ - if (num == 0) - return false; - while (num > 0) { - num--; - if (str1[num] != str2[num]) - return false; - } - return true; -} - static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, u8 band, u8 channel) { @@ -1660,42 +1648,42 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, power_limit = power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit; - if (_rtl8812ae_eq_n_byte(pregulation, "FCC", 3)) + if (strcmp(pregulation, "FCC") == 0) regulation = 0; - else if (_rtl8812ae_eq_n_byte(pregulation, "MKK", 3)) + else if (strcmp(pregulation, "MKK") == 0) regulation = 1; - else if (_rtl8812ae_eq_n_byte(pregulation, "ETSI", 4)) + else if (strcmp(pregulation, "ETSI") == 0) regulation = 2; - else if (_rtl8812ae_eq_n_byte(pregulation, "WW13", 4)) + else if (strcmp(pregulation, "WW13") == 0) regulation = 3; - if (_rtl8812ae_eq_n_byte(prate_section, "CCK", 3)) + if (strcmp(prate_section, "CCK") == 0) rate_section = 0; - else if (_rtl8812ae_eq_n_byte(prate_section, "OFDM", 4)) + else if (strcmp(prate_section, "OFDM") == 0) rate_section = 1; - else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) && - _rtl8812ae_eq_n_byte(prf_path, "1T", 2)) + else if (strcmp(prate_section, "HT") == 0 && + strcmp(prf_path, "1T") == 0) rate_section = 2; - else if (_rtl8812ae_eq_n_byte(prate_section, "HT", 2) && - _rtl8812ae_eq_n_byte(prf_path, "2T", 2)) + else if (strcmp(prate_section, "HT") == 0 && + strcmp(prf_path, "2T") == 0) rate_section = 3; - else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) && - _rtl8812ae_eq_n_byte(prf_path, "1T", 2)) + else if (strcmp(prate_section, "VHT") == 0 && + strcmp(prf_path, "1T") == 0) rate_section = 4; - else if (_rtl8812ae_eq_n_byte(prate_section, "VHT", 3) && - _rtl8812ae_eq_n_byte(prf_path, "2T", 2)) + else if (strcmp(prate_section, "VHT") == 0 && + strcmp(prf_path, "2T") == 0) rate_section = 5; - if (_rtl8812ae_eq_n_byte(pbandwidth, "20M", 3)) + if (strcmp(pbandwidth, "20M") == 0) bandwidth = 0; - else if (_rtl8812ae_eq_n_byte(pbandwidth, "40M", 3)) + else if (strcmp(pbandwidth, "40M") == 0) bandwidth = 1; - else if (_rtl8812ae_eq_n_byte(pbandwidth, "80M", 3)) + else if (strcmp(pbandwidth, "80M") == 0) bandwidth = 2; - else if (_rtl8812ae_eq_n_byte(pbandwidth, "160M", 4)) + else if (strcmp(pbandwidth, "160M") == 0) bandwidth = 3; - if (_rtl8812ae_eq_n_byte(pband, "2.4G", 4)) { + if (strcmp(pband, "2.4G") == 0) { ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G, channel); @@ -1719,7 +1707,7 @@ static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, regulation, bandwidth, rate_section, channel_index, rtlphy->txpwr_limit_2_4g[regulation][bandwidth] [rate_section][channel_index][RF90_PATH_A]); - } else if (_rtl8812ae_eq_n_byte(pband, "5G", 2)) { + } else if (strcmp(pband, "5G") == 0) { ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G, channel); From 3938f01405d61fde44b25a960c2d6cc851c80467 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Mon, 12 Dec 2022 13:15:03 -0800 Subject: [PATCH 0172/1017] libbpf: Fix btf__align_of() by taking into account field offsets [ Upstream commit 25a4481b4136af7794e1df2d6c90ed2f354d60ce ] btf__align_of() is supposed to be return alignment requirement of a requested BTF type. For STRUCT/UNION it doesn't always return correct value, because it calculates alignment only based on field types. But for packed structs this is not enough, we need to also check field offsets and struct size. If field offset isn't aligned according to field type's natural alignment, then struct must be packed. Similarly, if struct size is not a multiple of struct's natural alignment, then struct must be packed as well. This patch fixes this issue precisely by additionally checking these conditions. Fixes: 3d208f4ca111 ("libbpf: Expose btf__align_of() API") Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20221212211505.558851-5-andrii@kernel.org Signed-off-by: Sasha Levin --- tools/lib/bpf/btf.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index e6f644cdc9f1..f7c48b1fb3a0 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -614,8 +614,21 @@ int btf__align_of(const struct btf *btf, __u32 id) if (align <= 0) return align; max_align = max(max_align, align); + + /* if field offset isn't aligned according to field + * type's alignment, then struct must be packed + */ + if (btf_member_bitfield_size(t, i) == 0 && + (m->offset % (8 * align)) != 0) + return 1; } + /* if struct/union size isn't a multiple of its alignment, + * then struct must be packed + */ + if ((t->size % max_align) != 0) + return 1; + return max_align; } default: From 841ae9b924f4e7ff3bfa887fafb113a6665d01ff Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 8 Dec 2022 22:38:26 +0800 Subject: [PATCH 0173/1017] wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave() [ Upstream commit 45fc6d7461f18df2f238caf0cbc5acc4163203d1 ] It is not allowed to call kfree_skb() or consume_skb() from hardware interrupt context or with hardware interrupts being disabled. It should use dev_kfree_skb_irq() or dev_consume_skb_irq() instead. The difference between them is free reason, dev_kfree_skb_irq() means the SKB is dropped in error and dev_consume_skb_irq() means the SKB is consumed in normal. In this case, dev_kfree_skb() is called to free and drop the SKB when it's reset, so replace it with dev_kfree_skb_irq(). Compile tested only. Fixes: 43f66a6ce8da ("Add ipw2200 wireless driver.") Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221208143826.2385218-1-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index ada6ce32c1f1..df28e4a05e14 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -3444,7 +3444,7 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv, dma_unmap_single(&priv->pci_dev->dev, rxq->pool[i].dma_addr, IPW_RX_BUF_SIZE, DMA_FROM_DEVICE); - dev_kfree_skb(rxq->pool[i].skb); + dev_kfree_skb_irq(rxq->pool[i].skb); rxq->pool[i].skb = NULL; } list_add_tail(&rxq->pool[i].list, &rxq->rx_used); From 8a2eb9d9d0c1535bc8e22840193bff4cdcac878b Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Fri, 9 Dec 2022 09:24:22 +0800 Subject: [PATCH 0174/1017] wifi: ipw2200: fix memory leak in ipw_wdev_init() [ Upstream commit 9fe21dc626117fb44a8eb393713a86a620128ce3 ] In the error path of ipw_wdev_init(), exception value is returned, and the memory applied for in the function is not released. Also the memory is not released in ipw_pci_probe(). As a result, memory leakage occurs. So memory release needs to be added to the error path of ipw_wdev_init(). Fixes: a3caa99e6c68 ("libipw: initiate cfg80211 API conversion (v2)") Signed-off-by: Zhengchao Shao Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221209012422.182669-1-shaozhengchao@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index df28e4a05e14..bb728fb24b8a 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -11400,9 +11400,14 @@ static int ipw_wdev_init(struct net_device *dev) set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); /* With that information in place, we can now register the wiphy... */ - if (wiphy_register(wdev->wiphy)) - rc = -EIO; + rc = wiphy_register(wdev->wiphy); + if (rc) + goto out; + + return 0; out: + kfree(priv->ieee->a_band.channels); + kfree(priv->ieee->bg_band.channels); return rc; } From a1e94fb4d09d0fcfeaa73aa49d787f06c42db7ee Mon Sep 17 00:00:00 2001 From: Zhang Changzhong Date: Thu, 17 Nov 2022 19:36:03 +0800 Subject: [PATCH 0175/1017] wifi: wilc1000: fix potential memory leak in wilc_mac_xmit() [ Upstream commit deb962ec9e1c9a81babd3d37542ad4bd6ac3396e ] The wilc_mac_xmit() returns NETDEV_TX_OK without freeing skb, add dev_kfree_skb() to fix it. Compile tested only. Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver") Signed-off-by: Zhang Changzhong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1668684964-48622-1-git-send-email-zhangchangzhong@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/microchip/wilc1000/netdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 20615c7ec168..c508f429984a 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -684,6 +684,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) if (skb->dev != ndev) { netdev_err(ndev, "Packet not destined to this device\n"); + dev_kfree_skb(skb); return NETDEV_TX_OK; } From e08e6812efb6a8c676e733de0518594d1517e0d9 Mon Sep 17 00:00:00 2001 From: Zhang Changzhong Date: Thu, 17 Nov 2022 19:33:01 +0800 Subject: [PATCH 0176/1017] wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit() [ Upstream commit 212fde3fe76e962598ce1d47b97cc78afdfc71b3 ] The brcmf_netdev_start_xmit() returns NETDEV_TX_OK without freeing skb in case of pskb_expand_head() fails, add dev_kfree_skb() to fix it. Compile tested only. Fixes: 270a6c1f65fe ("brcmfmac: rework headroom check in .start_xmit()") Signed-off-by: Zhang Changzhong Reviewed-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1668684782-47422-1-git-send-email-zhangchangzhong@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index c8e1d505f7b5..3d544eedc1a3 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -333,6 +333,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, bphy_err(drvr, "%s: failed to expand headroom\n", brcmf_ifname(ifp)); atomic_inc(&drvr->bus_if->stats.pktcow_failed); + dev_kfree_skb(skb); goto done; } } From b4b4447481dbdffb0220632b4ba3be397b1d2676 Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Wed, 7 Dec 2022 09:31:14 +0800 Subject: [PATCH 0177/1017] wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid() [ Upstream commit b9f420032f2ba1e634b22ca7b433e5c40ea663af ] After the DMA buffer is mapped to a physical address, address is stored in pktids in brcmf_msgbuf_alloc_pktid(). Then, pktids is parsed in brcmf_msgbuf_get_pktid()/brcmf_msgbuf_release_array() to obtain physaddr and later unmap the DMA buffer. But when count is always equal to pktids->array_size, physaddr isn't stored in pktids and the DMA buffer will not be unmapped anyway. Fixes: 9a1bb60250d2 ("brcmfmac: Adding msgbuf protocol.") Signed-off-by: Zhengchao Shao Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207013114.1748936-1-shaozhengchao@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index 7c8e08ee8f0f..bd3b234b7803 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -346,8 +346,11 @@ brcmf_msgbuf_alloc_pktid(struct device *dev, count++; } while (count < pktids->array_size); - if (count == pktids->array_size) + if (count == pktids->array_size) { + dma_unmap_single(dev, *physaddr, skb->len - data_offset, + pktids->direction); return -ENOMEM; + } array[*idx].data_offset = data_offset; array[*idx].physaddr = *physaddr; From 0258757caab5e987b725243cfef0c4a105654db2 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 23:00:05 +0800 Subject: [PATCH 0178/1017] wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 9388ce97b98216833c969191ee6df61a7201d797 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. So replace kfree_skb() with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile tested only. Fixes: fc75122fabb5 ("libertas_tf: use irqsave() in USB's complete callback") Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207150008.111743-2-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c index ecce8b56f8a2..2c45ef6e0407 100644 --- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -613,7 +613,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, spin_lock_irqsave(&priv->driver_lock, flags); memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN, recvlength - MESSAGE_HEADER_LEN); - kfree_skb(skb); + dev_kfree_skb_irq(skb); lbtf_cmd_response_rx(priv); spin_unlock_irqrestore(&priv->driver_lock, flags); } From 647230e71e1c306810996966721ad581899d5b2c Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 23:00:06 +0800 Subject: [PATCH 0179/1017] wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 3968e81ba644f10a7d45bae2539560db9edac501 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. So replace kfree_skb() with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile tested only. Fixes: a3128feef6d5 ("libertas: use irqsave() in USB's complete callback") Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207150008.111743-3-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/libertas/if_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index 32fdc4150b60..2240b4db8c03 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -637,7 +637,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN); memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN, priv->resp_len[i]); - kfree_skb(skb); + dev_kfree_skb_irq(skb); lbs_notify_command_response(priv, i); spin_unlock_irqrestore(&priv->driver_lock, flags); From 2ddb1820bdacbccc0f296c70b3344308ed2c7623 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 23:00:07 +0800 Subject: [PATCH 0180/1017] wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit f393df151540bf858effbd29ff572ab94e76a4c4 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. So replace kfree_skb() with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile tested only. Fixes: d2e7b3425c47 ("libertas: disable functionality when interface is down") Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207150008.111743-4-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/libertas/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c index 36237457d136..1c56cc2742b0 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -217,7 +217,7 @@ int lbs_stop_iface(struct lbs_private *priv) spin_lock_irqsave(&priv->driver_lock, flags); priv->iface_running = false; - kfree_skb(priv->currenttxskb); + dev_kfree_skb_irq(priv->currenttxskb); priv->currenttxskb = NULL; priv->tx_pending_len = 0; spin_unlock_irqrestore(&priv->driver_lock, flags); From 93b8809be5ba7d28218fd5561560c10cf058e998 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 23:00:08 +0800 Subject: [PATCH 0181/1017] wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 708a49a64237f19bd404852f297aaadbc9e7fee0 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. So replace kfree_skb() with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile tested only. Fixes: f52b041aed77 ("libertas: Add spinlock to avoid race condition") Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207150008.111743-5-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/libertas/cmdresp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/libertas/cmdresp.c b/drivers/net/wireless/marvell/libertas/cmdresp.c index cb515c5584c1..74cb7551f427 100644 --- a/drivers/net/wireless/marvell/libertas/cmdresp.c +++ b/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -48,7 +48,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv, /* Free Tx and Rx packets */ spin_lock_irqsave(&priv->driver_lock, flags); - kfree_skb(priv->currenttxskb); + dev_kfree_skb_irq(priv->currenttxskb); priv->currenttxskb = NULL; priv->tx_pending_len = 0; spin_unlock_irqrestore(&priv->driver_lock, flags); From f6e429cde9ead0c42aba9fee5dc640fa9ba31ad0 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 7 Dec 2022 23:04:53 +0800 Subject: [PATCH 0182/1017] wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave() [ Upstream commit 44bacbdf9066c590423259dbd6d520baac99c1a8 ] It is not allowed to call kfree_skb() from hardware interrupt context or with interrupts being disabled. So replace kfree_skb() with dev_kfree_skb_irq() under spin_lock_irqsave(). Compile tested only. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yang Yingliang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221207150453.114742-1-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/wl3501_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index ff1701adbb17..ccf6344ed6fd 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1330,7 +1330,7 @@ static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb, } else { ++dev->stats.tx_packets; dev->stats.tx_bytes += skb->len; - kfree_skb(skb); + dev_kfree_skb_irq(skb); if (this->tx_buffer_cnt < 2) netif_stop_queue(dev); From 6e43b2d9d166286c232d91302906108063e33181 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 19 Dec 2022 21:40:40 -0800 Subject: [PATCH 0183/1017] crypto: x86/ghash - fix unaligned access in ghash_setkey() [ Upstream commit 116db2704c193fff6d73ea6c2219625f0c9bdfc8 ] The key can be unaligned, so use the unaligned memory access helpers. Fixes: 8ceee72808d1 ("crypto: ghash-clmulni-intel - use C implementation for setkey()") Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- arch/x86/crypto/ghash-clmulni-intel_glue.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index 1f1a95f3dd0c..c0ab0ff4af65 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -19,6 +19,7 @@ #include #include #include +#include #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -54,15 +55,14 @@ static int ghash_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) { struct ghash_ctx *ctx = crypto_shash_ctx(tfm); - be128 *x = (be128 *)key; u64 a, b; if (keylen != GHASH_BLOCK_SIZE) return -EINVAL; /* perform multiplication by 'x' in GF(2^128) */ - a = be64_to_cpu(x->a); - b = be64_to_cpu(x->b); + a = get_unaligned_be64(key); + b = get_unaligned_be64(key + 8); ctx->shash.a = (b << 1) | (a >> 63); ctx->shash.b = (a << 1) | (b >> 63); From 5562585c4aa26ba4f044c52a0af244b4b772bfe5 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 15 Dec 2022 09:51:20 -0600 Subject: [PATCH 0184/1017] ACPICA: Drop port I/O validation for some regions [ Upstream commit e1d9148582ab2c3dada5c5cf8ca7531ca269fee5 ] Microsoft introduced support in Windows XP for blocking port I/O to various regions. For Windows compatibility ACPICA has adopted the same protections and will disallow writes to those (presumably) the same regions. On some systems the AML included with the firmware will issue 4 byte long writes to 0x80. These writes aren't making it over because of this blockage. The first 4 byte write attempt is rejected, and then subsequently 1 byte at a time each offset is tried. The first at 0x80 works, but then the next 3 bytes are rejected. This manifests in bizarre failures for devices that expected the AML to write all 4 bytes. Trying the same AML on Windows 10 or 11 doesn't hit this failure and all 4 bytes are written. Either some of these regions were wrong or some point after Windows XP some of these regions blocks have been lifted. In the last 15 years there doesn't seem to be any reports popping up of this error in the Windows event viewer anymore. There is no documentation at Microsoft's developer site indicating that Windows ACPI interpreter blocks these regions. Between the lack of documentation and the fact that the writes actually do work in Windows 10 and 11, it's quite likely Windows doesn't actually enforce this anymore. So to help the issue, only enforce Windows XP specific entries if the latest _OSI supported is Windows XP. Continue to enforce the ALWAYS_ILLEGAL entries. Link: https://github.com/acpica/acpica/pull/817 Fixes: 7f0719039085 ("ACPICA: New: I/O port protection") Signed-off-by: Mario Limonciello Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpica/hwvalid.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index b2ca7dfd3fc9..0cc4de3f71d5 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -23,8 +23,8 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width); * * The table is used to implement the Microsoft port access rules that * first appeared in Windows XP. Some ports are always illegal, and some - * ports are only illegal if the BIOS calls _OSI with a win_XP string or - * later (meaning that the BIOS itelf is post-XP.) + * ports are only illegal if the BIOS calls _OSI with nothing newer than + * the specific _OSI strings. * * This provides ACPICA with the desired port protections and * Microsoft compatibility. @@ -145,7 +145,8 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) /* Port illegality may depend on the _OSI calls made by the BIOS */ - if (acpi_gbl_osi_data >= port_info->osi_dependency) { + if (port_info->osi_dependency == ACPI_ALWAYS_ILLEGAL || + acpi_gbl_osi_data == port_info->osi_dependency) { ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)\n", ACPI_FORMAT_UINT64(address), From a4935bb734448a71e4eae539b1d7768f6ed134ac Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Sat, 19 Nov 2022 17:25:03 +0800 Subject: [PATCH 0185/1017] genirq: Fix the return type of kstat_cpu_irqs_sum() [ Upstream commit 47904aed898a08f028572b9b5a5cc101ddfb2d82 ] The type of member ->irqs_sum is unsigned long, but kstat_cpu_irqs_sum() returns int, which can result in truncation. Therefore, change the kstat_cpu_irqs_sum() function's return value to unsigned long to avoid truncation. Fixes: f2c66cd8eedd ("/proc/stat: scalability of irq num per cpu") Reported-by: Elliott, Robert (Servers) Signed-off-by: Zhen Lei Cc: Tejun Heo Cc: "Peter Zijlstra (Intel)" Cc: Josh Don Cc: Andrew Morton Reviewed-by: Frederic Weisbecker Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- include/linux/kernel_stat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 8fff3500d50e..1160e20995a0 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -73,7 +73,7 @@ extern unsigned int kstat_irqs_usr(unsigned int irq); /* * Number of interrupts per cpu, since bootup */ -static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu) +static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu) { return kstat_cpu(cpu).irqs_sum; } From b02b6bb83c683efb69f62f709ac1b064a176ac32 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 25 Nov 2022 14:54:58 +0100 Subject: [PATCH 0186/1017] rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose [ Upstream commit e4e1e8089c5fd948da12cb9f4adc93821036945f ] Make sure we don't need to look again into the depths of git blame in order not to miss a subtle part about how rcu-tasks is dealing with exiting tasks. Suggested-by: Boqun Feng Suggested-by: Neeraj Upadhyay Suggested-by: Paul E. McKenney Cc: Oleg Nesterov Cc: Lai Jiangshan Cc: Eric W. Biederman Signed-off-by: Frederic Weisbecker Signed-off-by: Paul E. McKenney Stable-dep-of: 28319d6dc5e2 ("rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()") Signed-off-by: Sasha Levin --- kernel/rcu/tasks.h | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 8b51e6a5b386..372644126b0d 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -416,11 +416,21 @@ static void rcu_tasks_pertask(struct task_struct *t, struct list_head *hop) static void rcu_tasks_postscan(struct list_head *hop) { /* - * Wait for tasks that are in the process of exiting. This - * does only part of the job, ensuring that all tasks that were - * previously exiting reach the point where they have disabled - * preemption, allowing the later synchronize_rcu() to finish - * the job. + * Exiting tasks may escape the tasklist scan. Those are vulnerable + * until their final schedule() with TASK_DEAD state. To cope with + * this, divide the fragile exit path part in two intersecting + * read side critical sections: + * + * 1) An _SRCU_ read side starting before calling exit_notify(), + * which may remove the task from the tasklist, and ending after + * the final preempt_disable() call in do_exit(). + * + * 2) An _RCU_ read side starting with the final preempt_disable() + * call in do_exit() and ending with the final call to schedule() + * with TASK_DEAD state. + * + * This handles the part 1). And postgp will handle part 2) with a + * call to synchronize_rcu(). */ synchronize_srcu(&tasks_rcu_exit_srcu); } @@ -487,7 +497,10 @@ static void rcu_tasks_postgp(struct rcu_tasks *rtp) * * In addition, this synchronize_rcu() waits for exiting tasks * to complete their final preempt_disable() region of execution, - * cleaning up after the synchronize_srcu() above. + * cleaning up after synchronize_srcu(&tasks_rcu_exit_srcu), + * enforcing the whole region before tasklist removal until + * the final schedule() with TASK_DEAD state to be an RCU TASKS + * read side critical section. */ synchronize_rcu(); } @@ -576,7 +589,11 @@ static void show_rcu_tasks_classic_gp_kthread(void) } #endif /* #ifndef CONFIG_TINY_RCU */ -/* Do the srcu_read_lock() for the above synchronize_srcu(). */ +/* + * Contribute to protect against tasklist scan blind spot while the + * task is exiting and may be removed from the tasklist. See + * corresponding synchronize_srcu() for further details. + */ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu) { preempt_disable(); @@ -584,7 +601,11 @@ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu) preempt_enable(); } -/* Do the srcu_read_unlock() for the above synchronize_srcu(). */ +/* + * Contribute to protect against tasklist scan blind spot while the + * task is exiting and may be removed from the tasklist. See + * corresponding synchronize_srcu() for further details. + */ void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu) { struct task_struct *t = current; From ad410f64f7ab189e71192b1edb5786ffbe59c622 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 25 Nov 2022 14:54:59 +0100 Subject: [PATCH 0187/1017] rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls [ Upstream commit 44757092958bdd749775022f915b7ac974384c2a ] Ever since the following commit: 5a41344a3d83 ("srcu: Simplify __srcu_read_unlock() via this_cpu_dec()") SRCU doesn't rely anymore on preemption to be disabled in order to modify the per-CPU counter. And even then it used to be done from the API itself. Therefore and after checking further, it appears to be safe to remove the preemption disablement around __srcu_read_[un]lock() in exit_tasks_rcu_start() and exit_tasks_rcu_finish() Suggested-by: Boqun Feng Suggested-by: Paul E. McKenney Suggested-by: Neeraj Upadhyay Cc: Lai Jiangshan Signed-off-by: Frederic Weisbecker Signed-off-by: Paul E. McKenney Stable-dep-of: 28319d6dc5e2 ("rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()") Signed-off-by: Sasha Levin --- kernel/rcu/tasks.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 372644126b0d..c4af3c05663f 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -596,9 +596,7 @@ static void show_rcu_tasks_classic_gp_kthread(void) */ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu) { - preempt_disable(); current->rcu_tasks_idx = __srcu_read_lock(&tasks_rcu_exit_srcu); - preempt_enable(); } /* @@ -610,9 +608,7 @@ void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu) { struct task_struct *t = current; - preempt_disable(); __srcu_read_unlock(&tasks_rcu_exit_srcu, t->rcu_tasks_idx); - preempt_enable(); exit_tasks_rcu_finish_trace(t); } From 1c37e86a78c20b3b9d6997ad3f43431b6b2fe2f0 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 25 Nov 2022 14:55:00 +0100 Subject: [PATCH 0188/1017] rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes() [ Upstream commit 28319d6dc5e2ffefa452c2377dd0f71621b5bff0 ] RCU Tasks and PID-namespace unshare can interact in do_exit() in a complicated circular dependency: 1) TASK A calls unshare(CLONE_NEWPID), this creates a new PID namespace that every subsequent child of TASK A will belong to. But TASK A doesn't itself belong to that new PID namespace. 2) TASK A forks() and creates TASK B. TASK A stays attached to its PID namespace (let's say PID_NS1) and TASK B is the first task belonging to the new PID namespace created by unshare() (let's call it PID_NS2). 3) Since TASK B is the first task attached to PID_NS2, it becomes the PID_NS2 child reaper. 4) TASK A forks() again and creates TASK C which get attached to PID_NS2. Note how TASK C has TASK A as a parent (belonging to PID_NS1) but has TASK B (belonging to PID_NS2) as a pid_namespace child_reaper. 5) TASK B exits and since it is the child reaper for PID_NS2, it has to kill all other tasks attached to PID_NS2, and wait for all of them to die before getting reaped itself (zap_pid_ns_process()). 6) TASK A calls synchronize_rcu_tasks() which leads to synchronize_srcu(&tasks_rcu_exit_srcu). 7) TASK B is waiting for TASK C to get reaped. But TASK B is under a tasks_rcu_exit_srcu SRCU critical section (exit_notify() is between exit_tasks_rcu_start() and exit_tasks_rcu_finish()), blocking TASK A. 8) TASK C exits and since TASK A is its parent, it waits for it to reap TASK C, but it can't because TASK A waits for TASK B that waits for TASK C. Pid_namespace semantics can hardly be changed at this point. But the coverage of tasks_rcu_exit_srcu can be reduced instead. The current task is assumed not to be concurrently reapable at this stage of exit_notify() and therefore tasks_rcu_exit_srcu can be temporarily relaxed without breaking its constraints, providing a way out of the deadlock scenario. [ paulmck: Fix build failure by adding additional declaration. ] Fixes: 3f95aa81d265 ("rcu: Make TASKS_RCU handle tasks that are almost done exiting") Reported-by: Pengfei Xu Suggested-by: Boqun Feng Suggested-by: Neeraj Upadhyay Suggested-by: Paul E. McKenney Cc: Oleg Nesterov Cc: Lai Jiangshan Cc: Eric W . Biederman Signed-off-by: Frederic Weisbecker Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- include/linux/rcupdate.h | 2 ++ kernel/pid_namespace.c | 17 +++++++++++++++++ kernel/rcu/tasks.h | 15 +++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 095b3b39bd03..1f46db38d6ec 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -189,6 +189,7 @@ void synchronize_rcu_tasks_rude(void); #define rcu_note_voluntary_context_switch(t) rcu_tasks_qs(t, false) void exit_tasks_rcu_start(void); +void exit_tasks_rcu_stop(void); void exit_tasks_rcu_finish(void); #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */ #define rcu_tasks_qs(t, preempt) do { } while (0) @@ -196,6 +197,7 @@ void exit_tasks_rcu_finish(void); #define call_rcu_tasks call_rcu #define synchronize_rcu_tasks synchronize_rcu static inline void exit_tasks_rcu_start(void) { } +static inline void exit_tasks_rcu_stop(void) { } static inline void exit_tasks_rcu_finish(void) { } #endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */ diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index ef8733e2a476..20243682e605 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -251,7 +251,24 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) set_current_state(TASK_INTERRUPTIBLE); if (pid_ns->pid_allocated == init_pids) break; + /* + * Release tasks_rcu_exit_srcu to avoid following deadlock: + * + * 1) TASK A unshare(CLONE_NEWPID) + * 2) TASK A fork() twice -> TASK B (child reaper for new ns) + * and TASK C + * 3) TASK B exits, kills TASK C, waits for TASK A to reap it + * 4) TASK A calls synchronize_rcu_tasks() + * -> synchronize_srcu(tasks_rcu_exit_srcu) + * 5) *DEADLOCK* + * + * It is considered safe to release tasks_rcu_exit_srcu here + * because we assume the current task can not be concurrently + * reaped at this point. + */ + exit_tasks_rcu_stop(); schedule(); + exit_tasks_rcu_start(); } __set_current_state(TASK_RUNNING); diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index c4af3c05663f..df8143c8a6a8 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -604,17 +604,28 @@ void exit_tasks_rcu_start(void) __acquires(&tasks_rcu_exit_srcu) * task is exiting and may be removed from the tasklist. See * corresponding synchronize_srcu() for further details. */ -void exit_tasks_rcu_finish(void) __releases(&tasks_rcu_exit_srcu) +void exit_tasks_rcu_stop(void) __releases(&tasks_rcu_exit_srcu) { struct task_struct *t = current; __srcu_read_unlock(&tasks_rcu_exit_srcu, t->rcu_tasks_idx); - exit_tasks_rcu_finish_trace(t); +} + +/* + * Contribute to protect against tasklist scan blind spot while the + * task is exiting and may be removed from the tasklist. See + * corresponding synchronize_srcu() for further details. + */ +void exit_tasks_rcu_finish(void) +{ + exit_tasks_rcu_stop(); + exit_tasks_rcu_finish_trace(current); } #else /* #ifdef CONFIG_TASKS_RCU */ static inline void show_rcu_tasks_classic_gp_kthread(void) { } void exit_tasks_rcu_start(void) { } +void exit_tasks_rcu_stop(void) { } void exit_tasks_rcu_finish(void) { exit_tasks_rcu_finish_trace(current); } #endif /* #else #ifdef CONFIG_TASKS_RCU */ From 318dd6f5b7b401a7496e8474ed41a6a0e345afe1 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 27 Dec 2022 15:27:39 +0100 Subject: [PATCH 0189/1017] lib/mpi: Fix buffer overrun when SG is too long [ Upstream commit 7361d1bc307b926cbca214ab67b641123c2d6357 ] The helper mpi_read_raw_from_sgl sets the number of entries in the SG list according to nbytes. However, if the last entry in the SG list contains more data than nbytes, then it may overrun the buffer because it only allocates enough memory for nbytes. Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers") Reported-by: Roberto Sassu Signed-off-by: Herbert Xu Reviewed-by: Eric Biggers Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- lib/mpi/mpicoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 7ea225b2204f..7054311d7879 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c @@ -504,7 +504,8 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) while (sg_miter_next(&miter)) { buff = miter.addr; - len = miter.length; + len = min_t(unsigned, miter.length, nbytes); + nbytes -= len; for (x = 0; x < len; x++) { a <<= 8; From c997b509fd0168a3ced0b903c717f5b1a18a396b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:49 -0700 Subject: [PATCH 0190/1017] crypto: ccp: Use the stack for small SEV command buffers [ Upstream commit e4a9af799e5539b0feb99571f0aaed5a3c81dc5a ] For commands with small input/output buffers, use the local stack to "allocate" the structures used to communicate with the PSP. Now that __sev_do_cmd_locked() gracefully handles vmalloc'd buffers, there's no reason to avoid using the stack, e.g. CONFIG_VMAP_STACK=y will just work. Signed-off-by: Sean Christopherson Message-Id: <20210406224952.4177376-6-seanjc@google.com> Reviewed-by: Brijesh Singh Acked-by: Tom Lendacky Signed-off-by: Paolo Bonzini Stable-dep-of: 91dfd98216d8 ("crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2") Signed-off-by: Sasha Levin --- drivers/crypto/ccp/sev-dev.c | 117 +++++++++++++---------------------- 1 file changed, 44 insertions(+), 73 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index ed39a22e1b2b..75341ad2fdd8 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -385,7 +385,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) { struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pek_csr input; - struct sev_data_pek_csr *data; + struct sev_data_pek_csr data; void __user *input_address; void *blob = NULL; int ret; @@ -396,9 +396,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; + memset(&data, 0, sizeof(data)); /* userspace wants to query CSR length */ if (!input.address || !input.length) @@ -406,19 +404,15 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) /* allocate a physically contiguous buffer to store the CSR blob */ input_address = (void __user *)input.address; - if (input.length > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.length > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; blob = kmalloc(input.length, GFP_KERNEL); - if (!blob) { - ret = -ENOMEM; - goto e_free; - } + if (!blob) + return -ENOMEM; - data->address = __psp_pa(blob); - data->len = input.length; + data.address = __psp_pa(blob); + data.len = input.length; cmd: if (sev->state == SEV_STATE_UNINIT) { @@ -427,10 +421,10 @@ cmd: goto e_free_blob; } - ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, &data, &argp->error); /* If we query the CSR length, FW responded with expected data. */ - input.length = data->len; + input.length = data.len; if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { ret = -EFAULT; @@ -444,8 +438,6 @@ cmd: e_free_blob: kfree(blob); -e_free: - kfree(data); return ret; } @@ -577,7 +569,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) { struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pek_cert_import input; - struct sev_data_pek_cert_import *data; + struct sev_data_pek_cert_import data; void *pek_blob, *oca_blob; int ret; @@ -587,19 +579,14 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - /* copy PEK certificate blobs from userspace */ pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len); - if (IS_ERR(pek_blob)) { - ret = PTR_ERR(pek_blob); - goto e_free; - } + if (IS_ERR(pek_blob)) + return PTR_ERR(pek_blob); - data->pek_cert_address = __psp_pa(pek_blob); - data->pek_cert_len = input.pek_cert_len; + data.reserved = 0; + data.pek_cert_address = __psp_pa(pek_blob); + data.pek_cert_len = input.pek_cert_len; /* copy PEK certificate blobs from userspace */ oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len); @@ -608,8 +595,8 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) goto e_free_pek; } - data->oca_cert_address = __psp_pa(oca_blob); - data->oca_cert_len = input.oca_cert_len; + data.oca_cert_address = __psp_pa(oca_blob); + data.oca_cert_len = input.oca_cert_len; /* If platform is not in INIT state then transition it to INIT */ if (sev->state != SEV_STATE_INIT) { @@ -618,21 +605,19 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable) goto e_free_oca; } - ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PEK_CERT_IMPORT, &data, &argp->error); e_free_oca: kfree(oca_blob); e_free_pek: kfree(pek_blob); -e_free: - kfree(data); return ret; } static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) { struct sev_user_data_get_id2 input; - struct sev_data_get_id *data; + struct sev_data_get_id data; void __user *input_address; void *id_blob = NULL; int ret; @@ -646,28 +631,25 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) input_address = (void __user *)input.address; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - if (input.address && input.length) { id_blob = kmalloc(input.length, GFP_KERNEL); - if (!id_blob) { - kfree(data); + if (!id_blob) return -ENOMEM; - } - data->address = __psp_pa(id_blob); - data->len = input.length; + data.address = __psp_pa(id_blob); + data.len = input.length; + } else { + data.address = 0; + data.len = 0; } - ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_GET_ID, &data, &argp->error); /* * Firmware will return the length of the ID value (either the minimum * required length or the actual length written), return it to the user. */ - input.length = data->len; + input.length = data.len; if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { ret = -EFAULT; @@ -675,7 +657,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) } if (id_blob) { - if (copy_to_user(input_address, id_blob, data->len)) { + if (copy_to_user(input_address, id_blob, data.len)) { ret = -EFAULT; goto e_free; } @@ -683,7 +665,6 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) e_free: kfree(id_blob); - kfree(data); return ret; } @@ -733,7 +714,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) struct sev_device *sev = psp_master->sev_data; struct sev_user_data_pdh_cert_export input; void *pdh_blob = NULL, *cert_blob = NULL; - struct sev_data_pdh_cert_export *data; + struct sev_data_pdh_cert_export data; void __user *input_cert_chain_address; void __user *input_pdh_cert_address; int ret; @@ -751,9 +732,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; + memset(&data, 0, sizeof(data)); /* Userspace wants to query the certificate length. */ if (!input.pdh_cert_address || @@ -765,25 +744,19 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) input_cert_chain_address = (void __user *)input.cert_chain_address; /* Allocate a physically contiguous buffer to store the PDH blob. */ - if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; /* Allocate a physically contiguous buffer to store the cert chain blob. */ - if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) { - ret = -EFAULT; - goto e_free; - } + if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) + return -EFAULT; pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL); - if (!pdh_blob) { - ret = -ENOMEM; - goto e_free; - } + if (!pdh_blob) + return -ENOMEM; - data->pdh_cert_address = __psp_pa(pdh_blob); - data->pdh_cert_len = input.pdh_cert_len; + data.pdh_cert_address = __psp_pa(pdh_blob); + data.pdh_cert_len = input.pdh_cert_len; cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL); if (!cert_blob) { @@ -791,15 +764,15 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) goto e_free_pdh; } - data->cert_chain_address = __psp_pa(cert_blob); - data->cert_chain_len = input.cert_chain_len; + data.cert_chain_address = __psp_pa(cert_blob); + data.cert_chain_len = input.cert_chain_len; cmd: - ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PDH_CERT_EXPORT, &data, &argp->error); /* If we query the length, FW responded with expected data. */ - input.cert_chain_len = data->cert_chain_len; - input.pdh_cert_len = data->pdh_cert_len; + input.cert_chain_len = data.cert_chain_len; + input.pdh_cert_len = data.pdh_cert_len; if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { ret = -EFAULT; @@ -824,8 +797,6 @@ e_free_cert: kfree(cert_blob); e_free_pdh: kfree(pdh_blob); -e_free: - kfree(data); return ret; } From daaec051cd19e917215a5889bc67d58c0931e433 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 6 Apr 2021 15:49:50 -0700 Subject: [PATCH 0191/1017] crypto: ccp: Use the stack and common buffer for status commands [ Upstream commit 38103671aad38e888743dd26c767869cfc15adca ] Drop the dedicated status_cmd_buf and instead use a local variable for PLATFORM_STATUS. Now that the low level helper uses an internal buffer for all commands, using the stack for the upper layers is safe even when running with CONFIG_VMAP_STACK=y. Signed-off-by: Sean Christopherson Message-Id: <20210406224952.4177376-7-seanjc@google.com> Reviewed-by: Brijesh Singh Acked-by: Tom Lendacky Signed-off-by: Paolo Bonzini Stable-dep-of: 91dfd98216d8 ("crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2") Signed-off-by: Sasha Levin --- drivers/crypto/ccp/sev-dev.c | 27 ++++++++++++--------------- drivers/crypto/ccp/sev-dev.h | 1 - 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 75341ad2fdd8..1aac3a12a6c7 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -304,15 +304,14 @@ static int sev_platform_shutdown(int *error) static int sev_get_platform_state(int *state, int *error) { - struct sev_device *sev = psp_master->sev_data; + struct sev_user_data_status data; int rc; - rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, - &sev->status_cmd_buf, error); + rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, error); if (rc) return rc; - *state = sev->status_cmd_buf.state; + *state = data.state; return rc; } @@ -350,15 +349,14 @@ static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable) static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp) { - struct sev_device *sev = psp_master->sev_data; - struct sev_user_data_status *data = &sev->status_cmd_buf; + struct sev_user_data_status data; int ret; - ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error); if (ret) return ret; - if (copy_to_user((void __user *)argp->data, data, sizeof(*data))) + if (copy_to_user((void __user *)argp->data, &data, sizeof(data))) ret = -EFAULT; return ret; @@ -457,21 +455,20 @@ EXPORT_SYMBOL_GPL(psp_copy_user_blob); static int sev_get_api_version(void) { struct sev_device *sev = psp_master->sev_data; - struct sev_user_data_status *status; + struct sev_user_data_status status; int error = 0, ret; - status = &sev->status_cmd_buf; - ret = sev_platform_status(status, &error); + ret = sev_platform_status(&status, &error); if (ret) { dev_err(sev->dev, "SEV: failed to get status. Error: %#x\n", error); return 1; } - sev->api_major = status->api_major; - sev->api_minor = status->api_minor; - sev->build = status->build; - sev->state = status->state; + sev->api_major = status.api_major; + sev->api_minor = status.api_minor; + sev->build = status.build; + sev->state = status.state; return 0; } diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index dd5c4fe82914..3b0cd0f854df 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -46,7 +46,6 @@ struct sev_device { unsigned int int_rcvd; wait_queue_head_t int_queue; struct sev_misc_dev *misc; - struct sev_user_data_status status_cmd_buf; struct sev_data_init init_cmd_buf; u8 api_major; From 4c5300f6f5e18b11c02a92f136e69b98fddba15e Mon Sep 17 00:00:00 2001 From: John Allen Date: Wed, 18 May 2022 15:31:26 +0000 Subject: [PATCH 0192/1017] crypto: ccp - Use kzalloc for sev ioctl interfaces to prevent kernel memory leak [ Upstream commit 13dc15a3f5fd7f884e4bfa8c011a0ae868df12ae ] For some sev ioctl interfaces, input may be passed that is less than or equal to SEV_FW_BLOB_MAX_SIZE, but larger than the data that PSP firmware returns. In this case, kmalloc will allocate memory that is the size of the input rather than the size of the data. Since PSP firmware doesn't fully overwrite the buffer, the sev ioctl interfaces with the issue may return uninitialized slab memory. Currently, all of the ioctl interfaces in the ccp driver are safe, but to prevent future problems, change all ioctl interfaces that allocate memory with kmalloc to use kzalloc and memset the data buffer to zero in sev_ioctl_do_platform_status. Fixes: 38103671aad3 ("crypto: ccp: Use the stack and common buffer for status commands") Fixes: e799035609e15 ("crypto: ccp: Implement SEV_PEK_CSR ioctl command") Fixes: 76a2b524a4b1d ("crypto: ccp: Implement SEV_PDH_CERT_EXPORT ioctl command") Fixes: d6112ea0cb344 ("crypto: ccp - introduce SEV_GET_ID2 command") Cc: stable@vger.kernel.org Reported-by: Andy Nguyen Suggested-by: David Rientjes Suggested-by: Peter Gonda Signed-off-by: John Allen Reviewed-by: Peter Gonda Acked-by: David Rientjes Signed-off-by: Herbert Xu Stable-dep-of: 91dfd98216d8 ("crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2") Signed-off-by: Sasha Levin --- drivers/crypto/ccp/sev-dev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 1aac3a12a6c7..6edd938ce6ac 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -352,6 +352,8 @@ static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp) struct sev_user_data_status data; int ret; + memset(&data, 0, sizeof(data)); + ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, &data, &argp->error); if (ret) return ret; @@ -405,7 +407,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) if (input.length > SEV_FW_BLOB_MAX_SIZE) return -EFAULT; - blob = kmalloc(input.length, GFP_KERNEL); + blob = kzalloc(input.length, GFP_KERNEL); if (!blob) return -ENOMEM; @@ -629,7 +631,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) input_address = (void __user *)input.address; if (input.address && input.length) { - id_blob = kmalloc(input.length, GFP_KERNEL); + id_blob = kzalloc(input.length, GFP_KERNEL); if (!id_blob) return -ENOMEM; @@ -748,14 +750,14 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) if (input.cert_chain_len > SEV_FW_BLOB_MAX_SIZE) return -EFAULT; - pdh_blob = kmalloc(input.pdh_cert_len, GFP_KERNEL); + pdh_blob = kzalloc(input.pdh_cert_len, GFP_KERNEL); if (!pdh_blob) return -ENOMEM; data.pdh_cert_address = __psp_pa(pdh_blob); data.pdh_cert_len = input.pdh_cert_len; - cert_blob = kmalloc(input.cert_chain_len, GFP_KERNEL); + cert_blob = kzalloc(input.cert_chain_len, GFP_KERNEL); if (!cert_blob) { ret = -ENOMEM; goto e_free_pdh; From 4c33e01fe1d294b46c0212f213b8553e53604375 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 30 Dec 2022 14:18:46 -0800 Subject: [PATCH 0193/1017] crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2 [ Upstream commit 91dfd98216d817ec5f1c55890bacb7b4fe9b068a ] For SEV_GET_ID2, the user provided length does not have a specified limitation because the length of the ID may change in the future. The kernel memory allocation, however, is implicitly limited to 4MB on x86 by the page allocator, otherwise the kzalloc() will fail. When this happens, it is best not to spam the kernel log with the warning. Simply fail the allocation and return ENOMEM to the user. Fixes: d6112ea0cb34 ("crypto: ccp - introduce SEV_GET_ID2 command") Reported-by: Andy Nguyen Reported-by: Peter Gonda Suggested-by: Herbert Xu Signed-off-by: David Rientjes Acked-by: Tom Lendacky Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/sev-dev.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 6edd938ce6ac..e70ae98de118 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -631,7 +631,14 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) input_address = (void __user *)input.address; if (input.address && input.length) { - id_blob = kzalloc(input.length, GFP_KERNEL); + /* + * The length of the ID shouldn't be assumed by software since + * it may change in the future. The allocation size is limited + * to 1 << (PAGE_SHIFT + MAX_ORDER - 1) by the page allocator. + * If the allocation fails, simply return ENOMEM rather than + * warning in the kernel log. + */ + id_blob = kzalloc(input.length, GFP_KERNEL | __GFP_NOWARN); if (!id_blob) return -ENOMEM; From 5419cd28c8f29ccb347b5adbda1c2acc967700e6 Mon Sep 17 00:00:00 2001 From: Daniil Tatianin Date: Sat, 7 Jan 2023 02:53:08 +0300 Subject: [PATCH 0194/1017] ACPICA: nsrepair: handle cases without a return value correctly [ Upstream commit ca843a4c79486e99a19b859ef0b9887854afe146 ] Previously acpi_ns_simple_repair() would crash if expected_btypes contained any combination of ACPI_RTYPE_NONE with a different type, e.g | ACPI_RTYPE_INTEGER because of slightly incorrect logic in the !return_object branch, which wouldn't return AE_AML_NO_RETURN_VALUE for such cases. Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Link: https://github.com/acpica/acpica/pull/811 Fixes: 61db45ca2163 ("ACPICA: Restore code that repairs NULL package elements in return values.") Signed-off-by: Daniil Tatianin Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpica/nsrepair.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 90db2d85e7f5..f28d811a3724 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -181,8 +181,9 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info, * Try to fix if there was no return object. Warning if failed to fix. */ if (!return_object) { - if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { - if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { + if (expected_btypes) { + if (!(expected_btypes & ACPI_RTYPE_NONE) && + package_index != ACPI_NOT_PACKAGE_ELEMENT) { ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, ACPI_WARN_ALWAYS, @@ -196,14 +197,15 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info, if (ACPI_SUCCESS(status)) { return (AE_OK); /* Repair was successful */ } - } else { + } + + if (expected_btypes != ACPI_RTYPE_NONE) { ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, ACPI_WARN_ALWAYS, "Missing expected return value")); + return (AE_AML_NO_RETURN_VALUE); } - - return (AE_AML_NO_RETURN_VALUE); } } From e6ec7fa688d93839dcc1949b524e6b9bcea3a069 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:19 +0200 Subject: [PATCH 0195/1017] thermal/drivers/tsens: Drop msm8976-specific defines [ Upstream commit 3bf0ea99e2e32b0335106b86d84404cc85bcd113 ] Drop msm8976-specific defines, which duplicate generic ones. Fixes: 0e580290170d ("thermal: qcom: tsens-v1: Add support for MSM8956 and MSM8976") Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-6-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano Signed-off-by: Sasha Levin --- drivers/thermal/qcom/tsens-v1.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 3c19a3800c6d..bff50f3b9d0b 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -78,11 +78,6 @@ #define MSM8976_CAL_SEL_MASK 0x3 -#define MSM8976_CAL_DEGC_PT1 30 -#define MSM8976_CAL_DEGC_PT2 120 -#define MSM8976_SLOPE_FACTOR 1000 -#define MSM8976_SLOPE_DEFAULT 3200 - /* eeprom layout data for qcs404/405 (v1) */ #define BASE0_MASK 0x000007f8 #define BASE1_MASK 0x0007f800 @@ -160,8 +155,8 @@ static void compute_intercept_slope_8976(struct tsens_priv *priv, priv->sensor[10].slope = 3286; for (i = 0; i < priv->num_sensors; i++) { - priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) - - (MSM8976_CAL_DEGC_PT1 * + priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) - + (CAL_DEGC_PT1 * priv->sensor[i].slope); } } From a9f2002484ec6bd40094fb5d3d2feb90dbcd705a Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 25 Feb 2021 22:31:19 +0100 Subject: [PATCH 0196/1017] thermal/drivers/qcom/tsens_v1: Enable sensor 3 on MSM8976 [ Upstream commit 007d81a4519f04fa5ced5e9e28bf70cd753c398d ] The sensor *is* in fact used and does report temperature. Signed-off-by: Konrad Dybcio Acked-by: Thara Gopinath Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20210225213119.116550-1-konrad.dybcio@somainline.org Stable-dep-of: a7d3006be5ca ("thermal/drivers/tsens: Sort out msm8976 vs msm8956 data") Signed-off-by: Sasha Levin --- drivers/thermal/qcom/tsens-v1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index bff50f3b9d0b..13624263f1df 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -375,11 +375,11 @@ static const struct tsens_ops ops_8976 = { .get_temp = get_temp_tsens_valid, }; -/* Valid for both MSM8956 and MSM8976. Sensor ID 3 is unused. */ +/* Valid for both MSM8956 and MSM8976. */ struct tsens_plat_data data_8976 = { .num_sensors = 11, .ops = &ops_8976, - .hw_ids = (unsigned int[]){0, 1, 2, 4, 5, 6, 7, 8, 9, 10}, + .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, }; From 40f62ff0d7edbbc77d0074e5321f7fe0d275e57f Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 6 Apr 2022 03:26:46 +0300 Subject: [PATCH 0197/1017] thermal/drivers/tsens: Add compat string for the qcom,msm8960 [ Upstream commit 2caf73969de6675318a711d0622406c8c66afc03 ] On apq8064 (msm8960) platforms the tsens device is created manually by the gcc driver. Prepare the tsens driver for the qcom,msm8960-tsens device instantiated from the device tree. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20220406002648.393486-3-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano Stable-dep-of: a7d3006be5ca ("thermal/drivers/tsens: Sort out msm8976 vs msm8956 data") Signed-off-by: Sasha Levin --- drivers/thermal/qcom/tsens.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index cb4f4b522446..9e4a60db6e23 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -902,6 +902,9 @@ static const struct of_device_id tsens_table[] = { }, { .compatible = "qcom,msm8939-tsens", .data = &data_8939, + }, { + .compatible = "qcom,msm8960-tsens", + .data = &data_8960, }, { .compatible = "qcom,msm8974-tsens", .data = &data_8974, From 695f1d9431ff702eeecd637ff24698b17ceb7d42 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 1 Jan 2023 21:40:20 +0200 Subject: [PATCH 0198/1017] thermal/drivers/tsens: Sort out msm8976 vs msm8956 data [ Upstream commit a7d3006be5ca7b04e4b84b5ceaae55a700e511bd ] Tsens driver mentions that msm8976 data should be used for both msm8976 and msm8956 SoCs. This is not quite correct, as according to the vendor kernels, msm8976 should use standard slope values (3200), while msm8956 really uses the slope values found in the driver. Add separate compatibility string for msm8956, move slope value overrides to the corresponding init function and use the standard compute_intercept_slope() function for both platforms. Fixes: 0e580290170d ("thermal: qcom: tsens-v1: Add support for MSM8956 and MSM8976") Cc: AngeloGioacchino Del Regno Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230101194034.831222-7-dmitry.baryshkov@linaro.org Signed-off-by: Daniel Lezcano Signed-off-by: Sasha Levin --- drivers/thermal/qcom/tsens-v1.c | 56 ++++++++++++++++++--------------- drivers/thermal/qcom/tsens.c | 3 ++ drivers/thermal/qcom/tsens.h | 2 +- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 13624263f1df..faa4576fa028 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -137,30 +137,6 @@ #define CAL_SEL_MASK 7 #define CAL_SEL_SHIFT 0 -static void compute_intercept_slope_8976(struct tsens_priv *priv, - u32 *p1, u32 *p2, u32 mode) -{ - int i; - - priv->sensor[0].slope = 3313; - priv->sensor[1].slope = 3275; - priv->sensor[2].slope = 3320; - priv->sensor[3].slope = 3246; - priv->sensor[4].slope = 3279; - priv->sensor[5].slope = 3257; - priv->sensor[6].slope = 3234; - priv->sensor[7].slope = 3269; - priv->sensor[8].slope = 3255; - priv->sensor[9].slope = 3239; - priv->sensor[10].slope = 3286; - - for (i = 0; i < priv->num_sensors; i++) { - priv->sensor[i].offset = (p1[i] * SLOPE_FACTOR) - - (CAL_DEGC_PT1 * - priv->sensor[i].slope); - } -} - static int calibrate_v1(struct tsens_priv *priv) { u32 base0 = 0, base1 = 0; @@ -286,7 +262,7 @@ static int calibrate_8976(struct tsens_priv *priv) break; } - compute_intercept_slope_8976(priv, p1, p2, mode); + compute_intercept_slope(priv, p1, p2, mode); kfree(qfprom_cdata); return 0; @@ -357,6 +333,22 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = { [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0), }; +static int __init init_8956(struct tsens_priv *priv) { + priv->sensor[0].slope = 3313; + priv->sensor[1].slope = 3275; + priv->sensor[2].slope = 3320; + priv->sensor[3].slope = 3246; + priv->sensor[4].slope = 3279; + priv->sensor[5].slope = 3257; + priv->sensor[6].slope = 3234; + priv->sensor[7].slope = 3269; + priv->sensor[8].slope = 3255; + priv->sensor[9].slope = 3239; + priv->sensor[10].slope = 3286; + + return init_common(priv); +} + static const struct tsens_ops ops_generic_v1 = { .init = init_common, .calibrate = calibrate_v1, @@ -369,13 +361,25 @@ struct tsens_plat_data data_tsens_v1 = { .fields = tsens_v1_regfields, }; +static const struct tsens_ops ops_8956 = { + .init = init_8956, + .calibrate = calibrate_8976, + .get_temp = get_temp_tsens_valid, +}; + +struct tsens_plat_data data_8956 = { + .num_sensors = 11, + .ops = &ops_8956, + .feat = &tsens_v1_feat, + .fields = tsens_v1_regfields, +}; + static const struct tsens_ops ops_8976 = { .init = init_common, .calibrate = calibrate_8976, .get_temp = get_temp_tsens_valid, }; -/* Valid for both MSM8956 and MSM8976. */ struct tsens_plat_data data_8976 = { .num_sensors = 11, .ops = &ops_8976, diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 9e4a60db6e23..c73792ca727a 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -902,6 +902,9 @@ static const struct of_device_id tsens_table[] = { }, { .compatible = "qcom,msm8939-tsens", .data = &data_8939, + }, { + .compatible = "qcom,msm8956-tsens", + .data = &data_8956, }, { .compatible = "qcom,msm8960-tsens", .data = &data_8960, diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index f40b625f897e..bbb1e8332821 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -588,7 +588,7 @@ extern struct tsens_plat_data data_8960; extern struct tsens_plat_data data_8916, data_8939, data_8974; /* TSENS v1 targets */ -extern struct tsens_plat_data data_tsens_v1, data_8976; +extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956; /* TSENS v2 targets */ extern struct tsens_plat_data data_8996, data_tsens_v2; From 430f9f9bec53a75f9ccc53e156a66f13fc098b83 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 22 Dec 2022 13:48:04 +0200 Subject: [PATCH 0199/1017] wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU [ Upstream commit b39f662ce1648db0b9de32e6a849b098480793cb ] The wifi + bluetooth combo chip RTL8723BU can leak memory (especially?) when it's connected to a bluetooth audio device. The busy bluetooth traffic generates lots of C2H (card to host) messages, which are not freed correctly. To fix this, move the dev_kfree_skb() call in rtl8xxxu_c2hcmd_callback() inside the loop where skb_dequeue() is called. The RTL8192EU leaks memory because the C2H messages are added to the queue and left there forever. (This was fine in the past because it probably wasn't sending any C2H messages until commit e542e66b7c2e ("wifi: rtl8xxxu: gen2: Turn on the rate control"). Since that commit it sends a C2H message when the TX rate changes.) To fix this, delete the check for rf_paths > 1 and the goto. Let the function process the C2H messages from RTL8192EU like the ones from the other chips. Theoretically the RTL8188FU could also leak like RTL8723BU, but it most likely doesn't send C2H messages frequently enough. This change was tested with RTL8723BU by Erhard F. I tested it with RTL8188FU and RTL8192EU. Reported-by: Erhard F. Tested-by: Erhard F. Link: https://bugzilla.kernel.org/show_bug.cgi?id=215197 Fixes: e542e66b7c2e ("rtl8xxxu: add bluetooth co-existence support for single antenna") Signed-off-by: Bitterblue Smith Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/03b099c1-c671-d252-36f4-57b70d721f9d@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index f8b1871fe290..376782b7aba8 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -5491,9 +5491,6 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) btcoex = &priv->bt_coex; rarpt = &priv->ra_report; - if (priv->rf_paths > 1) - goto out; - while (!skb_queue_empty(&priv->c2hcmd_queue)) { spin_lock_irqsave(&priv->c2hcmd_lock, flags); skb = __skb_dequeue(&priv->c2hcmd_queue); @@ -5547,10 +5544,9 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) default: break; } - } -out: - dev_kfree_skb(skb); + dev_kfree_skb(skb); + } } static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, From b44178e71810b9556fb14515fcea527b73b9573c Mon Sep 17 00:00:00 2001 From: Alexey Kodanev Date: Tue, 27 Dec 2022 16:33:06 +0300 Subject: [PATCH 0200/1017] wifi: orinoco: check return value of hermes_write_wordrec() [ Upstream commit 1e346cbb096a5351a637ec1992beffbf330547f0 ] There is currently no return check for writing an authentication type (HERMES_AUTH_SHARED_KEY or HERMES_AUTH_OPEN). It looks like it was accidentally skipped. This patch adds a return check similar to the other checks in __orinoco_hw_setup_enc() for hermes_write_wordrec(). Detected using the static analysis tool - Svace. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Alexey Kodanev Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221227133306.201356-1-aleksei.kodanev@bell-sw.com Signed-off-by: Sasha Levin --- drivers/net/wireless/intersil/orinoco/hw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intersil/orinoco/hw.c b/drivers/net/wireless/intersil/orinoco/hw.c index 61af5a28f269..af49aa421e47 100644 --- a/drivers/net/wireless/intersil/orinoco/hw.c +++ b/drivers/net/wireless/intersil/orinoco/hw.c @@ -931,6 +931,8 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv) err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFAUTHENTICATION_AGERE, auth_flag); + if (err) + return err; } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPENABLED_AGERE, From ec246dfe006b2a8f36353f7489e4f525114db9a5 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Wed, 4 Jan 2023 15:35:46 +0300 Subject: [PATCH 0201/1017] wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9b25e3985477ac3f02eca5fc1e0cc6850a3f7e69 ] It is stated that ath9k_htc_rx_msg() either frees the provided skb or passes its management to another callback function. However, the skb is not freed in case there is no another callback function, and Syzkaller was able to cause a memory leak. Also minor comment fix. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Reported-by: syzbot+e008dccab31bd3647609@syzkaller.appspotmail.com Reported-by: syzbot+6692c72009680f7c4eb2@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin Signed-off-by: Alexey Khoroshilov Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230104123546.51427-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/htc_hst.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index ca05b07a45e6..fe62ff668f75 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -391,7 +391,7 @@ static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle, * HTC Messages are handled directly here and the obtained SKB * is freed. * - * Service messages (Data, WMI) passed to the corresponding + * Service messages (Data, WMI) are passed to the corresponding * endpoint RX handlers, which have to free the SKB. */ void ath9k_htc_rx_msg(struct htc_target *htc_handle, @@ -478,6 +478,8 @@ invalid: if (endpoint->ep_callbacks.rx) endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv, skb, epid); + else + goto invalid; } } From 221f9bd5ec56933c3e1ee07ff941804296ad5560 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Wed, 27 Apr 2022 10:37:32 +0300 Subject: [PATCH 0202/1017] ath9k: hif_usb: simplify if-if to if-else MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 2950833f10cfa601813262e1d9c8473f9415681b ] Use if and else instead of if(A) and if (!A). Signed-off-by: Wan Jiabing Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220424094441.104937-1-wanjiabing@vivo.com Stable-dep-of: 0af54343a762 ("wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails") Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f938ac1a4abd..f54380fb6c9e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -368,10 +368,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) __skb_queue_head_init(&tx_buf->skb_queue); list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); hif_dev->tx.tx_buf_cnt++; - } - - if (!ret) + } else { TX_STAT_INC(buf_queued); + } return ret; } From 5668e63e2673303d969a075aa5c028d3758a4a6e Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Mon, 13 Jun 2022 21:44:07 +0300 Subject: [PATCH 0203/1017] ath9k: htc: clean up statistics macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d7fc76039b74ad37b7056d5607b05d7cb31a5404 ] I've changed *STAT_* macros a bit in previous patch and I seems like they become really unreadable. Align these macros definitions to make code cleaner and fix folllowing checkpatch warning ERROR: Macros with complex values should be enclosed in parentheses Also, statistics macros now accept an hif_dev as argument, since macros that depend on having a local variable with a magic name don't abide by the coding style. No functional change Suggested-by: Jeff Johnson Signed-off-by: Pavel Skripkin Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/ebb2306d06a496cd1b032155ae52fdc5fa8cc2c5.1655145743.git.paskripkin@gmail.com Stable-dep-of: 0af54343a762 ("wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails") Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/hif_usb.c | 26 ++++++++-------- drivers/net/wireless/ath/ath9k/htc.h | 30 +++++++++++-------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 10 +++---- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f54380fb6c9e..1a2e0c7eeb02 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -244,11 +244,11 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, txok); if (txok) { - TX_STAT_INC(skb_success); - TX_STAT_ADD(skb_success_bytes, ln); + TX_STAT_INC(hif_dev, skb_success); + TX_STAT_ADD(hif_dev, skb_success_bytes, ln); } else - TX_STAT_INC(skb_failed); + TX_STAT_INC(hif_dev, skb_failed); } } @@ -302,7 +302,7 @@ static void hif_usb_tx_cb(struct urb *urb) hif_dev->tx.tx_buf_cnt++; if (!(hif_dev->tx.flags & HIF_USB_TX_STOP)) __hif_usb_tx(hif_dev); /* Check for pending SKBs */ - TX_STAT_INC(buf_completed); + TX_STAT_INC(hif_dev, buf_completed); spin_unlock(&hif_dev->tx.tx_lock); } @@ -353,7 +353,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) tx_buf->len += tx_buf->offset; __skb_queue_tail(&tx_buf->skb_queue, nskb); - TX_STAT_INC(skb_queued); + TX_STAT_INC(hif_dev, skb_queued); } usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev, @@ -369,7 +369,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); hif_dev->tx.tx_buf_cnt++; } else { - TX_STAT_INC(buf_queued); + TX_STAT_INC(hif_dev, buf_queued); } return ret; @@ -514,7 +514,7 @@ static void hif_usb_sta_drain(void *hif_handle, u8 idx) ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, false); hif_dev->tx.tx_skb_cnt--; - TX_STAT_INC(skb_failed); + TX_STAT_INC(hif_dev, skb_failed); } } @@ -585,14 +585,14 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, pkt_tag = get_unaligned_le16(ptr + index + 2); if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) { - RX_STAT_INC(skb_dropped); + RX_STAT_INC(hif_dev, skb_dropped); return; } if (pkt_len > 2 * MAX_RX_BUF_SIZE) { dev_err(&hif_dev->udev->dev, "ath9k_htc: invalid pkt_len (%x)\n", pkt_len); - RX_STAT_INC(skb_dropped); + RX_STAT_INC(hif_dev, skb_dropped); return; } @@ -618,7 +618,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, goto err; } skb_reserve(nskb, 32); - RX_STAT_INC(skb_allocated); + RX_STAT_INC(hif_dev, skb_allocated); memcpy(nskb->data, &(skb->data[chk_idx+4]), hif_dev->rx_transfer_len); @@ -639,7 +639,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, goto err; } skb_reserve(nskb, 32); - RX_STAT_INC(skb_allocated); + RX_STAT_INC(hif_dev, skb_allocated); memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len); skb_put(nskb, pkt_len); @@ -649,10 +649,10 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, err: for (i = 0; i < pool_index; i++) { - RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len); + RX_STAT_ADD(hif_dev, skb_completed_bytes, skb_pool[i]->len); ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], skb_pool[i]->len, USB_WLAN_RX_PIPE); - RX_STAT_INC(skb_completed); + RX_STAT_INC(hif_dev, skb_completed); } } diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index e3d546ef71dd..30f0765fb9fd 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -327,14 +327,18 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) } #ifdef CONFIG_ATH9K_HTC_DEBUGFS -#define __STAT_SAFE(expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0) -#define TX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) -#define TX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) -#define RX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++) -#define RX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a) -#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ +#define __STAT_SAFE(hif_dev, expr) ((hif_dev)->htc_handle->drv_priv ? (expr) : 0) +#define CAB_STAT_INC(priv) ((priv)->debug.tx_stats.cab_queued++) +#define TX_QSTAT_INC(priv, q) ((priv)->debug.tx_stats.queue_stats[q]++) -#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) +#define TX_STAT_INC(hif_dev, c) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++) +#define TX_STAT_ADD(hif_dev, c, a) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c += a) +#define RX_STAT_INC(hif_dev, c) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c++) +#define RX_STAT_ADD(hif_dev, c, a) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c += a) void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, struct ath_rx_status *rs); @@ -374,13 +378,13 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw, struct ethtool_stats *stats, u64 *data); #else -#define TX_STAT_INC(c) do { } while (0) -#define TX_STAT_ADD(c, a) do { } while (0) -#define RX_STAT_INC(c) do { } while (0) -#define RX_STAT_ADD(c, a) do { } while (0) -#define CAB_STAT_INC do { } while (0) +#define TX_STAT_INC(hif_dev, c) +#define TX_STAT_ADD(hif_dev, c, a) +#define RX_STAT_INC(hif_dev, c) +#define RX_STAT_ADD(hif_dev, c, a) -#define TX_QSTAT_INC(c) do { } while (0) +#define CAB_STAT_INC(priv) +#define TX_QSTAT_INC(priv, c) static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, struct ath_rx_status *rs) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 43a743ec9d9e..622fc7f17040 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, switch (qnum) { case 0: - TX_QSTAT_INC(IEEE80211_AC_VO); + TX_QSTAT_INC(priv, IEEE80211_AC_VO); epid = priv->data_vo_ep; break; case 1: - TX_QSTAT_INC(IEEE80211_AC_VI); + TX_QSTAT_INC(priv, IEEE80211_AC_VI); epid = priv->data_vi_ep; break; case 2: - TX_QSTAT_INC(IEEE80211_AC_BE); + TX_QSTAT_INC(priv, IEEE80211_AC_BE); epid = priv->data_be_ep; break; case 3: default: - TX_QSTAT_INC(IEEE80211_AC_BK); + TX_QSTAT_INC(priv, IEEE80211_AC_BK); epid = priv->data_bk_ep; break; } @@ -323,7 +323,7 @@ static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); if (is_cab) { - CAB_STAT_INC; + CAB_STAT_INC(priv); tx_ctl->epid = priv->cab_ep; return; } From f26dd69f61eff2eedf5df2d199bdd23108309947 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Wed, 4 Jan 2023 15:36:15 +0300 Subject: [PATCH 0204/1017] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 0af54343a76263a12dbae7fafb64eb47c4a6ad38 ] Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream(). While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we have an incorrect pkt_len or pkt_tag, the input skb is considered invalid and dropped. All the associated packets already in skb_pool should be dropped and freed. Added a comment describing this issue. The patch also makes remain_skb NULL after being processed so that it cannot be referenced after potential free. The initialization of hif_dev fields which are associated with remain_skb (rx_remain_len, rx_transfer_len and rx_pad_len) is moved after a new remain_skb is allocated. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream") Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column") Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin Signed-off-by: Alexey Khoroshilov Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230104123615.51511-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/hif_usb.c | 31 +++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 1a2e0c7eeb02..de6c0824c9ca 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -561,11 +561,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, memcpy(ptr, skb->data, rx_remain_len); rx_pkt_len += rx_remain_len; - hif_dev->rx_remain_len = 0; skb_put(remain_skb, rx_pkt_len); skb_pool[pool_index++] = remain_skb; - + hif_dev->remain_skb = NULL; + hif_dev->rx_remain_len = 0; } else { index = rx_remain_len; } @@ -584,16 +584,21 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, pkt_len = get_unaligned_le16(ptr + index); pkt_tag = get_unaligned_le16(ptr + index + 2); + /* It is supposed that if we have an invalid pkt_tag or + * pkt_len then the whole input SKB is considered invalid + * and dropped; the associated packets already in skb_pool + * are dropped, too. + */ if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) { RX_STAT_INC(hif_dev, skb_dropped); - return; + goto invalid_pkt; } if (pkt_len > 2 * MAX_RX_BUF_SIZE) { dev_err(&hif_dev->udev->dev, "ath9k_htc: invalid pkt_len (%x)\n", pkt_len); RX_STAT_INC(hif_dev, skb_dropped); - return; + goto invalid_pkt; } pad_len = 4 - (pkt_len & 0x3); @@ -605,11 +610,6 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, if (index > MAX_RX_BUF_SIZE) { spin_lock(&hif_dev->rx_lock); - hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; - hif_dev->rx_transfer_len = - MAX_RX_BUF_SIZE - chk_idx - 4; - hif_dev->rx_pad_len = pad_len; - nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); if (!nskb) { dev_err(&hif_dev->udev->dev, @@ -617,6 +617,12 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, spin_unlock(&hif_dev->rx_lock); goto err; } + + hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; + hif_dev->rx_transfer_len = + MAX_RX_BUF_SIZE - chk_idx - 4; + hif_dev->rx_pad_len = pad_len; + skb_reserve(nskb, 32); RX_STAT_INC(hif_dev, skb_allocated); @@ -654,6 +660,13 @@ err: skb_pool[i]->len, USB_WLAN_RX_PIPE); RX_STAT_INC(hif_dev, skb_completed); } + return; +invalid_pkt: + for (i = 0; i < pool_index; i++) { + dev_kfree_skb_any(skb_pool[i]); + RX_STAT_INC(hif_dev, skb_dropped); + } + return; } static void ath9k_hif_usb_rx_cb(struct urb *urb) From 78b56b0a613a87b61290b95be497fdfe2fe58aa6 Mon Sep 17 00:00:00 2001 From: Minsuk Kang Date: Wed, 4 Jan 2023 21:41:30 +0900 Subject: [PATCH 0205/1017] wifi: ath9k: Fix potential stack-out-of-bounds write in ath9k_wmi_rsp_callback() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 8a2f35b9830692f7a616f2f627f943bc748af13a ] Fix a stack-out-of-bounds write that occurs in a WMI response callback function that is called after a timeout occurs in ath9k_wmi_cmd(). The callback writes to wmi->cmd_rsp_buf, a stack-allocated buffer that could no longer be valid when a timeout occurs. Set wmi->last_seq_id to 0 when a timeout occurred. Found by a modified version of syzkaller. BUG: KASAN: stack-out-of-bounds in ath9k_wmi_ctrl_rx Write of size 4 Call Trace: memcpy ath9k_wmi_ctrl_rx ath9k_htc_rx_msg ath9k_hif_usb_reg_in_cb __usb_hcd_giveback_urb usb_hcd_giveback_urb dummy_timer call_timer_fn run_timer_softirq __do_softirq irq_exit_rcu sysvec_apic_timer_interrupt Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Signed-off-by: Minsuk Kang Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230104124130.10996-1-linuxlovemin@yonsei.ac.kr Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/wmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index f315c54bd3ac..19345b8f7bfd 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -341,6 +341,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, if (!time_left) { ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n", wmi_cmd_to_name(cmd_id)); + wmi->last_seq_id = 0; mutex_unlock(&wmi->op_mutex); return -ETIMEDOUT; } From 137963e3b95776f1d57c62f249a93fe47e019a22 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 12:11:42 +0400 Subject: [PATCH 0206/1017] wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup [ Upstream commit ed3f83b3459a67a3ab9d806490ac304b567b1c2d ] crypto_alloc_shash() allocates resources, which should be released by crypto_free_shash(). When ath11k_peer_find() fails, there has memory leak. Add missing crypto_free_shash() to fix this. Fixes: 243874c64c81 ("ath11k: handle RX fragments") Signed-off-by: Miaoqian Lin Reviewed-by: Leon Romanovsky Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230102081142.3937570-1-linmq006@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/dp_rx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 2e77dca6b1ad..578fdc446bc0 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -3022,6 +3022,7 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id if (!peer) { ath11k_warn(ab, "failed to find the peer to set up fragment info\n"); spin_unlock_bh(&ab->base_lock); + crypto_free_shash(tfm); return -ENOENT; } From 45a1ca6f3ae7c75cc317a0850196e08af76f583b Mon Sep 17 00:00:00 2001 From: Shivani Baranwal Date: Tue, 6 Dec 2022 20:07:14 +0530 Subject: [PATCH 0207/1017] wifi: cfg80211: Fix extended KCK key length check in nl80211_set_rekey_data() [ Upstream commit df4969ca135b9b3b2c38c07514aaa775112ac835 ] The extended KCK key length check wrongly using the KEK key attribute for validation. Due to this GTK rekey offload is failing when the KCK key length is 24 bytes even though the driver advertising WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK flag. Use correct attribute to fix the same. Fixes: 093a48d2aa4b ("cfg80211: support bigger kek/kck key length") Signed-off-by: Shivani Baranwal Signed-off-by: Veerendranath Jakkam Link: https://lore.kernel.org/r/20221206143715.1802987-2-quic_vjakkam@quicinc.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8a7f0c8fba5e..ea36d8c47b31 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12675,7 +12675,7 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) return -ERANGE; if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN && !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK && - nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN)) + nla_len(tb[NL80211_REKEY_DATA_KCK]) == NL80211_KCK_EXT_LEN)) return -ERANGE; rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]); From 6fb7dead798c97f6c13acdea1023979d16dd7482 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Sat, 14 Jan 2023 09:50:50 +0100 Subject: [PATCH 0208/1017] ACPI: battery: Fix missing NUL-termination with large strings [ Upstream commit f2ac14b5f197e4a2dec51e5ceaa56682ff1592bc ] When encountering a string bigger than the destination buffer (32 bytes), the string is not properly NUL-terminated, causing buffer overreads later. This for example happens on the Inspiron 3505, where the battery model name is larger than 32 bytes, which leads to sysfs showing the model name together with the serial number string (which is NUL-terminated and thus prevents worse). Fix this by using strscpy() which ensures that the result is always NUL-terminated. Fixes: 106449e870b3 ("ACPI: Battery: Allow extract string from integer") Signed-off-by: Armin Wolf Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index be743d177bcb..8b43efe97da5 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -454,7 +454,7 @@ static int extract_package(struct acpi_battery *battery, u8 *ptr = (u8 *)battery + offsets[i].offset; if (element->type == ACPI_TYPE_STRING || element->type == ACPI_TYPE_BUFFER) - strncpy(ptr, element->string.pointer, 32); + strscpy(ptr, element->string.pointer, 32); else if (element->type == ACPI_TYPE_INTEGER) { strncpy(ptr, (u8 *)&element->integer.value, sizeof(u64)); From 62d428c9fe1b3c1c4aabab710e464f8e360b2786 Mon Sep 17 00:00:00 2001 From: Koba Ko Date: Mon, 9 Jan 2023 10:15:02 +0800 Subject: [PATCH 0209/1017] crypto: ccp - Failure on re-initialization due to duplicate sysfs filename [ Upstream commit 299bf602b3f92f1456aef59c6413591fb02e762a ] The following warning appears during the CCP module re-initialization: [ 140.965403] sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:07.1/0000:03:00.2/dma/dma0chan0' [ 140.975736] CPU: 0 PID: 388 Comm: kworker/0:2 Kdump: loaded Not tainted 6.2.0-0.rc2.18.eln124.x86_64 #1 [ 140.985185] Hardware name: HPE ProLiant DL325 Gen10/ProLiant DL325 Gen10, BIOS A41 07/17/2020 [ 140.993761] Workqueue: events work_for_cpu_fn [ 140.998151] Call Trace: [ 141.000613] [ 141.002726] dump_stack_lvl+0x33/0x46 [ 141.006415] sysfs_warn_dup.cold+0x17/0x23 [ 141.010542] sysfs_create_dir_ns+0xba/0xd0 [ 141.014670] kobject_add_internal+0xba/0x260 [ 141.018970] kobject_add+0x81/0xb0 [ 141.022395] device_add+0xdc/0x7e0 [ 141.025822] ? complete_all+0x20/0x90 [ 141.029510] __dma_async_device_channel_register+0xc9/0x130 [ 141.035119] dma_async_device_register+0x19e/0x3b0 [ 141.039943] ccp_dmaengine_register+0x334/0x3f0 [ccp] [ 141.045042] ccp5_init+0x662/0x6a0 [ccp] [ 141.049000] ? devm_kmalloc+0x40/0xd0 [ 141.052688] ccp_dev_init+0xbb/0xf0 [ccp] [ 141.056732] ? __pci_set_master+0x56/0xd0 [ 141.060768] sp_init+0x70/0x90 [ccp] [ 141.064377] sp_pci_probe+0x186/0x1b0 [ccp] [ 141.068596] local_pci_probe+0x41/0x80 [ 141.072374] work_for_cpu_fn+0x16/0x20 [ 141.076145] process_one_work+0x1c8/0x380 [ 141.080181] worker_thread+0x1ab/0x380 [ 141.083953] ? __pfx_worker_thread+0x10/0x10 [ 141.088250] kthread+0xda/0x100 [ 141.091413] ? __pfx_kthread+0x10/0x10 [ 141.095185] ret_from_fork+0x2c/0x50 [ 141.098788] [ 141.100996] kobject_add_internal failed for dma0chan0 with -EEXIST, don't try to register things with the same name in the same directory. [ 141.113703] ccp 0000:03:00.2: ccp initialization failed The /dma/dma0chan0 sysfs file is not removed since dma_chan object has been released in ccp_dma_release() before releasing dma device. A correct procedure would be: release dma channels first => unregister dma device => release ccp dma object. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216888 Fixes: 68dbe80f5b51 ("crypto: ccp - Release dma channels before dmaengine unrgister") Tested-by: Vladis Dronov Signed-off-by: Koba Ko Reviewed-by: Vladis Dronov Acked-by: Tom Lendacky Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/ccp-dmaengine.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c index b9299defb431..e416456b2b8a 100644 --- a/drivers/crypto/ccp/ccp-dmaengine.c +++ b/drivers/crypto/ccp/ccp-dmaengine.c @@ -643,14 +643,26 @@ static void ccp_dma_release(struct ccp_device *ccp) chan = ccp->ccp_dma_chan + i; dma_chan = &chan->dma_chan; - if (dma_chan->client_count) - dma_release_channel(dma_chan); - tasklet_kill(&chan->cleanup_tasklet); list_del_rcu(&dma_chan->device_node); } } +static void ccp_dma_release_channels(struct ccp_device *ccp) +{ + struct ccp_dma_chan *chan; + struct dma_chan *dma_chan; + unsigned int i; + + for (i = 0; i < ccp->cmd_q_count; i++) { + chan = ccp->ccp_dma_chan + i; + dma_chan = &chan->dma_chan; + + if (dma_chan->client_count) + dma_release_channel(dma_chan); + } +} + int ccp_dmaengine_register(struct ccp_device *ccp) { struct ccp_dma_chan *chan; @@ -771,8 +783,9 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp) if (!dmaengine) return; - ccp_dma_release(ccp); + ccp_dma_release_channels(ccp); dma_async_device_unregister(dma_dev); + ccp_dma_release(ccp); kmem_cache_destroy(ccp->dma_desc_cache); kmem_cache_destroy(ccp->dma_cmd_cache); From 796e02cca30a67322161f0745e5ce994bbe75605 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 13 Jan 2023 18:24:09 +0800 Subject: [PATCH 0210/1017] crypto: essiv - Handle EBUSY correctly [ Upstream commit b5a772adf45a32c68bef28e60621f12617161556 ] As it is essiv only handles the special return value of EINPROGERSS, which means that in all other cases it will free data related to the request. However, as the caller of essiv may specify MAY_BACKLOG, we also need to expect EBUSY and treat it in the same way. Otherwise backlogged requests will trigger a use-after-free. Fixes: be1eb7f78aa8 ("crypto: essiv - create wrapper template...") Signed-off-by: Herbert Xu Acked-by: Ard Biesheuvel Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/essiv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crypto/essiv.c b/crypto/essiv.c index d012be23d496..85bb624e32b9 100644 --- a/crypto/essiv.c +++ b/crypto/essiv.c @@ -170,7 +170,12 @@ static void essiv_aead_done(struct crypto_async_request *areq, int err) struct aead_request *req = areq->data; struct essiv_aead_request_ctx *rctx = aead_request_ctx(req); + if (err == -EINPROGRESS) + goto out; + kfree(rctx->assoc); + +out: aead_request_complete(req, err); } @@ -246,7 +251,7 @@ static int essiv_aead_crypt(struct aead_request *req, bool enc) err = enc ? crypto_aead_encrypt(subreq) : crypto_aead_decrypt(subreq); - if (rctx->assoc && err != -EINPROGRESS) + if (rctx->assoc && err != -EINPROGRESS && err != -EBUSY) kfree(rctx->assoc); return err; } From ae849d2f48019ff9c104e32bf588ccbfb200e971 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 13 Jan 2023 18:27:51 +0800 Subject: [PATCH 0211/1017] crypto: seqiv - Handle EBUSY correctly [ Upstream commit 32e62025e5e52fbe4812ef044759de7010b15dbc ] As it is seqiv only handles the special return value of EINPROGERSS, which means that in all other cases it will free data related to the request. However, as the caller of seqiv may specify MAY_BACKLOG, we also need to expect EBUSY and treat it in the same way. Otherwise backlogged requests will trigger a use-after-free. Fixes: 0a270321dbf9 ("[CRYPTO] seqiv: Add Sequence Number IV Generator") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/seqiv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/seqiv.c b/crypto/seqiv.c index 0899d527c284..b1bcfe537daf 100644 --- a/crypto/seqiv.c +++ b/crypto/seqiv.c @@ -23,7 +23,7 @@ static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err) struct aead_request *subreq = aead_request_ctx(req); struct crypto_aead *geniv; - if (err == -EINPROGRESS) + if (err == -EINPROGRESS || err == -EBUSY) return; if (err) From 0e7a569929acdea82e56f0d0c2f45ff85dc25161 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 3 Jan 2023 20:57:26 +0800 Subject: [PATCH 0212/1017] powercap: fix possible name leak in powercap_register_zone() [ Upstream commit 1b6599f741a4525ca761ecde46e5885ff1e6ba58 ] In the error path after calling dev_set_name(), the device name is leaked. To fix this, calling dev_set_name() before device_register(), and call put_device() if it returns error. All the resources is released in powercap_release(), so it can return from powercap_register_zone() directly. Fixes: 75d2364ea0ca ("PowerCap: Add class driver") Signed-off-by: Yang Yingliang Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/powercap/powercap_sys.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 3f0b8e2ef3d4..7a3109a53881 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -530,9 +530,6 @@ struct powercap_zone *powercap_register_zone( power_zone->name = kstrdup(name, GFP_KERNEL); if (!power_zone->name) goto err_name_alloc; - dev_set_name(&power_zone->dev, "%s:%x", - dev_name(power_zone->dev.parent), - power_zone->id); power_zone->constraints = kcalloc(nr_constraints, sizeof(*power_zone->constraints), GFP_KERNEL); @@ -555,9 +552,16 @@ struct powercap_zone *powercap_register_zone( power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group; power_zone->dev_attr_groups[1] = NULL; power_zone->dev.groups = power_zone->dev_attr_groups; + dev_set_name(&power_zone->dev, "%s:%x", + dev_name(power_zone->dev.parent), + power_zone->id); result = device_register(&power_zone->dev); - if (result) - goto err_dev_ret; + if (result) { + put_device(&power_zone->dev); + mutex_unlock(&control_type->lock); + + return ERR_PTR(result); + } control_type->nr_zones++; mutex_unlock(&control_type->lock); From 2e3bd75f64d2f844a0f8c7b2d80eba17d1959677 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 10 May 2021 23:29:25 +0200 Subject: [PATCH 0213/1017] x86/cpu: Init AP exception handling from cpu_init_secondary() [ Upstream commit b1efd0ff4bd16e8bb8607ba566b03f2024a830bb ] SEV-ES guests require properly setup task register with which the TSS descriptor in the GDT can be located so that the IST-type #VC exception handler which they need to function properly, can be executed. This setup needs to happen before attempting to load microcode in ucode_cpu_init() on secondary CPUs which can cause such #VC exceptions. Simplify the machinery by running that exception setup from a new function cpu_init_secondary() and explicitly call cpu_init_exception_handling() for the boot CPU before cpu_init(). The latter prepares for fixing and simplifying the exception/IST setup on the boot CPU. There should be no functional changes resulting from this patch. [ tglx: Reworked it so cpu_init_exception_handling() stays seperate ] Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Reviewed-by: Lai Jiangshan Acked-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/87k0o6gtvu.ffs@nanos.tec.linutronix.de Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/include/asm/processor.h | 1 + arch/x86/kernel/cpu/common.c | 28 +++++++++++++++------------- arch/x86/kernel/smpboot.c | 3 +-- arch/x86/kernel/traps.c | 4 +--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index d428d611a43a..388541ec77aa 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -682,6 +682,7 @@ extern void load_direct_gdt(int); extern void load_fixmap_gdt(int); extern void load_percpu_segment(int); extern void cpu_init(void); +extern void cpu_init_secondary(void); extern void cpu_init_exception_handling(void); extern void cr4_init(void); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 56573241d029..4402589a1ee1 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2048,13 +2048,12 @@ void cpu_init_exception_handling(void) /* * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. + * initialized (naturally) in the bootstrap process, such as the GDT. We + * reload it nevertheless, this function acts as a 'CPU state barrier', + * nothing should get across. */ void cpu_init(void) { - struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw); struct task_struct *cur = current; int cpu = raw_smp_processor_id(); @@ -2067,8 +2066,6 @@ void cpu_init(void) early_cpu_to_node(cpu) != NUMA_NO_NODE) set_numa_node(early_cpu_to_node(cpu)); #endif - setup_getcpu(cpu); - pr_debug("Initializing CPU#%d\n", cpu); if (IS_ENABLED(CONFIG_X86_64) || cpu_feature_enabled(X86_FEATURE_VME) || @@ -2080,7 +2077,6 @@ void cpu_init(void) * and set up the GDT descriptor: */ switch_to_new_gdt(cpu); - load_current_idt(); if (IS_ENABLED(CONFIG_X86_64)) { loadsegment(fs, 0); @@ -2100,12 +2096,6 @@ void cpu_init(void) initialize_tlbstate_and_flush(); enter_lazy_tlb(&init_mm, cur); - /* Initialize the TSS. */ - tss_setup_ist(tss); - tss_setup_io_bitmap(tss); - set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss); - - load_TR_desc(); /* * sp0 points to the entry trampoline stack regardless of what task * is running. @@ -2127,6 +2117,18 @@ void cpu_init(void) load_fixmap_gdt(cpu); } +#ifdef CONFIG_SMP +void cpu_init_secondary(void) +{ + /* + * Relies on the BP having set-up the IDT tables, which are loaded + * on this CPU in cpu_init_exception_handling(). + */ + cpu_init_exception_handling(); + cpu_init(); +} +#endif + /* * The microcode loader calls this upon late microcode load to recheck features, * only when microcode has been updated. Caller holds microcode_mutex and CPU diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index e8e5515fb7e9..bda89ecc7799 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -227,8 +227,7 @@ static void notrace start_secondary(void *unused) load_cr3(swapper_pg_dir); __flush_tlb_all(); #endif - cpu_init_exception_handling(); - cpu_init(); + cpu_init_secondary(); rcu_cpu_starting(raw_smp_processor_id()); x86_cpuinit.early_percpu_clock_init(); smp_callin(); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 2a39a2df6f43..3780c728345c 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -1185,9 +1185,7 @@ void __init trap_init(void) idt_setup_traps(); - /* - * Should be a barrier for any external CPU state: - */ + cpu_init_exception_handling(); cpu_init(); idt_setup_ist_traps(); From 3900b7de1df724bc8d70c8d48ff6dab39611b6d4 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 3 Aug 2021 16:15:51 +0200 Subject: [PATCH 0214/1017] x86/microcode: Replace deprecated CPU-hotplug functions. [ Upstream commit 2089f34f8c5b91f7235023ec72e71e3247261ecc ] The functions get_online_cpus() and put_online_cpus() have been deprecated during the CPU hotplug rework. They map directly to cpus_read_lock() and cpus_read_unlock(). Replace deprecated CPU-hotplug functions with the official version. The behavior remains unchanged. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20210803141621.780504-9-bigeasy@linutronix.de Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/microcode/core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 0b1732b98e71..38a58819c1b9 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -55,7 +55,7 @@ LIST_HEAD(microcode_cache); * All non cpu-hotplug-callback call sites use: * * - microcode_mutex to synchronize with each other; - * - get/put_online_cpus() to synchronize with + * - cpus_read_lock/unlock() to synchronize with * the cpu-hotplug-callback call sites. * * We guarantee that only a single cpu is being @@ -431,7 +431,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf, return ret; } - get_online_cpus(); + cpus_read_lock(); mutex_lock(µcode_mutex); if (do_microcode_update(buf, len) == 0) @@ -441,7 +441,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf, perf_check_microcode(); mutex_unlock(µcode_mutex); - put_online_cpus(); + cpus_read_unlock(); return ret; } @@ -629,7 +629,7 @@ static ssize_t reload_store(struct device *dev, if (val != 1) return size; - get_online_cpus(); + cpus_read_lock(); ret = check_online_cpus(); if (ret) @@ -644,7 +644,7 @@ static ssize_t reload_store(struct device *dev, mutex_unlock(µcode_mutex); put: - put_online_cpus(); + cpus_read_unlock(); if (ret == 0) ret = size; @@ -853,14 +853,14 @@ int __init microcode_init(void) if (IS_ERR(microcode_pdev)) return PTR_ERR(microcode_pdev); - get_online_cpus(); + cpus_read_lock(); mutex_lock(µcode_mutex); error = subsys_interface_register(&mc_cpu_interface); if (!error) perf_check_microcode(); mutex_unlock(µcode_mutex); - put_online_cpus(); + cpus_read_unlock(); if (error) goto out_pdev; @@ -892,13 +892,13 @@ int __init microcode_init(void) &cpu_root_microcode_group); out_driver: - get_online_cpus(); + cpus_read_lock(); mutex_lock(µcode_mutex); subsys_interface_unregister(&mc_cpu_interface); mutex_unlock(µcode_mutex); - put_online_cpus(); + cpus_read_unlock(); out_pdev: platform_device_unregister(microcode_pdev); From 8078a170baab3696dba1b6a2bd48ec59aefaacdc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 8 Mar 2022 16:30:47 +0100 Subject: [PATCH 0215/1017] x86: Mark stop_this_cpu() __noreturn [ Upstream commit f9cdf7ca57cada055f61ef6d0eb4db21c3f200db ] vmlinux.o: warning: objtool: smp_stop_nmi_callback()+0x2b: unreachable instruction 0000 0000000000047cf0 : ... 0026 47d16: e8 00 00 00 00 call 47d1b 47d17: R_X86_64_PLT32 stop_this_cpu-0x4 002b 47d1b: b8 01 00 00 00 mov $0x1,%eax Signed-off-by: Peter Zijlstra (Intel) Acked-by: Josh Poimboeuf Link: https://lore.kernel.org/r/20220308154319.290905453@infradead.org Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/process.c | 2 +- tools/objtool/check.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 388541ec77aa..01bcbf8a25b2 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -839,7 +839,7 @@ bool xen_set_default_idle(void); #define xen_set_default_idle 0 #endif -void stop_this_cpu(void *dummy); +void __noreturn stop_this_cpu(void *dummy); void microcode_check(void); enum l1tf_mitigations { diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 5e17c3939dd1..1cba09a9f1c1 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -720,7 +720,7 @@ bool xen_set_default_idle(void) } #endif -void stop_this_cpu(void *dummy) +void __noreturn stop_this_cpu(void *dummy) { local_irq_disable(); /* diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 985bcc5cea8a..ff47aed7ef6f 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -180,6 +180,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, "kunit_try_catch_throw", "xen_start_kernel", "cpu_bringup_and_idle", + "stop_this_cpu", }; if (!func) From 9e56938f207241512aab787b17c88c96dc150b90 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 25 May 2022 18:12:29 +0200 Subject: [PATCH 0216/1017] x86/microcode: Rip out the OLD_INTERFACE [ Upstream commit 181b6f40e9ea80c76756d4d0cdeed396016c487e ] Everything should be using the early initrd loading by now. Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20220525161232.14924-2-bp@alien8.de Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/Kconfig | 12 ---- arch/x86/kernel/cpu/microcode/core.c | 100 --------------------------- 2 files changed, 112 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d64e69013995..1f55fc647037 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1329,18 +1329,6 @@ config MICROCODE_AMD If you select this option, microcode patch loading support for AMD processors will be enabled. -config MICROCODE_OLD_INTERFACE - bool "Ancient loading interface (DEPRECATED)" - default n - depends on MICROCODE - help - DO NOT USE THIS! This is the ancient /dev/cpu/microcode interface - which was used by userspace tools like iucode_tool and microcode.ctl. - It is inadequate because it runs too late to be able to properly - load microcode on a machine and it needs special tools. Instead, you - should've switched to the early loading method with the initrd or - builtin microcode by now: Documentation/x86/microcode.rst - config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" help diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 38a58819c1b9..8d8d7ee47e1c 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -390,98 +390,6 @@ static int apply_microcode_on_target(int cpu) return ret; } -#ifdef CONFIG_MICROCODE_OLD_INTERFACE -static int do_microcode_update(const void __user *buf, size_t size) -{ - int error = 0; - int cpu; - - for_each_online_cpu(cpu) { - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - enum ucode_state ustate; - - if (!uci->valid) - continue; - - ustate = microcode_ops->request_microcode_user(cpu, buf, size); - if (ustate == UCODE_ERROR) { - error = -1; - break; - } else if (ustate == UCODE_NEW) { - apply_microcode_on_target(cpu); - } - } - - return error; -} - -static int microcode_open(struct inode *inode, struct file *file) -{ - return capable(CAP_SYS_RAWIO) ? stream_open(inode, file) : -EPERM; -} - -static ssize_t microcode_write(struct file *file, const char __user *buf, - size_t len, loff_t *ppos) -{ - ssize_t ret = -EINVAL; - unsigned long nr_pages = totalram_pages(); - - if ((len >> PAGE_SHIFT) > nr_pages) { - pr_err("too much data (max %ld pages)\n", nr_pages); - return ret; - } - - cpus_read_lock(); - mutex_lock(µcode_mutex); - - if (do_microcode_update(buf, len) == 0) - ret = (ssize_t)len; - - if (ret > 0) - perf_check_microcode(); - - mutex_unlock(µcode_mutex); - cpus_read_unlock(); - - return ret; -} - -static const struct file_operations microcode_fops = { - .owner = THIS_MODULE, - .write = microcode_write, - .open = microcode_open, - .llseek = no_llseek, -}; - -static struct miscdevice microcode_dev = { - .minor = MICROCODE_MINOR, - .name = "microcode", - .nodename = "cpu/microcode", - .fops = µcode_fops, -}; - -static int __init microcode_dev_init(void) -{ - int error; - - error = misc_register(µcode_dev); - if (error) { - pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR); - return error; - } - - return 0; -} - -static void __exit microcode_dev_exit(void) -{ - misc_deregister(µcode_dev); -} -#else -#define microcode_dev_init() 0 -#define microcode_dev_exit() do { } while (0) -#endif - /* fake device for request_firmware */ static struct platform_device *microcode_pdev; @@ -873,10 +781,6 @@ int __init microcode_init(void) goto out_driver; } - error = microcode_dev_init(); - if (error) - goto out_ucode_group; - register_syscore_ops(&mc_syscore_ops); cpuhp_setup_state_nocalls(CPUHP_AP_MICROCODE_LOADER, "x86/microcode:starting", mc_cpu_starting, NULL); @@ -887,10 +791,6 @@ int __init microcode_init(void) return 0; - out_ucode_group: - sysfs_remove_group(&cpu_subsys.dev_root->kobj, - &cpu_root_microcode_group); - out_driver: cpus_read_lock(); mutex_lock(µcode_mutex); From e6230806681fa25b7a3829c021d5b33d68c9bd09 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 25 May 2022 18:12:30 +0200 Subject: [PATCH 0217/1017] x86/microcode: Default-disable late loading [ Upstream commit a77a94f86273ce42a39cb479217dd8d68acfe0ff ] It is dangerous and it should not be used anyway - there's a nice early loading already. Requested-by: Peter Zijlstra (Intel) Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20220525161232.14924-3-bp@alien8.de Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/Kconfig | 11 +++++++++++ arch/x86/kernel/cpu/common.c | 2 ++ arch/x86/kernel/cpu/microcode/core.c | 7 ++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1f55fc647037..2284666e8c90 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1329,6 +1329,17 @@ config MICROCODE_AMD If you select this option, microcode patch loading support for AMD processors will be enabled. +config MICROCODE_LATE_LOADING + bool "Late microcode loading (DANGEROUS)" + default n + depends on MICROCODE + help + Loading microcode late, when the system is up and executing instructions + is a tricky business and should be avoided if possible. Just the sequence + of synchronizing all cores and SMT threads is one fragile dance which does + not guarantee that cores might not softlock after the loading. Therefore, + use this at your own risk. Late loading taints the kernel too. + config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" help diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4402589a1ee1..95f52540db37 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2129,6 +2129,7 @@ void cpu_init_secondary(void) } #endif +#ifdef CONFIG_MICROCODE_LATE_LOADING /* * The microcode loader calls this upon late microcode load to recheck features, * only when microcode has been updated. Caller holds microcode_mutex and CPU @@ -2158,6 +2159,7 @@ void microcode_check(void) pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n"); pr_warn("x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update.\n"); } +#endif /* * Invoked from core CPU hotplug code after hotplug operations diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 8d8d7ee47e1c..5b27030714e4 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -393,6 +393,7 @@ static int apply_microcode_on_target(int cpu) /* fake device for request_firmware */ static struct platform_device *microcode_pdev; +#ifdef CONFIG_MICROCODE_LATE_LOADING /* * Late loading dance. Why the heavy-handed stomp_machine effort? * @@ -560,6 +561,9 @@ put: return ret; } +static DEVICE_ATTR_WO(reload); +#endif + static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -576,7 +580,6 @@ static ssize_t pf_show(struct device *dev, return sprintf(buf, "0x%x\n", uci->cpu_sig.pf); } -static DEVICE_ATTR_WO(reload); static DEVICE_ATTR(version, 0444, version_show, NULL); static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL); @@ -729,7 +732,9 @@ static int mc_cpu_down_prep(unsigned int cpu) } static struct attribute *cpu_root_microcode_attrs[] = { +#ifdef CONFIG_MICROCODE_LATE_LOADING &dev_attr_reload.attr, +#endif NULL }; From f5e78fa916aafe2dbcb323ee8b436f3e81cf0aec Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Mon, 29 Aug 2022 18:10:30 +0000 Subject: [PATCH 0218/1017] x86/microcode: Print previous version of microcode after reload [ Upstream commit 7fce8d6eccbc31a561d07c79f359ad09f0424347 ] Print both old and new versions of microcode after a reload is complete because knowing the previous microcode version is sometimes important from a debugging perspective. [ bp: Massage commit message. ] Signed-off-by: Ashok Raj Signed-off-by: Borislav Petkov Acked-by: Tony Luck Link: https://lore.kernel.org/r/20220829181030.722891-1-ashok.raj@intel.com Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/microcode/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 5b27030714e4..707a385943b4 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -508,7 +508,7 @@ wait_for_siblings: */ static int microcode_reload_late(void) { - int ret; + int old = boot_cpu_data.microcode, ret; atomic_set(&late_cpus_in, 0); atomic_set(&late_cpus_out, 0); @@ -517,7 +517,8 @@ static int microcode_reload_late(void) if (ret == 0) microcode_check(); - pr_info("Reload completed, microcode revision: 0x%x\n", boot_cpu_data.microcode); + pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n", + old, boot_cpu_data.microcode); return ret; } From 89e848bb4aa140e701eb0d017736ce5d1ee198da Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Mon, 9 Jan 2023 07:35:50 -0800 Subject: [PATCH 0219/1017] x86/microcode: Add a parameter to microcode_check() to store CPU capabilities [ Upstream commit ab31c74455c64e69342ddab21fd9426fcbfefde7 ] Add a parameter to store CPU capabilities before performing a microcode update so that CPU capabilities can be compared before and after update. [ bp: Massage. ] Signed-off-by: Ashok Raj Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230109153555.4986-2-ashok.raj@intel.com Stable-dep-of: c0dd9245aa9e ("x86/microcode: Check CPU capabilities after late microcode update correctly") Signed-off-by: Sasha Levin --- arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/cpu/common.c | 21 +++++++++++++-------- arch/x86/kernel/cpu/microcode/core.c | 3 ++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 01bcbf8a25b2..6d40c409ebc1 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -840,7 +840,7 @@ bool xen_set_default_idle(void); #endif void __noreturn stop_this_cpu(void *dummy); -void microcode_check(void); +void microcode_check(struct cpuinfo_x86 *prev_info); enum l1tf_mitigations { L1TF_MITIGATION_OFF, diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 95f52540db37..f724002adbfc 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2130,30 +2130,35 @@ void cpu_init_secondary(void) #endif #ifdef CONFIG_MICROCODE_LATE_LOADING -/* +/** + * microcode_check() - Check if any CPU capabilities changed after an update. + * @prev_info: CPU capabilities stored before an update. + * * The microcode loader calls this upon late microcode load to recheck features, * only when microcode has been updated. Caller holds microcode_mutex and CPU * hotplug lock. + * + * Return: None */ -void microcode_check(void) +void microcode_check(struct cpuinfo_x86 *prev_info) { - struct cpuinfo_x86 info; - perf_check_microcode(); /* Reload CPUID max function as it might've changed. */ - info.cpuid_level = cpuid_eax(0); + prev_info->cpuid_level = cpuid_eax(0); /* * Copy all capability leafs to pick up the synthetic ones so that * memcmp() below doesn't fail on that. The ones coming from CPUID will * get overwritten in get_cpu_cap(). */ - memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability)); + memcpy(&prev_info->x86_capability, &boot_cpu_data.x86_capability, + sizeof(prev_info->x86_capability)); - get_cpu_cap(&info); + get_cpu_cap(prev_info); - if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability))) + if (!memcmp(&prev_info->x86_capability, &boot_cpu_data.x86_capability, + sizeof(prev_info->x86_capability))) return; pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n"); diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 707a385943b4..2c70f3cfae68 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -509,13 +509,14 @@ wait_for_siblings: static int microcode_reload_late(void) { int old = boot_cpu_data.microcode, ret; + struct cpuinfo_x86 prev_info; atomic_set(&late_cpus_in, 0); atomic_set(&late_cpus_out, 0); ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask); if (ret == 0) - microcode_check(); + microcode_check(&prev_info); pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n", old, boot_cpu_data.microcode); From 511e27e5fdd658e6cb06b4947fb0d3ac76163776 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Mon, 9 Jan 2023 07:35:51 -0800 Subject: [PATCH 0220/1017] x86/microcode: Check CPU capabilities after late microcode update correctly [ Upstream commit c0dd9245aa9e25a697181f6085692272c9ec61bc ] The kernel caches each CPU's feature bits at boot in an x86_capability[] structure. However, the capabilities in the BSP's copy can be turned off as a result of certain command line parameters or configuration restrictions, for example the SGX bit. This can cause a mismatch when comparing the values before and after the microcode update. Another example is X86_FEATURE_SRBDS_CTRL which gets added only after microcode update: # --- cpuid.before 2023-01-21 14:54:15.652000747 +0100 # +++ cpuid.after 2023-01-21 14:54:26.632001024 +0100 # @@ -10,7 +10,7 @@ CPU: # 0x00000004 0x04: eax=0x00000000 ebx=0x00000000 ecx=0x00000000 edx=0x00000000 # 0x00000005 0x00: eax=0x00000040 ebx=0x00000040 ecx=0x00000003 edx=0x11142120 # 0x00000006 0x00: eax=0x000027f7 ebx=0x00000002 ecx=0x00000001 edx=0x00000000 # - 0x00000007 0x00: eax=0x00000000 ebx=0x029c6fbf ecx=0x40000000 edx=0xbc002400 # + 0x00000007 0x00: eax=0x00000000 ebx=0x029c6fbf ecx=0x40000000 edx=0xbc002e00 ^^^ and which proves for a gazillionth time that late loading is a bad bad idea. microcode_check() is called after an update to report any previously cached CPUID bits which might have changed due to the update. Therefore, store the cached CPU caps before the update and compare them with the CPU caps after the microcode update has succeeded. Thus, the comparison is done between the CPUID *hardware* bits before and after the upgrade instead of using the cached, possibly runtime modified values in BSP's boot_cpu_data copy. As a result, false warnings about CPUID bits changes are avoided. [ bp: - Massage. - Add SRBDS_CTRL example. - Add kernel-doc. - Incorporate forgotten review feedback from dhansen. ] Fixes: 1008c52c09dc ("x86/CPU: Add a microcode loader callback") Signed-off-by: Ashok Raj Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230109153555.4986-3-ashok.raj@intel.com Signed-off-by: Sasha Levin --- arch/x86/include/asm/processor.h | 1 + arch/x86/kernel/cpu/common.c | 36 ++++++++++++++++++---------- arch/x86/kernel/cpu/microcode/core.c | 6 +++++ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 6d40c409ebc1..60514502ead6 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -841,6 +841,7 @@ bool xen_set_default_idle(void); void __noreturn stop_this_cpu(void *dummy); void microcode_check(struct cpuinfo_x86 *prev_info); +void store_cpu_caps(struct cpuinfo_x86 *info); enum l1tf_mitigations { L1TF_MITIGATION_OFF, diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f724002adbfc..e2dee6010846 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2130,6 +2130,25 @@ void cpu_init_secondary(void) #endif #ifdef CONFIG_MICROCODE_LATE_LOADING +/** + * store_cpu_caps() - Store a snapshot of CPU capabilities + * @curr_info: Pointer where to store it + * + * Returns: None + */ +void store_cpu_caps(struct cpuinfo_x86 *curr_info) +{ + /* Reload CPUID max function as it might've changed. */ + curr_info->cpuid_level = cpuid_eax(0); + + /* Copy all capability leafs and pick up the synthetic ones. */ + memcpy(&curr_info->x86_capability, &boot_cpu_data.x86_capability, + sizeof(curr_info->x86_capability)); + + /* Get the hardware CPUID leafs */ + get_cpu_cap(curr_info); +} + /** * microcode_check() - Check if any CPU capabilities changed after an update. * @prev_info: CPU capabilities stored before an update. @@ -2142,22 +2161,13 @@ void cpu_init_secondary(void) */ void microcode_check(struct cpuinfo_x86 *prev_info) { + struct cpuinfo_x86 curr_info; + perf_check_microcode(); - /* Reload CPUID max function as it might've changed. */ - prev_info->cpuid_level = cpuid_eax(0); + store_cpu_caps(&curr_info); - /* - * Copy all capability leafs to pick up the synthetic ones so that - * memcmp() below doesn't fail on that. The ones coming from CPUID will - * get overwritten in get_cpu_cap(). - */ - memcpy(&prev_info->x86_capability, &boot_cpu_data.x86_capability, - sizeof(prev_info->x86_capability)); - - get_cpu_cap(prev_info); - - if (!memcmp(&prev_info->x86_capability, &boot_cpu_data.x86_capability, + if (!memcmp(&prev_info->x86_capability, &curr_info.x86_capability, sizeof(prev_info->x86_capability))) return; diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 2c70f3cfae68..122da99bac4e 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -514,6 +514,12 @@ static int microcode_reload_late(void) atomic_set(&late_cpus_in, 0); atomic_set(&late_cpus_out, 0); + /* + * Take a snapshot before the microcode update in order to compare and + * check whether any bits changed after an update. + */ + store_cpu_caps(&prev_info); + ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask); if (ret == 0) microcode_check(&prev_info); From 8e83e1619fac9151b1515177f5066ae67b0cbda2 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Mon, 9 Jan 2023 07:35:52 -0800 Subject: [PATCH 0221/1017] x86/microcode: Adjust late loading result reporting message [ Upstream commit 6eab3abac7043226e5375e9ead0c7607ced6767b ] During late microcode loading, the "Reload completed" message is issued unconditionally, regardless of success or failure. Adjust the message to report the result of the update. [ bp: Massage. ] Fixes: 9bd681251b7c ("x86/microcode: Announce reload operation's completion") Suggested-by: Thomas Gleixner Signed-off-by: Ashok Raj Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Tony Luck Link: https://lore.kernel.org/lkml/874judpqqd.ffs@tglx/ Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/microcode/core.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 122da99bac4e..36583bc4b88c 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -521,11 +521,14 @@ static int microcode_reload_late(void) store_cpu_caps(&prev_info); ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask); - if (ret == 0) + if (!ret) { + pr_info("Reload succeeded, microcode revision: 0x%x -> 0x%x\n", + old, boot_cpu_data.microcode); microcode_check(&prev_info); - - pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n", - old, boot_cpu_data.microcode); + } else { + pr_info("Reload failed, current microcode revision: 0x%x\n", + boot_cpu_data.microcode); + } return ret; } From 37f0ca73fe81305bc889d8d765bbb6f8756b53b5 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 30 Oct 2020 22:07:04 +0200 Subject: [PATCH 0222/1017] net: ethernet: ti: am65-cpsw: fix tx csum offload for multi mac mode [ Upstream commit 97067aaf127487788a297267dede0008cd75bb7b ] The current implementation uses .ndo_set_features() callback to track NETIF_F_HW_CSUM feature changes and update generic CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option accordingly. It's not going to work in case of multi-port devices as TX csum offload can be changed per netdev. On K3 CPSWxG devices TX csum offload enabled in the following way: - the CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option enables TX csum offload in generic and affects all TX DMA channels and packets; - corresponding fields in TX DMA descriptor have to be filed properly when upper layer wants to offload TX csum (skb->ip_summed == CHECKSUM_PARTIAL) and it's per-packet option. The Linux Network core is expected to never request TX csum offload if netdev NETIF_F_HW_CSUM feature is disabled, and, as result, TX DMA descriptors should not be modified, and per-packet TX csum offload will be disabled (or enabled) on per-netdev basis. Which, in turn, makes it safe to enable the CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option unconditionally. Hence, fix TX csum offload for multi-port devices by: - enabling the CPSW_P0_CONTROL_REG.RX_CHECKSUM_EN option in am65_cpsw_nuss_common_open() unconditionally - and removing .ndo_set_features() callback implementation, which was used only NETIF_F_HW_CSUM feature update purposes Signed-off-by: Grygorii Strashko Reviewed-by: Jesse Brandeburg Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 30 +----------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 059d68d48f1e..487c1570dd42 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -426,9 +426,7 @@ static int am65_cpsw_nuss_common_open(struct am65_cpsw_common *common, writel(common->rx_flow_id_base, host_p->port_base + AM65_CPSW_PORT0_REG_FLOW_ID_OFFSET); /* en tx crc offload */ - if (features & NETIF_F_HW_CSUM) - writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN, - host_p->port_base + AM65_CPSW_P0_REG_CTL); + writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN, host_p->port_base + AM65_CPSW_P0_REG_CTL); am65_cpsw_nuss_set_p0_ptype(common); @@ -1369,31 +1367,6 @@ static void am65_cpsw_nuss_ndo_get_stats(struct net_device *dev, stats->tx_dropped = dev->stats.tx_dropped; } -static int am65_cpsw_nuss_ndo_slave_set_features(struct net_device *ndev, - netdev_features_t features) -{ - struct am65_cpsw_common *common = am65_ndev_to_common(ndev); - netdev_features_t changes = features ^ ndev->features; - struct am65_cpsw_host *host_p; - - host_p = am65_common_get_host(common); - - if (changes & NETIF_F_HW_CSUM) { - bool enable = !!(features & NETIF_F_HW_CSUM); - - dev_info(common->dev, "Turn %s tx-checksum-ip-generic\n", - enable ? "ON" : "OFF"); - if (enable) - writel(AM65_CPSW_P0_REG_CTL_RX_CHECKSUM_EN, - host_p->port_base + AM65_CPSW_P0_REG_CTL); - else - writel(0, - host_p->port_base + AM65_CPSW_P0_REG_CTL); - } - - return 0; -} - static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = { .ndo_open = am65_cpsw_nuss_ndo_slave_open, .ndo_stop = am65_cpsw_nuss_ndo_slave_stop, @@ -1406,7 +1379,6 @@ static const struct net_device_ops am65_cpsw_nuss_netdev_ops_2g = { .ndo_vlan_rx_add_vid = am65_cpsw_nuss_ndo_slave_add_vid, .ndo_vlan_rx_kill_vid = am65_cpsw_nuss_ndo_slave_kill_vid, .ndo_do_ioctl = am65_cpsw_nuss_ndo_slave_ioctl, - .ndo_set_features = am65_cpsw_nuss_ndo_slave_set_features, .ndo_setup_tc = am65_cpsw_qos_ndo_setup_tc, }; From 80c81aafc998a551d41f7efbcfa27aff7cec6ef5 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Fri, 30 Oct 2020 22:07:07 +0200 Subject: [PATCH 0223/1017] net: ethernet: ti: am65-cpsw: handle deferred probe with dev_err_probe() [ Upstream commit 8fbc2f9edce23d19fc09ef5bf8d4eb38be2db0f8 ] Use new dev_err_probe() API to handle deferred probe properly and simplify the code. Signed-off-by: Grygorii Strashko Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 28 +++++++++--------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 487c1570dd42..5300e1439e1e 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -1487,9 +1487,8 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common) tx_chn->tx_chn_name, &tx_cfg); if (IS_ERR(tx_chn->tx_chn)) { - ret = PTR_ERR(tx_chn->tx_chn); - dev_err(dev, "Failed to request tx dma channel %d\n", - ret); + ret = dev_err_probe(dev, PTR_ERR(tx_chn->tx_chn), + "Failed to request tx dma channel\n"); goto err; } @@ -1560,8 +1559,8 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common) rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, "rx", &rx_cfg); if (IS_ERR(rx_chn->rx_chn)) { - ret = PTR_ERR(rx_chn->rx_chn); - dev_err(dev, "Failed to request rx dma channel %d\n", ret); + ret = dev_err_probe(dev, PTR_ERR(rx_chn->rx_chn), + "Failed to request rx dma channel\n"); goto err; } @@ -1768,12 +1767,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) /* get phy/link info */ if (of_phy_is_fixed_link(port_np)) { ret = of_phy_register_fixed_link(port_np); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "%pOF failed to register fixed-link phy: %d\n", - port_np, ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "failed to register fixed-link phy %pOF\n", + port_np); port->slave.phy_node = of_node_get(port_np); } else { port->slave.phy_node = @@ -2062,13 +2059,8 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) return -ENOMEM; clk = devm_clk_get(dev, "fck"); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - - if (ret != -EPROBE_DEFER) - dev_err(dev, "error getting fck clock %d\n", ret); - return ret; - } + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "getting fck clock\n"); common->bus_freq = clk_get_rate(clk); pm_runtime_enable(dev); From 119848416480f70d57d7cff7597391f2c2735838 Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Mon, 13 Dec 2021 01:44:36 -0800 Subject: [PATCH 0224/1017] net: ethernet: ti: add missing of_node_put before return [ Upstream commit be565ec71d1d59438bed0c7ed0a252a327e0b0ef ] Fix following coccicheck warning: WARNING: Function "for_each_child_of_node" should have of_node_put() before return. Early exits from for_each_child_of_node should decrement the node reference counter. Signed-off-by: Wang Qing Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 29 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 5300e1439e1e..4074310abcff 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -1724,13 +1724,14 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) if (ret < 0) { dev_err(dev, "%pOF error reading port_id %d\n", port_np, ret); - return ret; + goto of_node_put; } if (!port_id || port_id > common->port_num) { dev_err(dev, "%pOF has invalid port_id %u %s\n", port_np, port_id, port_np->name); - return -EINVAL; + ret = -EINVAL; + goto of_node_put; } port = am65_common_get_port(common, port_id); @@ -1746,8 +1747,10 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) (AM65_CPSW_NU_FRAM_PORT_OFFSET * (port_id - 1)); port->slave.mac_sl = cpsw_sl_get("am65", dev, port->port_base); - if (IS_ERR(port->slave.mac_sl)) - return PTR_ERR(port->slave.mac_sl); + if (IS_ERR(port->slave.mac_sl)) { + ret = PTR_ERR(port->slave.mac_sl); + goto of_node_put; + } port->disabled = !of_device_is_available(port_np); if (port->disabled) @@ -1758,7 +1761,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) ret = PTR_ERR(port->slave.ifphy); dev_err(dev, "%pOF error retrieving port phy: %d\n", port_np, ret); - return ret; + goto of_node_put; } port->slave.mac_only = @@ -1767,10 +1770,12 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) /* get phy/link info */ if (of_phy_is_fixed_link(port_np)) { ret = of_phy_register_fixed_link(port_np); - if (ret) - return dev_err_probe(dev, ret, + if (ret) { + ret = dev_err_probe(dev, ret, "failed to register fixed-link phy %pOF\n", port_np); + goto of_node_put; + } port->slave.phy_node = of_node_get(port_np); } else { port->slave.phy_node = @@ -1780,14 +1785,15 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) if (!port->slave.phy_node) { dev_err(dev, "slave[%d] no phy found\n", port_id); - return -ENODEV; + ret = -ENODEV; + goto of_node_put; } ret = of_get_phy_mode(port_np, &port->slave.phy_if); if (ret) { dev_err(dev, "%pOF read phy-mode err %d\n", port_np, ret); - return ret; + goto of_node_put; } mac_addr = of_get_mac_address(port_np); @@ -1804,6 +1810,11 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) of_node_put(node); return 0; + +of_node_put: + of_node_put(port_np); + of_node_put(node); + return ret; } static void am65_cpsw_pcpu_stats_free(void *data) From 92a07ba4f0af2cccdc2aa5ee32679c9c9714db90 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 22 Jan 2023 16:07:37 +0800 Subject: [PATCH 0225/1017] crypto: xts - Handle EBUSY correctly [ Upstream commit 51c082514c2dedf2711c99d93c196cc4eedceb40 ] As it is xts only handles the special return value of EINPROGRESS, which means that in all other cases it will free data related to the request. However, as the caller of xts may specify MAY_BACKLOG, we also need to expect EBUSY and treat it in the same way. Otherwise backlogged requests will trigger a use-after-free. Fixes: 8083b1bf8163 ("crypto: xts - add support for ciphertext stealing") Signed-off-by: Herbert Xu Acked-by: Ard Biesheuvel Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/xts.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index ad45b009774b..c6a105dba38b 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -202,12 +202,12 @@ static void xts_encrypt_done(struct crypto_async_request *areq, int err) if (!err) { struct xts_request_ctx *rctx = skcipher_request_ctx(req); - rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; err = xts_xor_tweak_post(req, true); if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) { err = xts_cts_final(req, crypto_skcipher_encrypt); - if (err == -EINPROGRESS) + if (err == -EINPROGRESS || err == -EBUSY) return; } } @@ -222,12 +222,12 @@ static void xts_decrypt_done(struct crypto_async_request *areq, int err) if (!err) { struct xts_request_ctx *rctx = skcipher_request_ctx(req); - rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->subreq.base.flags &= CRYPTO_TFM_REQ_MAY_BACKLOG; err = xts_xor_tweak_post(req, false); if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) { err = xts_cts_final(req, crypto_skcipher_decrypt); - if (err == -EINPROGRESS) + if (err == -EINPROGRESS || err == -EBUSY) return; } } From 6952629bed36a0ba0dd4bedf8d4d799bdae757ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 20 Jan 2023 12:45:14 +0100 Subject: [PATCH 0226/1017] leds: led-class: Add missing put_device() to led_put() [ Upstream commit 445110941eb94709216363f9d807d2508e64abd7 ] led_put() is used to "undo" a successful of_led_get() call, of_led_get() uses class_find_device_by_of_node() which returns a reference to the device which must be free-ed with put_device() when the caller is done with it. Add a put_device() call to led_put() to free the reference returned by class_find_device_by_of_node(). And also add a put_device() in the error-exit case of try_module_get() failing. Fixes: 699a8c7c4bd3 ("leds: Add of_led_get() and led_put()") Reviewed-by: Andy Shevchenko Reviewed-by: Linus Walleij Signed-off-by: Hans de Goede Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20230120114524.408368-2-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/leds/led-class.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 4365c1cc4505..e28a4bb71603 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -242,8 +242,10 @@ struct led_classdev *of_led_get(struct device_node *np, int index) led_cdev = dev_get_drvdata(led_dev); - if (!try_module_get(led_cdev->dev->parent->driver->owner)) + if (!try_module_get(led_cdev->dev->parent->driver->owner)) { + put_device(led_cdev->dev); return ERR_PTR(-ENODEV); + } return led_cdev; } @@ -256,6 +258,7 @@ EXPORT_SYMBOL_GPL(of_led_get); void led_put(struct led_classdev *led_cdev) { module_put(led_cdev->dev->parent->driver->owner); + put_device(led_cdev->dev); } EXPORT_SYMBOL_GPL(led_put); From 959bd9d42a839809b00c7243037919d61b4b7763 Mon Sep 17 00:00:00 2001 From: Peter Gonda Date: Tue, 7 Dec 2021 15:33:04 -0800 Subject: [PATCH 0227/1017] crypto: ccp - Refactor out sev_fw_alloc() [ Upstream commit cc17982d58d1e67eab831e7023ede999dda56173 ] Create a helper function sev_fw_alloc() which can be used to allocate aligned memory regions for use by the PSP firmware. Currently only used for the SEV-ES TMR region but will be used for the SEV_INIT_EX NV memory region. Signed-off-by: Peter Gonda Reviewed-by: Marc Orr Acked-by: David Rientjes Acked-by: Brijesh Singh Cc: Tom Lendacky Cc: Brijesh Singh Cc: Marc Orr Cc: Joerg Roedel Cc: Herbert Xu Cc: David Rientjes Cc: John Allen Cc: "David S. Miller" Cc: Paolo Bonzini Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Herbert Xu Stable-dep-of: 46a334a98f58 ("crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware") Signed-off-by: Sasha Levin --- drivers/crypto/ccp/sev-dev.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index e70ae98de118..8a900226d73a 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -138,6 +138,17 @@ static int sev_cmd_buffer_len(int cmd) return 0; } +static void *sev_fw_alloc(unsigned long len) +{ + struct page *page; + + page = alloc_pages(GFP_KERNEL, get_order(len)); + if (!page) + return NULL; + + return page_address(page); +} + static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) { struct psp_device *psp = psp_master; @@ -1040,7 +1051,6 @@ EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user); void sev_pci_init(void) { struct sev_device *sev = psp_master->sev_data; - struct page *tmr_page; int error, rc; if (!sev) @@ -1056,14 +1066,10 @@ void sev_pci_init(void) sev_get_api_version(); /* Obtain the TMR memory area for SEV-ES use */ - tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_SIZE)); - if (tmr_page) { - sev_es_tmr = page_address(tmr_page); - } else { - sev_es_tmr = NULL; + sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE); + if (!sev_es_tmr) dev_warn(sev->dev, "SEV: TMR allocation failed, SEV-ES support unavailable\n"); - } /* Initialize the platform */ rc = sev_platform_init(&error); From 627e140a5b7df4ec285271b8566720a3990732b8 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Mon, 23 Jan 2023 16:53:08 -0600 Subject: [PATCH 0228/1017] crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware [ Upstream commit 46a334a98f585ef78d51d8f5736596887bdd7f54 ] Perform a cache flush on the SEV-ES TMR memory after allocation to prevent any possibility of the firmware encountering an error should dirty cache lines be present. Use clflush_cache_range() to flush the SEV-ES TMR memory. Fixes: 97f9ac3db661 ("crypto: ccp - Add support for SEV-ES to the PSP driver") Signed-off-by: Tom Lendacky Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/sev-dev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 8a900226d73a..856d867f46eb 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -23,6 +23,7 @@ #include #include +#include #include "psp-dev.h" #include "sev-dev.h" @@ -1067,7 +1068,10 @@ void sev_pci_init(void) /* Obtain the TMR memory area for SEV-ES use */ sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE); - if (!sev_es_tmr) + if (sev_es_tmr) + /* Must flush the cache before giving it to the firmware */ + clflush_cache_range(sev_es_tmr, SEV_ES_TMR_SIZE); + else dev_warn(sev->dev, "SEV: TMR allocation failed, SEV-ES support unavailable\n"); From 94c4eafbbde36de86685a78526ab52c2b5c2cd56 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Thu, 2 Feb 2023 21:17:01 +0800 Subject: [PATCH 0229/1017] bpftool: profile online CPUs instead of possible [ Upstream commit 377c16fa3f3c60d21e4b05314c8be034ce37f2eb ] The number of online cpu may be not equal to possible cpu. "bpftool prog profile" can not create pmu event on possible but on online cpu. $ dmidecode -s system-product-name PowerEdge R620 $ cat /sys/devices/system/cpu/possible 0-47 $ cat /sys/devices/system/cpu/online 0-31 Disable cpu dynamically: $ echo 0 > /sys/devices/system/cpu/cpuX/online If one cpu is offline, perf_event_open will return ENODEV. To fix this issue: * check value returned and skip offline cpu. * close pmu_fd immediately on error path, avoid fd leaking. Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command") Signed-off-by: Tonghao Zhang Cc: Quentin Monnet Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Andrii Nakryiko Cc: Martin KaFai Lau Cc: Song Liu Cc: Yonghong Song Cc: John Fastabend Cc: KP Singh Cc: Stanislav Fomichev Cc: Hao Luo Cc: Jiri Olsa Acked-by: John Fastabend Link: https://lore.kernel.org/r/20230202131701.29519-1-tong@infragraf.org Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- tools/bpf/bpftool/prog.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 592536904dde..d2bcce627b32 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -1912,10 +1912,38 @@ static void profile_close_perf_events(struct profiler_bpf *obj) profile_perf_event_cnt = 0; } +static int profile_open_perf_event(int mid, int cpu, int map_fd) +{ + int pmu_fd; + + pmu_fd = syscall(__NR_perf_event_open, &metrics[mid].attr, + -1 /*pid*/, cpu, -1 /*group_fd*/, 0); + if (pmu_fd < 0) { + if (errno == ENODEV) { + p_info("cpu %d may be offline, skip %s profiling.", + cpu, metrics[mid].name); + profile_perf_event_cnt++; + return 0; + } + return -1; + } + + if (bpf_map_update_elem(map_fd, + &profile_perf_event_cnt, + &pmu_fd, BPF_ANY) || + ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) { + close(pmu_fd); + return -1; + } + + profile_perf_events[profile_perf_event_cnt++] = pmu_fd; + return 0; +} + static int profile_open_perf_events(struct profiler_bpf *obj) { unsigned int cpu, m; - int map_fd, pmu_fd; + int map_fd; profile_perf_events = calloc( sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric); @@ -1934,17 +1962,11 @@ static int profile_open_perf_events(struct profiler_bpf *obj) if (!metrics[m].selected) continue; for (cpu = 0; cpu < obj->rodata->num_cpu; cpu++) { - pmu_fd = syscall(__NR_perf_event_open, &metrics[m].attr, - -1/*pid*/, cpu, -1/*group_fd*/, 0); - if (pmu_fd < 0 || - bpf_map_update_elem(map_fd, &profile_perf_event_cnt, - &pmu_fd, BPF_ANY) || - ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0)) { + if (profile_open_perf_event(m, cpu, map_fd)) { p_err("failed to create event %s on cpu %d", metrics[m].name, cpu); return -1; } - profile_perf_events[profile_perf_event_cnt++] = pmu_fd; } } return 0; From 9cc2a41c5804e2de2cbc74cfeceff0606b23896b Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Wed, 18 Jan 2023 19:57:04 +0200 Subject: [PATCH 0230/1017] net/mlx5: Enhance debug print in page allocation failure [ Upstream commit 7eef93003e5d20e1a6a6e59e12d914b5431cbda2 ] Provide more details to aid debugging. Fixes: bf0bf77f6519 ("mlx5: Support communicating arbitrary host page size to firmware") Signed-off-by: Eran Ben Elisha Signed-off-by: Majd Dibbiny Signed-off-by: Jack Morgenstein Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index a44a2bad5bbb..1ea71f06fdb1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -216,7 +216,8 @@ static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr, u32 function) n = find_first_bit(&fp->bitmask, 8 * sizeof(fp->bitmask)); if (n >= MLX5_NUM_4K_IN_PAGE) { - mlx5_core_warn(dev, "alloc 4k bug\n"); + mlx5_core_warn(dev, "alloc 4k bug: fw page = 0x%llx, n = %u, bitmask: %lu, max num of 4K pages: %d\n", + fp->addr, n, fp->bitmask, MLX5_NUM_4K_IN_PAGE); return -ENOENT; } clear_bit(n, &fp->bitmask); From b00baffcc2561374f8fe8af873d00531f19864eb Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 16:13:18 +0400 Subject: [PATCH 0231/1017] irqchip: Fix refcount leak in platform_irqchip_probe [ Upstream commit 6caa5a2b78f5f53c433d3a3781e53325da22f0ac ] of_irq_find_parent() returns a node pointer with refcount incremented, We should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak. Fixes: f8410e626569 ("irqchip: Add IRQCHIP_PLATFORM_DRIVER_BEGIN/END and IRQCHIP_MATCH helper macros") Signed-off-by: Miaoqian Lin Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230102121318.3990586-1-linmq006@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irqchip.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index 3570f0a588c4..7899607fbee8 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c @@ -38,8 +38,10 @@ int platform_irqchip_probe(struct platform_device *pdev) struct device_node *par_np = of_irq_find_parent(np); of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); - if (!irq_init_cb) + if (!irq_init_cb) { + of_node_put(par_np); return -EINVAL; + } if (par_np == np) par_np = NULL; @@ -52,8 +54,10 @@ int platform_irqchip_probe(struct platform_device *pdev) * interrupt controller. The actual initialization callback of this * interrupt controller can check for specific domains as necessary. */ - if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { + of_node_put(par_np); return -EPROBE_DEFER; + } return irq_init_cb(np, par_np); } From c9aaf4efe1f02b2fef21a69fb3652f5ad12a5710 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 12:28:10 +0400 Subject: [PATCH 0232/1017] irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains [ Upstream commit 071d068b89e95d1b078aa6bbcb9d0961b77d6aa1 ] of_irq_find_parent() returns a node pointer with refcount incremented, We should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak. Fixes: e6b78f2c3e14 ("irqchip: Add the Alpine MSIX interrupt controller") Signed-off-by: Miaoqian Lin Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230102082811.3947760-1-linmq006@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irq-alpine-msi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c index ede02dc2bcd0..1819bb1d2723 100644 --- a/drivers/irqchip/irq-alpine-msi.c +++ b/drivers/irqchip/irq-alpine-msi.c @@ -199,6 +199,7 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv, } gic_domain = irq_find_host(gic_node); + of_node_put(gic_node); if (!gic_domain) { pr_err("Failed to find the GIC domain\n"); return -ENXIO; From cee12e8be8e227731a845ae43a4c9ce2e404be45 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 12:42:08 +0400 Subject: [PATCH 0233/1017] irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe [ Upstream commit 9419e700021a393f67be36abd0c4f3acc6139041 ] of_irq_find_parent() returns a node pointer with refcount incremented, We should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak. Fixes: a68a63cb4dfc ("irqchip/irq-mvebu-gicp: Add new driver for Marvell GICP") Signed-off-by: Miaoqian Lin Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230102084208.3951758-1-linmq006@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irq-mvebu-gicp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c index 3be5c5dba1da..5caec411059f 100644 --- a/drivers/irqchip/irq-mvebu-gicp.c +++ b/drivers/irqchip/irq-mvebu-gicp.c @@ -223,6 +223,7 @@ static int mvebu_gicp_probe(struct platform_device *pdev) } parent_domain = irq_find_host(irq_parent_dn); + of_node_put(irq_parent_dn); if (!parent_domain) { dev_err(&pdev->dev, "failed to find parent IRQ domain\n"); return -ENODEV; From df8d3536b660c6c6f6b25fa8b157e9b38ad78142 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 12:56:10 +0400 Subject: [PATCH 0234/1017] irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe [ Upstream commit 02298b7bae12936ca313975b02e7f98b06670d37 ] of_irq_find_parent() returns a node pointer with refcount incremented, We should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak. Fixes: cd844b0715ce ("irqchip/ti-sci-intr: Add support for Interrupt Router driver") Signed-off-by: Miaoqian Lin Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230102085611.3955984-1-linmq006@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irq-ti-sci-intr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c index fe8fad22bcf9..020ddf29efb8 100644 --- a/drivers/irqchip/irq-ti-sci-intr.c +++ b/drivers/irqchip/irq-ti-sci-intr.c @@ -236,6 +236,7 @@ static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev) } parent_domain = irq_find_host(parent_node); + of_node_put(parent_node); if (!parent_domain) { dev_err(dev, "Failed to find IRQ parent domain\n"); return -ENODEV; From 4a614a68d9f87b22b4177e5e255a0ab90239b20d Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Sat, 28 Jan 2023 17:35:12 +0100 Subject: [PATCH 0235/1017] s390/vmem: fix empty page tables cleanup under KASAN [ Upstream commit 108303b0a2d27cb14eed565e33e64ad9eefe5d7e ] Commit b9ff81003cf1 ("s390/vmem: cleanup empty page tables") introduced empty page tables cleanup in vmem code, but when the kernel is built with KASAN enabled the code has no effect due to wrong KASAN shadow memory intersection condition, which effectively ignores any memory range below KASAN shadow. Fix intersection condition to make code work as anticipated. Fixes: b9ff81003cf1 ("s390/vmem: cleanup empty page tables") Reviewed-by: Alexander Gordeev Signed-off-by: Vasily Gorbik Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin --- arch/s390/mm/vmem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index b239f2ba93b0..cbfff2460e58 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -296,7 +296,7 @@ static void try_free_pmd_table(pud_t *pud, unsigned long start) if (end > VMALLOC_START) return; #ifdef CONFIG_KASAN - if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end) + if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START) return; #endif pmd = pmd_offset(pud, start); @@ -371,7 +371,7 @@ static void try_free_pud_table(p4d_t *p4d, unsigned long start) if (end > VMALLOC_START) return; #ifdef CONFIG_KASAN - if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end) + if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START) return; #endif @@ -425,7 +425,7 @@ static void try_free_p4d_table(pgd_t *pgd, unsigned long start) if (end > VMALLOC_START) return; #ifdef CONFIG_KASAN - if (start < KASAN_SHADOW_END && KASAN_SHADOW_START > end) + if (start < KASAN_SHADOW_END && end > KASAN_SHADOW_START) return; #endif From 2416abd6bad28b8de107ccffe55095812369dd2b Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sat, 4 Feb 2023 17:39:20 +0000 Subject: [PATCH 0236/1017] net: add sock_init_data_uid() [ Upstream commit 584f3742890e966d2f0a1f3c418c9ead70b2d99e ] Add sock_init_data_uid() to explicitly initialize the socket uid. To initialise the socket uid, sock_init_data() assumes a the struct socket* sock is always embedded in a struct socket_alloc, used to access the corresponding inode uid. This may not be true. Examples are sockets created in tun_chr_open() and tap_open(). Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.") Signed-off-by: Pietro Borrello Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/sock.h | 7 ++++++- net/core/sock.c | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 0f48d50a6dde..1d8529311d6f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1775,7 +1775,12 @@ void sk_common_release(struct sock *sk); * Default socket callbacks and setup code */ -/* Initialise core socket variables */ +/* Initialise core socket variables using an explicit uid. */ +void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid); + +/* Initialise core socket variables. + * Assumes struct socket *sock is embedded in a struct socket_alloc. + */ void sock_init_data(struct socket *sock, struct sock *sk); /* diff --git a/net/core/sock.c b/net/core/sock.c index 1bb6a003323b..c5ae520d4a69 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2968,7 +2968,7 @@ void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer) } EXPORT_SYMBOL(sk_stop_timer_sync); -void sock_init_data(struct socket *sock, struct sock *sk) +void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid) { sk_init_common(sk); sk->sk_send_head = NULL; @@ -2987,11 +2987,10 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_type = sock->type; RCU_INIT_POINTER(sk->sk_wq, &sock->wq); sock->sk = sk; - sk->sk_uid = SOCK_INODE(sock)->i_uid; } else { RCU_INIT_POINTER(sk->sk_wq, NULL); - sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0); } + sk->sk_uid = uid; rwlock_init(&sk->sk_callback_lock); if (sk->sk_kern_sock) @@ -3049,6 +3048,16 @@ void sock_init_data(struct socket *sock, struct sock *sk) refcount_set(&sk->sk_refcnt, 1); atomic_set(&sk->sk_drops, 0); } +EXPORT_SYMBOL(sock_init_data_uid); + +void sock_init_data(struct socket *sock, struct sock *sk) +{ + kuid_t uid = sock ? + SOCK_INODE(sock)->i_uid : + make_kuid(sock_net(sk)->user_ns, 0); + + sock_init_data_uid(sock, sk, uid); +} EXPORT_SYMBOL(sock_init_data); void lock_sock_nested(struct sock *sk, int subclass) From 9a31af61f397500ccae49d56d809b2217d1e2178 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sat, 4 Feb 2023 17:39:21 +0000 Subject: [PATCH 0237/1017] tun: tun_chr_open(): correctly initialize socket uid [ Upstream commit a096ccca6e503a5c575717ff8a36ace27510ab0a ] sock_init_data() assumes that the `struct socket` passed in input is contained in a `struct socket_alloc` allocated with sock_alloc(). However, tun_chr_open() passes a `struct socket` embedded in a `struct tun_file` allocated with sk_alloc(). This causes a type confusion when issuing a container_of() with SOCK_INODE() in sock_init_data() which results in assigning a wrong sk_uid to the `struct sock` in input. On default configuration, the type confused field overlaps with the high 4 bytes of `struct tun_struct __rcu *tun` of `struct tun_file`, NULL at the time of call, which makes the uid of all tun sockets 0, i.e., the root one. Fix the assignment by using sock_init_data_uid(). Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.") Signed-off-by: Pietro Borrello Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 67ce7b779af6..f1d46aea8a2b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -3457,7 +3457,7 @@ static int tun_chr_open(struct inode *inode, struct file * file) tfile->socket.file = file; tfile->socket.ops = &tun_socket_ops; - sock_init_data(&tfile->socket, &tfile->sk); + sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid); tfile->sk.sk_write_space = tun_sock_write_space; tfile->sk.sk_sndbuf = INT_MAX; From 4a9272a864cbf6dacc3f4b35213108dd01691d31 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sat, 4 Feb 2023 17:39:22 +0000 Subject: [PATCH 0238/1017] tap: tap_open(): correctly initialize socket uid [ Upstream commit 66b2c338adce580dfce2199591e65e2bab889cff ] sock_init_data() assumes that the `struct socket` passed in input is contained in a `struct socket_alloc` allocated with sock_alloc(). However, tap_open() passes a `struct socket` embedded in a `struct tap_queue` allocated with sk_alloc(). This causes a type confusion when issuing a container_of() with SOCK_INODE() in sock_init_data() which results in assigning a wrong sk_uid to the `struct sock` in input. On default configuration, the type confused field overlaps with padding bytes between `int vnet_hdr_sz` and `struct tap_dev __rcu *tap` in `struct tap_queue`, which makes the uid of all tap sockets 0, i.e., the root one. Fix the assignment by using sock_init_data_uid(). Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.") Signed-off-by: Pietro Borrello Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/tap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 8f7bb15206e9..d9018d9fe310 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -523,7 +523,7 @@ static int tap_open(struct inode *inode, struct file *file) q->sock.state = SS_CONNECTED; q->sock.file = file; q->sock.ops = &tap_socket_ops; - sock_init_data(&q->sock, &q->sk); + sock_init_data_uid(&q->sock, &q->sk, inode->i_uid); q->sk.sk_write_space = tap_sock_write_space; q->sk.sk_destruct = tap_sock_destruct; q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; From 4f4c970a05a24f4e3ecbfda534ec95caf498d2a0 Mon Sep 17 00:00:00 2001 From: Qi Zheng Date: Wed, 8 Feb 2023 12:00:37 +0800 Subject: [PATCH 0239/1017] OPP: fix error checking in opp_migrate_dentry() [ Upstream commit eca4c0eea53432ec4b711b2a8ad282cbad231b4f ] Since commit ff9fb72bc077 ("debugfs: return error values, not NULL") changed return value of debugfs_rename() in error cases from %NULL to %ERR_PTR(-ERROR), we should also check error values instead of NULL. Fixes: ff9fb72bc077 ("debugfs: return error values, not NULL") Signed-off-by: Qi Zheng Signed-off-by: Viresh Kumar Signed-off-by: Sasha Levin --- drivers/opp/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c index 596c185b5dda..60f4ff8e044d 100644 --- a/drivers/opp/debugfs.c +++ b/drivers/opp/debugfs.c @@ -204,7 +204,7 @@ static void opp_migrate_dentry(struct opp_device *opp_dev, dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir, opp_table->dentry_name); - if (!dentry) { + if (IS_ERR(dentry)) { dev_err(dev, "%s: Failed to rename link from: %s to %s\n", __func__, dev_name(opp_dev->dev), dev_name(dev)); return; From b8ed41cc04fb74005aa51d17865ca3d022760335 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 1 Feb 2023 14:01:11 -0800 Subject: [PATCH 0240/1017] Bluetooth: L2CAP: Fix potential user-after-free [ Upstream commit df5703348813235874d851934e957c3723d71644 ] This fixes all instances of which requires to allocate a buffer calling alloc_skb which may release the chan lock and reacquire later which makes it possible that the chan is disconnected in the meantime. Fixes: a6a5568c03c4 ("Bluetooth: Lock the L2CAP channel when sending") Reported-by: Alexander Coffin Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_core.c | 24 ------------------------ net/bluetooth/l2cap_sock.c | 8 ++++++++ 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index cf56582d298a..bde90df6b497 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2679,14 +2679,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) if (IS_ERR(skb)) return PTR_ERR(skb); - /* Channel lock is released before requesting new skb and then - * reacquired thus we need to recheck channel state. - */ - if (chan->state != BT_CONNECTED) { - kfree_skb(skb); - return -ENOTCONN; - } - l2cap_do_send(chan, skb); return len; } @@ -2731,14 +2723,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) if (IS_ERR(skb)) return PTR_ERR(skb); - /* Channel lock is released before requesting new skb and then - * reacquired thus we need to recheck channel state. - */ - if (chan->state != BT_CONNECTED) { - kfree_skb(skb); - return -ENOTCONN; - } - l2cap_do_send(chan, skb); err = len; break; @@ -2759,14 +2743,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) */ err = l2cap_segment_sdu(chan, &seg_queue, msg, len); - /* The channel could have been closed while segmenting, - * check that it is still connected. - */ - if (chan->state != BT_CONNECTED) { - __skb_queue_purge(&seg_queue); - err = -ENOTCONN; - } - if (err) break; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d2c678520599..a267c9b6bcef 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1623,6 +1623,14 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, if (!skb) return ERR_PTR(err); + /* Channel lock is released before requesting new skb and then + * reacquired thus we need to recheck channel state. + */ + if (chan->state != BT_CONNECTED) { + kfree_skb(skb); + return ERR_PTR(-ENOTCONN); + } + skb->priority = sk->sk_priority; bt_cb(skb)->l2cap.chan = chan; From b7aa7fbc16936efa5171b8038848e18acdbab63d Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 10 Feb 2023 01:12:01 +0100 Subject: [PATCH 0241/1017] libbpf: Fix alen calculation in libbpf_nla_dump_errormsg() [ Upstream commit 17bcd27a08a21397698edf143084d7c87ce17946 ] The code assumes that everything that comes after nlmsgerr are nlattrs. When calculating their size, it does not account for the initial nlmsghdr. This may lead to accessing uninitialized memory. Fixes: bbf48c18ee0c ("libbpf: add error reporting in XDP") Signed-off-by: Ilya Leoshkevich Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20230210001210.395194-8-iii@linux.ibm.com Signed-off-by: Sasha Levin --- tools/lib/bpf/nlattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c index b607fa9852b1..1a04299a2a60 100644 --- a/tools/lib/bpf/nlattr.c +++ b/tools/lib/bpf/nlattr.c @@ -178,7 +178,7 @@ int libbpf_nla_dump_errormsg(struct nlmsghdr *nlh) hlen += nlmsg_len(&err->msg); attr = (struct nlattr *) ((void *) err + hlen); - alen = nlh->nlmsg_len - hlen; + alen = (void *)nlh + nlh->nlmsg_len - (void *)attr; if (libbpf_nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen, extack_policy) != 0) { From eb209a35d3627b6345bea0f07020c99897a2ca87 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Thu, 9 Feb 2023 12:26:23 +0000 Subject: [PATCH 0242/1017] rds: rds_rm_zerocopy_callback() correct order for list_add_tail() [ Upstream commit 68762148d1b011d47bc2ceed7321739b5aea1e63 ] rds_rm_zerocopy_callback() uses list_add_tail() with swapped arguments. This links the list head with the new entry, losing the references to the remaining part of the list. Fixes: 9426bbc6de99 ("rds: use list structure to track information for zerocopy completion notification") Suggested-by: Paolo Abeni Signed-off-by: Pietro Borrello Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/rds/message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/message.c b/net/rds/message.c index b363ef13c75e..8fa3d19c2e66 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -118,7 +118,7 @@ static void rds_rm_zerocopy_callback(struct rds_sock *rs, ck = &info->zcookies; memset(ck, 0, sizeof(*ck)); WARN_ON(!rds_zcookie_add(info, cookie)); - list_add_tail(&q->zcookie_head, &info->rs_zcookie_next); + list_add_tail(&info->rs_zcookie_next, &q->zcookie_head); spin_unlock_irqrestore(&q->lock, flags); /* caller invokes rds_wake_sk_sleep() */ From c9c87142260cd2278aaa432588788916e54d461c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 31 Jan 2023 16:02:04 +0800 Subject: [PATCH 0243/1017] crypto: rsa-pkcs1pad - Use akcipher_request_complete [ Upstream commit 564cabc0ca0bdfa8f0fc1ae74b24d0a7554522c5 ] Use the akcipher_request_complete helper instead of calling the completion function directly. In fact the previous code was buggy in that EINPROGRESS was never passed back to the original caller. Fixes: 3d5b1ecdea6f ("crypto: rsa - RSA padding algorithm") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/rsa-pkcs1pad.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 9d804831c8b3..a4ebbb889274 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -214,16 +214,14 @@ static void pkcs1pad_encrypt_sign_complete_cb( struct crypto_async_request *child_async_req, int err) { struct akcipher_request *req = child_async_req->data; - struct crypto_async_request async_req; if (err == -EINPROGRESS) - return; + goto out; - async_req.data = req->base.data; - async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req)); - async_req.flags = child_async_req->flags; - req->base.complete(&async_req, - pkcs1pad_encrypt_sign_complete(req, err)); + err = pkcs1pad_encrypt_sign_complete(req, err); + +out: + akcipher_request_complete(req, err); } static int pkcs1pad_encrypt(struct akcipher_request *req) @@ -332,15 +330,14 @@ static void pkcs1pad_decrypt_complete_cb( struct crypto_async_request *child_async_req, int err) { struct akcipher_request *req = child_async_req->data; - struct crypto_async_request async_req; if (err == -EINPROGRESS) - return; + goto out; - async_req.data = req->base.data; - async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req)); - async_req.flags = child_async_req->flags; - req->base.complete(&async_req, pkcs1pad_decrypt_complete(req, err)); + err = pkcs1pad_decrypt_complete(req, err); + +out: + akcipher_request_complete(req, err); } static int pkcs1pad_decrypt(struct akcipher_request *req) @@ -512,15 +509,14 @@ static void pkcs1pad_verify_complete_cb( struct crypto_async_request *child_async_req, int err) { struct akcipher_request *req = child_async_req->data; - struct crypto_async_request async_req; if (err == -EINPROGRESS) - return; + goto out; - async_req.data = req->base.data; - async_req.tfm = crypto_akcipher_tfm(crypto_akcipher_reqtfm(req)); - async_req.flags = child_async_req->flags; - req->base.complete(&async_req, pkcs1pad_verify_complete(req, err)); + err = pkcs1pad_verify_complete(req, err); + +out: + akcipher_request_complete(req, err); } /* From dabc22a30d83f97128992a8e1f9b8ee2f8a16f55 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 8 Feb 2023 17:08:25 -0800 Subject: [PATCH 0244/1017] m68k: /proc/hardware should depend on PROC_FS [ Upstream commit 1e5b5df65af99013b4d31607ddb3ca5731dbe44d ] When CONFIG_PROC_FS is not set, there is a build error for an unused function. Make PROC_HARDWARE depend on PROC_FS to prevent this error. In file included from ../arch/m68k/kernel/setup.c:3: ../arch/m68k/kernel/setup_mm.c:477:12: error: 'hardware_proc_show' defined but not used [-Werror=unused-function] 477 | static int hardware_proc_show(struct seq_file *m, void *v) | ^~~~~~~~~~~~~~~~~~ Fixes: 66d857b08b8c ("m68k: merge m68k and m68knommu arch directories") # v3.0 Signed-off-by: Randy Dunlap Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230209010825.24136-1-rdunlap@infradead.org Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/Kconfig.devices | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices index 6a87b4a5fcac..e6e3efac1840 100644 --- a/arch/m68k/Kconfig.devices +++ b/arch/m68k/Kconfig.devices @@ -19,6 +19,7 @@ config HEARTBEAT # We have a dedicated heartbeat LED. :-) config PROC_HARDWARE bool "/proc/hardware support" + depends on PROC_FS help Say Y here to support the /proc/hardware file, which gives you access to information about the machine you're running on, From 5da95a7eb9e3e045db4082fd906b40e67181c443 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 3 Jan 2023 19:41:00 +0530 Subject: [PATCH 0245/1017] RISC-V: time: initialize hrtimer based broadcast clock event device [ Upstream commit 8b3b8fbb4896984b5564789a42240e4b3caddb61 ] Similarly to commit 022eb8ae8b5e ("ARM: 8938/1: kernel: initialize broadcast hrtimer based clock event device"), RISC-V needs to initiate hrtimer based broadcast clock event device before C3STOP can be used. Otherwise, the introduction of C3STOP for the RISC-V arch timer in commit 232ccac1bd9b ("clocksource/drivers/riscv: Events are stopped during CPU suspend") leaves us without any broadcast timer registered. This prevents the kernel from entering oneshot mode, which breaks timer behaviour, for example clock_nanosleep(). A test app that sleeps each cpu for 6, 5, 4, 3 ms respectively, HZ=250 & C3STOP enabled, the sleep times are rounded up to the next jiffy: == CPU: 1 == == CPU: 2 == == CPU: 3 == == CPU: 4 == Mean: 7.974992 Mean: 7.976534 Mean: 7.962591 Mean: 3.952179 Std Dev: 0.154374 Std Dev: 0.156082 Std Dev: 0.171018 Std Dev: 0.076193 Hi: 9.472000 Hi: 10.495000 Hi: 8.864000 Hi: 4.736000 Lo: 6.087000 Lo: 6.380000 Lo: 4.872000 Lo: 3.403000 Samples: 521 Samples: 521 Samples: 521 Samples: 521 Link: https://lore.kernel.org/linux-riscv/YzYTNQRxLr7Q9JR0@spud/ Fixes: 232ccac1bd9b ("clocksource/drivers/riscv: Events are stopped during CPU suspend") Suggested-by: Samuel Holland Signed-off-by: Conor Dooley Signed-off-by: Anup Patel Reviewed-by: Samuel Holland Acked-by: Palmer Dabbelt Link: https://lore.kernel.org/r/20230103141102.772228-2-apatel@ventanamicro.com Signed-off-by: Daniel Lezcano Signed-off-by: Sasha Levin --- arch/riscv/kernel/time.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c index 8a5cf99c0776..303ae47dfb4d 100644 --- a/arch/riscv/kernel/time.c +++ b/arch/riscv/kernel/time.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -28,6 +29,8 @@ void __init time_init(void) of_clk_init(NULL); timer_probe(); + + tick_setup_hrtimer_broadcast(); } void clocksource_arch_init(struct clocksource *cs) From 2f80b3ff92514ebd227e5c55d3d1e480401b02b7 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Wed, 8 Feb 2023 14:30:32 +0800 Subject: [PATCH 0246/1017] wifi: iwl3945: Add missing check for create_singlethread_workqueue [ Upstream commit 1fdeb8b9f29dfd64805bb49475ac7566a3cb06cb ] Add the check for the return value of the create_singlethread_workqueue in order to avoid NULL pointer dereference. Fixes: b481de9ca074 ("[IWLWIFI]: add iwlwifi wireless drivers") Signed-off-by: Jiasheng Jiang Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230208063032.42763-2-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlegacy/3945-mac.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c index 4ca8212d4fa4..ef0ac42a55a2 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c @@ -3380,10 +3380,12 @@ static DEVICE_ATTR(dump_errors, 0200, NULL, il3945_dump_error_log); * *****************************************************************************/ -static void +static int il3945_setup_deferred_work(struct il_priv *il) { il->workqueue = create_singlethread_workqueue(DRV_NAME); + if (!il->workqueue) + return -ENOMEM; init_waitqueue_head(&il->wait_command_queue); @@ -3400,6 +3402,8 @@ il3945_setup_deferred_work(struct il_priv *il) timer_setup(&il->watchdog, il_bg_watchdog, 0); tasklet_setup(&il->irq_tasklet, il3945_irq_tasklet); + + return 0; } static void @@ -3721,7 +3725,10 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } il_set_rxon_channel(il, &il->bands[NL80211_BAND_2GHZ].channels[5]); - il3945_setup_deferred_work(il); + err = il3945_setup_deferred_work(il); + if (err) + goto out_remove_sysfs; + il3945_setup_handlers(il); il_power_initialize(il); @@ -3733,7 +3740,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = il3945_setup_mac(il); if (err) - goto out_remove_sysfs; + goto out_destroy_workqueue; il_dbgfs_register(il, DRV_NAME); @@ -3742,9 +3749,10 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; -out_remove_sysfs: +out_destroy_workqueue: destroy_workqueue(il->workqueue); il->workqueue = NULL; +out_remove_sysfs: sysfs_remove_group(&pdev->dev.kobj, &il3945_attribute_group); out_release_irq: free_irq(il->pci_dev->irq, il); From 3185d6cfc59277a77bf311dce701b7e25193f66a Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Thu, 9 Feb 2023 09:07:48 +0800 Subject: [PATCH 0247/1017] wifi: iwl4965: Add missing check for create_singlethread_workqueue() [ Upstream commit 26e6775f75517ad6844fe5b79bc5f3fa8c22ee61 ] Add the check for the return value of the create_singlethread_workqueue() in order to avoid NULL pointer dereference. Fixes: b481de9ca074 ("[IWLWIFI]: add iwlwifi wireless drivers") Signed-off-by: Jiasheng Jiang Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230209010748.45454-1-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlegacy/4965-mac.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index 28675a4ad861..12cf22d0e994 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -6212,10 +6212,12 @@ out: mutex_unlock(&il->mutex); } -static void +static int il4965_setup_deferred_work(struct il_priv *il) { il->workqueue = create_singlethread_workqueue(DRV_NAME); + if (!il->workqueue) + return -ENOMEM; init_waitqueue_head(&il->wait_command_queue); @@ -6234,6 +6236,8 @@ il4965_setup_deferred_work(struct il_priv *il) timer_setup(&il->watchdog, il_bg_watchdog, 0); tasklet_setup(&il->irq_tasklet, il4965_irq_tasklet); + + return 0; } static void @@ -6623,7 +6627,10 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable_msi; } - il4965_setup_deferred_work(il); + err = il4965_setup_deferred_work(il); + if (err) + goto out_free_irq; + il4965_setup_handlers(il); /********************************************* @@ -6661,6 +6668,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) out_destroy_workqueue: destroy_workqueue(il->workqueue); il->workqueue = NULL; +out_free_irq: free_irq(il->pci_dev->irq, il); out_disable_msi: pci_disable_msi(il->pci_dev); From d7c5ecbc4915be882a305e4aadf43857cca6eb93 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Feb 2023 17:41:33 +0300 Subject: [PATCH 0248/1017] wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize() [ Upstream commit 3cfb7df24cee0f5fdc4cc5d3176cab9aadfcb430 ] This code re-uses "i" to be the iterator for both the inside and outside loops. It means the outside loop will exit earlier than intended. Fixes: d219b7eb3792 ("mwifiex: handle BT coex event to adjust Rx BA window size") Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/Y+ERnaDaZD7RtLvX@kili Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/mwifiex/11n.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c index cf08a4af84d6..b99381ebb82a 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n.c +++ b/drivers/net/wireless/marvell/mwifiex/11n.c @@ -890,7 +890,7 @@ mwifiex_send_delba_txbastream_tbl(struct mwifiex_private *priv, u8 tid) */ void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter) { - u8 i; + u8 i, j; u32 tx_win_size; struct mwifiex_private *priv; @@ -921,8 +921,8 @@ void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter) if (tx_win_size != priv->add_ba_param.tx_win_size) { if (!priv->media_connected) continue; - for (i = 0; i < MAX_NUM_TID; i++) - mwifiex_send_delba_txbastream_tbl(priv, i); + for (j = 0; j < MAX_NUM_TID; j++) + mwifiex_send_delba_txbastream_tbl(priv, j); } } } From b10827bce73943b0823b26ef5aebc4b971733d50 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Thu, 9 Feb 2023 00:12:11 +0100 Subject: [PATCH 0249/1017] selftests/bpf: Fix out-of-srctree build [ Upstream commit 0b0757244754ea1d0721195c824770f5576e119e ] Building BPF selftests out of srctree fails with: make: *** No rule to make target '/linux-build//ima_setup.sh', needed by 'ima_setup.sh'. Stop. The culprit is the rule that defines convenient shorthands like "make test_progs", which builds $(OUTPUT)/test_progs. These shorthands make sense only for binaries that are built though; scripts that live in the source tree do not end up in $(OUTPUT). Therefore drop $(TEST_PROGS) and $(TEST_PROGS_EXTENDED) from the rule. The issue exists for a while, but it became a problem only after commit d68ae4982cb7 ("selftests/bpf: Install all required files to run selftests"), which added dependencies on these scripts. Fixes: 03dcb78460c2 ("selftests/bpf: Add simple per-test targets to Makefile") Signed-off-by: Ilya Leoshkevich Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20230208231211.283606-1-iii@linux.ibm.com Signed-off-by: Sasha Levin --- tools/testing/selftests/bpf/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 1d9155533360..a845724e0906 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -119,8 +119,6 @@ RESOLVE_BTFIDS := $(BUILD_DIR)/resolve_btfids/resolve_btfids # NOTE: Semicolon at the end is critical to override lib.mk's default static # rule for binaries. $(notdir $(TEST_GEN_PROGS) \ - $(TEST_PROGS) \ - $(TEST_PROGS_EXTENDED) \ $(TEST_GEN_PROGS_EXTENDED) \ $(TEST_CUSTOM_PROGS)): %: $(OUTPUT)/% ; From f333346001f9ea152d04b3848e77f986ab69e5aa Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 6 Feb 2023 14:01:53 +0800 Subject: [PATCH 0250/1017] crypto: crypto4xx - Call dma_unmap_page when done [ Upstream commit bcdda4301bdc4955d45f7e1ffefb6207967b067e ] In crypto4xx_cipher_done, we should be unmapping the dst page, not mapping it. This was flagged by a sparse warning about the unused addr variable. While we're at it, also fix a sparse warning regarding the unused ctx variable in crypto4xx_ahash_done (by actually using it). Fixes: 049359d65527 ("crypto: amcc - Add crypt4xx driver") Signed-off-by: Herbert Xu Tested-by: Christian Lamparter Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/amcc/crypto4xx_core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 2e3690f65786..6d05ac0c0513 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -522,7 +522,6 @@ static void crypto4xx_cipher_done(struct crypto4xx_device *dev, { struct skcipher_request *req; struct scatterlist *dst; - dma_addr_t addr; req = skcipher_request_cast(pd_uinfo->async_req); @@ -531,8 +530,8 @@ static void crypto4xx_cipher_done(struct crypto4xx_device *dev, req->cryptlen, req->dst); } else { dst = pd_uinfo->dest_va; - addr = dma_map_page(dev->core_dev->device, sg_page(dst), - dst->offset, dst->length, DMA_FROM_DEVICE); + dma_unmap_page(dev->core_dev->device, pd->dest, dst->length, + DMA_FROM_DEVICE); } if (pd_uinfo->sa_va->sa_command_0.bf.save_iv == SA_SAVE_IV) { @@ -557,10 +556,9 @@ static void crypto4xx_ahash_done(struct crypto4xx_device *dev, struct ahash_request *ahash_req; ahash_req = ahash_request_cast(pd_uinfo->async_req); - ctx = crypto_tfm_ctx(ahash_req->base.tfm); + ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(ahash_req)); - crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo, - crypto_tfm_ctx(ahash_req->base.tfm)); + crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo, ctx); crypto4xx_ret_sg_desc(dev, pd_uinfo); if (pd_uinfo->state & PD_ENTRY_BUSY) From 3856f7559722b76a66a3f59eb3217dfd7fcaca15 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Thu, 9 Feb 2023 19:06:59 +0800 Subject: [PATCH 0251/1017] wifi: mac80211: make rate u32 in sta_set_rate_info_rx() [ Upstream commit 59336e07b287d91dc4ec265e07724e8f7e3d0209 ] The value of last_rate in ieee80211_sta_rx_stats is degraded from u32 to u16 after being assigned to rate variable, which causes information loss in STA_STATS_FIELD_TYPE and later bitfields. Signed-off-by: Shayne Chen Link: https://lore.kernel.org/r/20230209110659.25447-1-shayne.chen@mediatek.com Fixes: 41cbb0f5a295 ("mac80211: add support for HE") Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index cee39ae52245..d572478c4d68 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2159,7 +2159,7 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate, static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) { - u16 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate); + u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate); if (rate == STA_STATS_RATE_INVALID) return -EINVAL; From e02bc492883abf751fd1a8d89fc025fbce6744c6 Mon Sep 17 00:00:00 2001 From: Yongqin Liu Date: Fri, 10 Feb 2023 22:15:07 +0800 Subject: [PATCH 0252/1017] thermal/drivers/hisi: Drop second sensor hi3660 [ Upstream commit 15cc25829a97c3957e520e971868aacc84341317 ] The commit 74c8e6bffbe1 ("driver core: Add __alloc_size hint to devm allocators") exposes a panic "BRK handler: Fatal exception" on the hi3660_thermal_probe funciton. This is because the function allocates memory for only one sensors array entry, but tries to fill up a second one. Fix this by removing the unneeded second access. Fixes: 7d3a2a2bbadb ("thermal/drivers/hisi: Fix number of sensors on hi3660") Signed-off-by: Yongqin Liu Link: https://lore.kernel.org/linux-mm/20221101223321.1326815-5-keescook@chromium.org/ Link: https://lore.kernel.org/r/20230210141507.71014-1-yongqin.liu@linaro.org Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/hisi_thermal.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index ee05950afd2f..7b1e81912ccf 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -435,10 +435,6 @@ static int hi3660_thermal_probe(struct hisi_thermal_data *data) data->sensor[0].irq_name = "tsensor_a73"; data->sensor[0].data = data; - data->sensor[1].id = HI3660_LITTLE_SENSOR; - data->sensor[1].irq_name = "tsensor_a53"; - data->sensor[1].data = data; - return 0; } From 3e8733949f81c5e95002f7365974adcef2ea3888 Mon Sep 17 00:00:00 2001 From: Frank Jungclaus Date: Thu, 16 Feb 2023 20:04:48 +0100 Subject: [PATCH 0253/1017] can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a bus error [ Upstream commit 118469f88180438ef43dee93d71f77c00e7b425d ] Move the supply for cf->data[3] (bit stream position of CAN error), in case of a bus- or protocol-error, outside of the "switch (ecc & SJA1000_ECC_MASK){}"-statement, because this bit stream position is independent of the error type. Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device") Signed-off-by: Frank Jungclaus Link: https://lore.kernel.org/all/20230216190450.3901254-2-frank.jungclaus@esd.eu Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- drivers/net/can/usb/esd_usb2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 73c5343e609b..c9ccce6c60b4 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -278,7 +278,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, cf->data[2] |= CAN_ERR_PROT_STUFF; break; default: - cf->data[3] = ecc & SJA1000_ECC_SEG; break; } @@ -286,6 +285,9 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, if (!(ecc & SJA1000_ECC_DIR)) cf->data[2] |= CAN_ERR_PROT_TX; + /* Bit stream position in CAN frame as the error was detected */ + cf->data[3] = ecc & SJA1000_ECC_SEG; + if (priv->can.state == CAN_STATE_ERROR_WARNING || priv->can.state == CAN_STATE_ERROR_PASSIVE) { cf->data[1] = (txerr > rxerr) ? From 9f487d888ee5cddc6d78c16ae6cd554ceda78a78 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Wed, 15 Feb 2023 20:59:52 -0800 Subject: [PATCH 0254/1017] bpf: Fix global subprog context argument resolution logic [ Upstream commit d384dce281ed1b504fae2e279507827638d56fa3 ] KPROBE program's user-facing context type is defined as typedef bpf_user_pt_regs_t. This leads to a problem when trying to passing kprobe/uprobe/usdt context argument into global subprog, as kernel always strip away mods and typedefs of user-supplied type, but takes expected type from bpf_ctx_convert as is, which causes mismatch. Current way to work around this is to define a fake struct with the same name as expected typedef: struct bpf_user_pt_regs_t {}; __noinline my_global_subprog(struct bpf_user_pt_regs_t *ctx) { ... } This patch fixes the issue by resolving expected type, if it's not a struct. It still leaves the above work-around working for backwards compatibility. Fixes: 91cc1a99740e ("bpf: Annotate context types") Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Acked-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20230216045954.3002473-2-andrii@kernel.org Signed-off-by: Sasha Levin --- kernel/bpf/btf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 52e704860739..11b612e94e4e 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -4273,6 +4273,7 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf, if (!ctx_struct) /* should not happen */ return NULL; +again: ctx_tname = btf_name_by_offset(btf_vmlinux, ctx_struct->name_off); if (!ctx_tname) { /* should not happen */ @@ -4286,8 +4287,16 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, struct btf *btf, * int socket_filter_bpf_prog(struct __sk_buff *skb) * { // no fields of skb are ever used } */ - if (strcmp(ctx_tname, tname)) - return NULL; + if (strcmp(ctx_tname, tname)) { + /* bpf_user_pt_regs_t is a typedef, so resolve it to + * underlying struct and check name again + */ + if (!btf_type_is_modifier(ctx_struct)) + return NULL; + while (btf_type_is_modifier(ctx_struct)) + ctx_struct = btf_type_by_id(btf_vmlinux, ctx_struct->type); + goto again; + } return ctx_type; } From 27a601623dde64da601dc4a881691ee592cfaab0 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 16 Dec 2022 15:09:33 -0800 Subject: [PATCH 0255/1017] irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 94debe03e8afa1267f95a9001786a6aa506b9ff3 ] When support for the level triggered interrupt controller flavor was added with c0ca7262088e, we forgot to update the flags to be set to contain IRQ_LEVEL. While the flow handler is correct, the output from /proc/interrupts does not show such interrupts as being level triggered when they are, correct that. Fixes: c0ca7262088e ("irqchip/brcmstb-l2: Add support for the BCM7271 L2 controller") Signed-off-by: Florian Fainelli Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20221216230934.2478345-2-f.fainelli@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irq-brcmstb-l2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index cdd6a42d4efa..a4aee16db531 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -161,6 +161,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, *init_params) { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; struct brcmstb_l2_intc_data *data; struct irq_chip_type *ct; int ret; @@ -208,9 +209,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) flags |= IRQ_GC_BE_IO; + if (init_params->handler == handle_level_irq) + set |= IRQ_LEVEL; + /* Allocate a single Generic IRQ chip for this node */ ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, - np->full_name, init_params->handler, clr, 0, flags); + np->full_name, init_params->handler, clr, set, flags); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; From 7cefa692224a94ae65ef844037c74119ad13f855 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 16 Dec 2022 15:09:34 -0800 Subject: [PATCH 0256/1017] irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 13a157b38ca5b4f9eed81442b8821db293755961 ] When support for the interrupt controller was added with a5042de2688d, we forgot to update the flags to be set to contain IRQ_LEVEL. While the flow handler is correct, the output from /proc/interrupts does not show such interrupts as being level triggered when they are, correct that. Fixes: a5042de2688d ("irqchip: bcm7120-l2: Add Broadcom BCM7120-style Level 2 interrupt controller") Signed-off-by: Florian Fainelli Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20221216230934.2478345-3-f.fainelli@gmail.com Signed-off-by: Sasha Levin --- drivers/irqchip/irq-bcm7120-l2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index c7c9e976acbb..7d776c905b7d 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -273,7 +273,8 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, flags |= IRQ_GC_BE_IO; ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1, - dn->full_name, handle_level_irq, clr, 0, flags); + dn->full_name, handle_level_irq, clr, + IRQ_LEVEL, flags); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; From 5663df20622d0e19283de8d348037a841f33ff65 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Thu, 16 Feb 2023 13:43:40 +0100 Subject: [PATCH 0257/1017] selftests/net: Interpret UDP_GRO cmsg data as an int value [ Upstream commit 436864095a95fcc611c20c44a111985fa9848730 ] Data passed to user-space with a (SOL_UDP, UDP_GRO) cmsg carries an int (see udp_cmsg_recv), not a u16 value, as strace confirms: recvmsg(8, {msg_name=..., msg_iov=[{iov_base="\0\0..."..., iov_len=96000}], msg_iovlen=1, msg_control=[{cmsg_len=20, <-- sizeof(cmsghdr) + 4 cmsg_level=SOL_UDP, cmsg_type=0x68}], <-- UDP_GRO msg_controllen=24, msg_flags=0}, 0) = 11200 Interpreting the data as an u16 value won't work on big-endian platforms. Since it is too late to back out of this API decision [1], fix the test. [1]: https://lore.kernel.org/netdev/20230131174601.203127-1-jakub@cloudflare.com/ Fixes: 3327a9c46352 ("selftests: add functionals test for UDP GRO") Suggested-by: Eric Dumazet Signed-off-by: Jakub Sitnicki Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- tools/testing/selftests/net/udpgso_bench_rx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c index 4058c7451e70..f35a924d4a30 100644 --- a/tools/testing/selftests/net/udpgso_bench_rx.c +++ b/tools/testing/selftests/net/udpgso_bench_rx.c @@ -214,11 +214,10 @@ static void do_verify_udp(const char *data, int len) static int recv_msg(int fd, char *buf, int len, int *gso_size) { - char control[CMSG_SPACE(sizeof(uint16_t))] = {0}; + char control[CMSG_SPACE(sizeof(int))] = {0}; struct msghdr msg = {0}; struct iovec iov = {0}; struct cmsghdr *cmsg; - uint16_t *gsosizeptr; int ret; iov.iov_base = buf; @@ -237,8 +236,7 @@ static int recv_msg(int fd, char *buf, int len, int *gso_size) cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_UDP && cmsg->cmsg_type == UDP_GRO) { - gsosizeptr = (uint16_t *) CMSG_DATA(cmsg); - *gso_size = *gsosizeptr; + *gso_size = *(int *)CMSG_DATA(cmsg); break; } } From 4a413d360959962995e16a899cf2b9ef53e9fcb9 Mon Sep 17 00:00:00 2001 From: Shigeru Yoshida Date: Fri, 17 Feb 2023 01:37:10 +0900 Subject: [PATCH 0258/1017] l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register() [ Upstream commit 9ca5e7ecab064f1f47da07f7c1ddf40e4bc0e5ac ] When a file descriptor of pppol2tp socket is passed as file descriptor of UDP socket, a recursive deadlock occurs in l2tp_tunnel_register(). This situation is reproduced by the following program: int main(void) { int sock; struct sockaddr_pppol2tp addr; sock = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); if (sock < 0) { perror("socket"); return 1; } addr.sa_family = AF_PPPOX; addr.sa_protocol = PX_PROTO_OL2TP; addr.pppol2tp.pid = 0; addr.pppol2tp.fd = sock; addr.pppol2tp.addr.sin_family = PF_INET; addr.pppol2tp.addr.sin_port = htons(0); addr.pppol2tp.addr.sin_addr.s_addr = inet_addr("192.168.0.1"); addr.pppol2tp.s_tunnel = 1; addr.pppol2tp.s_session = 0; addr.pppol2tp.d_tunnel = 0; addr.pppol2tp.d_session = 0; if (connect(sock, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("connect"); return 1; } return 0; } This program causes the following lockdep warning: ============================================ WARNING: possible recursive locking detected 6.2.0-rc5-00205-gc96618275234 #56 Not tainted -------------------------------------------- repro/8607 is trying to acquire lock: ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: l2tp_tunnel_register+0x2b7/0x11c0 but task is already holding lock: ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: pppol2tp_connect+0xa82/0x1a30 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(sk_lock-AF_PPPOX); lock(sk_lock-AF_PPPOX); *** DEADLOCK *** May be due to missing lock nesting notation 1 lock held by repro/8607: #0: ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: pppol2tp_connect+0xa82/0x1a30 stack backtrace: CPU: 0 PID: 8607 Comm: repro Not tainted 6.2.0-rc5-00205-gc96618275234 #56 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 Call Trace: dump_stack_lvl+0x100/0x178 __lock_acquire.cold+0x119/0x3b9 ? lockdep_hardirqs_on_prepare+0x410/0x410 lock_acquire+0x1e0/0x610 ? l2tp_tunnel_register+0x2b7/0x11c0 ? lock_downgrade+0x710/0x710 ? __fget_files+0x283/0x3e0 lock_sock_nested+0x3a/0xf0 ? l2tp_tunnel_register+0x2b7/0x11c0 l2tp_tunnel_register+0x2b7/0x11c0 ? sprintf+0xc4/0x100 ? l2tp_tunnel_del_work+0x6b0/0x6b0 ? debug_object_deactivate+0x320/0x320 ? lockdep_init_map_type+0x16d/0x7a0 ? lockdep_init_map_type+0x16d/0x7a0 ? l2tp_tunnel_create+0x2bf/0x4b0 ? l2tp_tunnel_create+0x3c6/0x4b0 pppol2tp_connect+0x14e1/0x1a30 ? pppol2tp_put_sk+0xd0/0xd0 ? aa_sk_perm+0x2b7/0xa80 ? aa_af_perm+0x260/0x260 ? bpf_lsm_socket_connect+0x9/0x10 ? pppol2tp_put_sk+0xd0/0xd0 __sys_connect_file+0x14f/0x190 __sys_connect+0x133/0x160 ? __sys_connect_file+0x190/0x190 ? lockdep_hardirqs_on+0x7d/0x100 ? ktime_get_coarse_real_ts64+0x1b7/0x200 ? ktime_get_coarse_real_ts64+0x147/0x200 ? __audit_syscall_entry+0x396/0x500 __x64_sys_connect+0x72/0xb0 do_syscall_64+0x38/0xb0 entry_SYSCALL_64_after_hwframe+0x63/0xcd This patch fixes the issue by getting/creating the tunnel before locking the pppol2tp socket. Fixes: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()") Cc: Cong Wang Signed-off-by: Shigeru Yoshida Reviewed-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/l2tp/l2tp_ppp.c | 127 ++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index aea85f91f059..5ecc0f200944 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -651,6 +651,65 @@ static int pppol2tp_tunnel_mtu(const struct l2tp_tunnel *tunnel) return mtu - PPPOL2TP_HEADER_OVERHEAD; } +static struct l2tp_tunnel *pppol2tp_tunnel_get(struct net *net, + const struct l2tp_connect_info *info, + bool *new_tunnel) +{ + struct l2tp_tunnel *tunnel; + int error; + + *new_tunnel = false; + + tunnel = l2tp_tunnel_get(net, info->tunnel_id); + + /* Special case: create tunnel context if session_id and + * peer_session_id is 0. Otherwise look up tunnel using supplied + * tunnel id. + */ + if (!info->session_id && !info->peer_session_id) { + if (!tunnel) { + struct l2tp_tunnel_cfg tcfg = { + .encap = L2TP_ENCAPTYPE_UDP, + }; + + /* Prevent l2tp_tunnel_register() from trying to set up + * a kernel socket. + */ + if (info->fd < 0) + return ERR_PTR(-EBADF); + + error = l2tp_tunnel_create(info->fd, + info->version, + info->tunnel_id, + info->peer_tunnel_id, &tcfg, + &tunnel); + if (error < 0) + return ERR_PTR(error); + + l2tp_tunnel_inc_refcount(tunnel); + error = l2tp_tunnel_register(tunnel, net, &tcfg); + if (error < 0) { + kfree(tunnel); + return ERR_PTR(error); + } + + *new_tunnel = true; + } + } else { + /* Error if we can't find the tunnel */ + if (!tunnel) + return ERR_PTR(-ENOENT); + + /* Error if socket is not prepped */ + if (!tunnel->sock) { + l2tp_tunnel_dec_refcount(tunnel); + return ERR_PTR(-ENOENT); + } + } + + return tunnel; +} + /* connect() handler. Attach a PPPoX socket to a tunnel UDP socket */ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, @@ -664,7 +723,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, struct pppol2tp_session *ps; struct l2tp_session_cfg cfg = { 0, }; bool drop_refcnt = false; - bool drop_tunnel = false; bool new_session = false; bool new_tunnel = false; int error; @@ -673,6 +731,14 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, if (error < 0) return error; + /* Don't bind if tunnel_id is 0 */ + if (!info.tunnel_id) + return -EINVAL; + + tunnel = pppol2tp_tunnel_get(sock_net(sk), &info, &new_tunnel); + if (IS_ERR(tunnel)) + return PTR_ERR(tunnel); + lock_sock(sk); /* Check for already bound sockets */ @@ -685,62 +751,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, if (sk->sk_user_data) goto end; /* socket is already attached */ - /* Don't bind if tunnel_id is 0 */ - error = -EINVAL; - if (!info.tunnel_id) - goto end; - - tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id); - if (tunnel) - drop_tunnel = true; - - /* Special case: create tunnel context if session_id and - * peer_session_id is 0. Otherwise look up tunnel using supplied - * tunnel id. - */ - if (!info.session_id && !info.peer_session_id) { - if (!tunnel) { - struct l2tp_tunnel_cfg tcfg = { - .encap = L2TP_ENCAPTYPE_UDP, - }; - - /* Prevent l2tp_tunnel_register() from trying to set up - * a kernel socket. - */ - if (info.fd < 0) { - error = -EBADF; - goto end; - } - - error = l2tp_tunnel_create(info.fd, - info.version, - info.tunnel_id, - info.peer_tunnel_id, &tcfg, - &tunnel); - if (error < 0) - goto end; - - l2tp_tunnel_inc_refcount(tunnel); - error = l2tp_tunnel_register(tunnel, sock_net(sk), - &tcfg); - if (error < 0) { - kfree(tunnel); - goto end; - } - drop_tunnel = true; - new_tunnel = true; - } - } else { - /* Error if we can't find the tunnel */ - error = -ENOENT; - if (!tunnel) - goto end; - - /* Error if socket is not prepped */ - if (!tunnel->sock) - goto end; - } - if (tunnel->peer_tunnel_id == 0) tunnel->peer_tunnel_id = info.peer_tunnel_id; @@ -841,8 +851,7 @@ end: } if (drop_refcnt) l2tp_session_dec_refcount(session); - if (drop_tunnel) - l2tp_tunnel_dec_refcount(tunnel); + l2tp_tunnel_dec_refcount(tunnel); release_sock(sk); return error; From e1c848d9ddd56f67f201e6e7571cbca90dfdf4fb Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Thu, 16 Feb 2023 11:41:28 -0800 Subject: [PATCH 0259/1017] net: bcmgenet: fix MoCA LED control [ Upstream commit a7515af9fb8f0890fe540b108def4a86b9e8330a ] When the bcmgenet_mii_config() code was refactored it was missed that the LED control for the MoCA interface got overwritten by the port_ctrl value. Its previous programming is restored here. Fixes: 4f8d81b77e66 ("net: bcmgenet: Refactor register access in bcmgenet_mii_config") Signed-off-by: Doug Berger Acked-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index f9e91304d232..4b875838a646 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -165,15 +165,6 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable) static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) { - u32 reg; - - if (!GENET_IS_V5(priv)) { - /* Speed settings are set in bcmgenet_mii_setup() */ - reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL); - reg |= LED_ACT_SOURCE_MAC; - bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL); - } - if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) fixed_phy_set_link_update(priv->dev->phydev, bcmgenet_fixed_phy_link_update); @@ -206,6 +197,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) if (!phy_name) { phy_name = "MoCA"; + if (!GENET_IS_V5(priv)) + port_ctrl |= LED_ACT_SOURCE_MAC; bcmgenet_moca_phy_setup(priv); } break; From 6038e458798d578d9e6736f4b424d8b851fc6d10 Mon Sep 17 00:00:00 2001 From: Roxana Nicolescu Date: Mon, 20 Feb 2023 12:04:00 +0100 Subject: [PATCH 0260/1017] selftest: fib_tests: Always cleanup before exit [ Upstream commit b60417a9f2b890a8094477b2204d4f73c535725e ] Usage of `set -e` before executing a command causes immediate exit on failure, without cleanup up the resources allocated at setup. This can affect the next tests that use the same resources, leading to a chain of failures. A simple fix is to always call cleanup function when the script exists. This approach is already used by other existing tests. Fixes: 1056691b2680 ("selftests: fib_tests: Make test results more verbose") Signed-off-by: Roxana Nicolescu Link: https://lore.kernel.org/r/20230220110400.26737-2-roxana.nicolescu@canonical.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- tools/testing/selftests/net/fib_tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index 0f3bf90e04d3..8f42e17db5d0 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh @@ -1773,6 +1773,8 @@ EOF ################################################################################ # main +trap cleanup EXIT + while getopts :t:pPhv o do case $o in From 8f06907f9f5814cf14c9fd8b0e4e616fd29b2b26 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 20 Feb 2023 14:23:36 +0100 Subject: [PATCH 0261/1017] sefltests: netdevsim: wait for devlink instance after netns removal [ Upstream commit f922c7b1c1c45740d329bf248936fdb78c0cff6e ] When devlink instance is put into network namespace and that network namespace gets deleted, devlink instance is moved back into init_ns. This is done as a part of cleanup_net() routine. Since cleanup_net() is called asynchronously from workqueue, there is no guarantee that the devlink instance move is done after "ip netns del" returns. So fix this race by making sure that the devlink instance is present before any other operation. Reported-by: Amir Tzin Fixes: b74c37fd35a2 ("selftests: netdevsim: add tests for devlink reload with resources") Signed-off-by: Jiri Pirko Reviewed-by: Pavan Chebbi Link: https://lore.kernel.org/r/20230220132336.198597-1-jiri@resnulli.us Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- .../selftests/drivers/net/netdevsim/devlink.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh index 16d2de18591d..2c81e01c30b3 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh @@ -16,6 +16,18 @@ SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV_NAME/net/ DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV_NAME/ DL_HANDLE=netdevsim/$DEV_NAME +wait_for_devlink() +{ + "$@" | grep -q $DL_HANDLE +} + +devlink_wait() +{ + local timeout=$1 + + busywait "$timeout" wait_for_devlink devlink dev +} + fw_flash_test() { RET=0 @@ -255,6 +267,9 @@ netns_reload_test() ip netns del testns2 ip netns del testns1 + # Wait until netns async cleanup is done. + devlink_wait 2000 + log_test "netns reload test" } @@ -347,6 +362,9 @@ resource_test() ip netns del testns2 ip netns del testns1 + # Wait until netns async cleanup is done. + devlink_wait 2000 + log_test "resource test" } From 5ae70041a6d7de62a0cdb2bbcfe0c9cf753035d0 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Fri, 18 Nov 2022 10:16:51 +0800 Subject: [PATCH 0262/1017] drm: Fix potential null-ptr-deref due to drmm_mode_config_init() [ Upstream commit 834c23e4f798dcdc8af251b3c428ceef94741991 ] drmm_mode_config_init() will call drm_mode_create_standard_properties() and won't check the ret value. When drm_mode_create_standard_properties() failed due to alloc, property will be a NULL pointer and may causes the null-ptr-deref. Fix the null-ptr-deref by adding the ret value check. Found null-ptr-deref while testing insert module bochs: general protection fault, probably for non-canonical address 0xdffffc000000000c: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000060-0x0000000000000067] CPU: 3 PID: 249 Comm: modprobe Not tainted 6.1.0-rc1+ #364 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:drm_object_attach_property+0x73/0x3c0 [drm] Call Trace: __drm_connector_init+0xb6c/0x1100 [drm] bochs_pci_probe.cold.11+0x4cb/0x7fe [bochs] pci_device_probe+0x17d/0x340 really_probe+0x1db/0x5d0 __driver_probe_device+0x1e7/0x250 driver_probe_device+0x4a/0x120 __driver_attach+0xcd/0x2c0 bus_for_each_dev+0x11a/0x1b0 bus_add_driver+0x3d7/0x500 driver_register+0x18e/0x320 do_one_initcall+0xc4/0x3e0 do_init_module+0x1b4/0x630 load_module+0x5dca/0x7230 __do_sys_finit_module+0x100/0x170 do_syscall_64+0x3f/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7ff65af9f839 Fixes: 6b4959f43a04 ("drm/atomic: atomic plane properties") Signed-off-by: Shang XiaoJing Signed-off-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20221118021651.2460-1-shangxiaojing@huawei.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_mode_config.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index f1affc1bb679..fad2c1181127 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -398,6 +398,8 @@ static void drm_mode_config_init_release(struct drm_device *dev, void *ptr) */ int drmm_mode_config_init(struct drm_device *dev) { + int ret; + mutex_init(&dev->mode_config.mutex); drm_modeset_lock_init(&dev->mode_config.connection_mutex); mutex_init(&dev->mode_config.idr_mutex); @@ -419,7 +421,11 @@ int drmm_mode_config_init(struct drm_device *dev) init_llist_head(&dev->mode_config.connector_free_list); INIT_WORK(&dev->mode_config.connector_free_work, drm_connector_free_work_fn); - drm_mode_create_standard_properties(dev); + ret = drm_mode_create_standard_properties(dev); + if (ret) { + drm_mode_config_cleanup(dev); + return ret; + } /* Just to be sure */ dev->mode_config.num_fb = 0; From a86bd12bd974c20d0f045ac601f96ab0e8db0410 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 23 Nov 2022 17:43:10 +0100 Subject: [PATCH 0263/1017] drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats [ Upstream commit 6fb6c979ca628583d4d0c59a0f8ff977e581ecc0 ] As of commit eae06120f1974e1a ("drm: refuse ADDFB2 ioctl for broken bigendian drivers"), drivers must set the quirk_addfb_prefer_host_byte_order quirk to make the drm_mode_addfb() compat code work correctly on big-endian machines. While that works fine for big-endian XRGB8888 and ARGB8888, which are mapped to the existing little-endian BGRX8888 and BGRA8888 formats, it does not work for big-endian XRGB1555 and RGB565, as the latter are not listed in the format database. Fix this by adding the missing formats. Limit this to big-endian platforms, as there is currently no need to support these formats on little-endian platforms. Fixes: 6960e6da9cec3f66 ("drm: fix drm_mode_addfb() on big endian machines.") Signed-off-by: Geert Uytterhoeven Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/3ee1f8144feb96c28742b22384189f1f83bcfc1a.1669221671.git.geert@linux-m68k.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_fourcc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index 92152c06b75b..8d1064061e83 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -178,6 +178,10 @@ const struct drm_format_info *__drm_format_info(u32 format) { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, +#ifdef __BIG_ENDIAN + { .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, + { .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, +#endif { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, From 181fb5efb64974709ac3b9ebc0c8278ccc96a3d0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 21 Nov 2022 16:59:55 +0100 Subject: [PATCH 0264/1017] drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC [ Upstream commit 7783cc67862f9166c901bfa0f80b717aa8d354dd ] Freescale/NXP i.MX LCDIF and eLCDIF LCD controllers are only present on Freescale/NXP i.MX SoCs. Hence add a dependency on ARCH_MXS || ARCH_MXC, to prevent asking the user about this driver when configuring a kernel without Freescale/NXP i.MX support. Fixes: 45d59d704080cc0c ("drm: Add new driver for MXSFB controller") Signed-off-by: Geert Uytterhoeven Reviewed-by: Marek Vasut Signed-off-by: Marek Vasut Link: https://patchwork.freedesktop.org/patch/msgid/98e74779ca2bc575d91afff03369e86b080c01ac.1669046358.git.geert+renesas@glider.be Signed-off-by: Sasha Levin --- drivers/gpu/drm/mxsfb/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig index ee22cd25d3e3..e7201e16119a 100644 --- a/drivers/gpu/drm/mxsfb/Kconfig +++ b/drivers/gpu/drm/mxsfb/Kconfig @@ -8,6 +8,7 @@ config DRM_MXSFB tristate "i.MX (e)LCDIF LCD controller" depends on DRM && OF depends on COMMON_CLK + depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST select DRM_MXS select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER From 5b9bcb33cf3ffa60c520c02b33a364cb64d7e7df Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Tue, 8 Nov 2022 09:12:26 +0000 Subject: [PATCH 0265/1017] drm/bridge: megachips: Fix error handling in i2c_register_driver() [ Upstream commit 4ecff954c370b82bce45bdca2846c5c5563e8a8a ] A problem about insmod megachips-stdpxxxx-ge-b850v3-fw.ko failed is triggered with the following log given: [ 4497.981497] Error: Driver 'stdp4028-ge-b850v3-fw' is already registered, aborting... insmod: ERROR: could not insert module megachips-stdpxxxx-ge-b850v3-fw.ko: Device or resource busy The reason is that stdpxxxx_ge_b850v3_init() returns i2c_add_driver() directly without checking its return value, if i2c_add_driver() failed, it returns without calling i2c_del_driver() on the previous i2c driver, resulting the megachips-stdpxxxx-ge-b850v3-fw can never be installed later. A simple call graph is shown as below: stdpxxxx_ge_b850v3_init() i2c_add_driver(&stdp4028_ge_b850v3_fw_driver) i2c_add_driver(&stdp2690_ge_b850v3_fw_driver) i2c_register_driver() driver_register() bus_add_driver() priv = kzalloc(...) # OOM happened # return without delete stdp4028_ge_b850v3_fw_driver Fix by calling i2c_del_driver() on stdp4028_ge_b850v3_fw_driver when i2c_add_driver() returns error. Fixes: fcfa0ddc18ed ("drm/bridge: Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)") Signed-off-by: Yuan Can Reviewed-by: Andrzej Hajda Tested-by: Ian Ray Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20221108091226.114524-1-yuancan@huawei.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c index 72248a565579..e41afcc5326b 100644 --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -444,7 +444,11 @@ static int __init stdpxxxx_ge_b850v3_init(void) if (ret) return ret; - return i2c_add_driver(&stdp2690_ge_b850v3_fw_driver); + ret = i2c_add_driver(&stdp2690_ge_b850v3_fw_driver); + if (ret) + i2c_del_driver(&stdp4028_ge_b850v3_fw_driver); + + return ret; } module_init(stdpxxxx_ge_b850v3_init); From 0b8f390e2251191f1b179cc87f65d54c96565f0d Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Tue, 1 Nov 2022 06:51:56 +0000 Subject: [PATCH 0266/1017] drm/vkms: Fix null-ptr-deref in vkms_release() [ Upstream commit 2fe2a8f40c21161ffe7653cc234e7934db5b7cc5 ] A null-ptr-deref is triggered when it tries to destroy the workqueue in vkms->output.composer_workq in vkms_release(). KASAN: null-ptr-deref in range [0x0000000000000118-0x000000000000011f] CPU: 5 PID: 17193 Comm: modprobe Not tainted 6.0.0-11331-gd465bff130bf #24 RIP: 0010:destroy_workqueue+0x2f/0x710 ... Call Trace: ? vkms_config_debugfs_init+0x50/0x50 [vkms] __devm_drm_dev_alloc+0x15a/0x1c0 [drm] vkms_init+0x245/0x1000 [vkms] do_one_initcall+0xd0/0x4f0 do_init_module+0x1a4/0x680 load_module+0x6249/0x7110 __do_sys_finit_module+0x140/0x200 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 The reason is that an OOM happened which triggers the destroy of the workqueue, however, the workqueue is alloced in the later process, thus a null-ptr-deref happened. A simple call graph is shown as below: vkms_init() vkms_create() devm_drm_dev_alloc() __devm_drm_dev_alloc() devm_drm_dev_init() devm_add_action_or_reset() devm_add_action() # an error happened devm_drm_dev_init_release() drm_dev_put() kref_put() drm_dev_release() vkms_release() destroy_workqueue() # null-ptr-deref happened vkms_modeset_init() vkms_output_init() vkms_crtc_init() # where the workqueue get allocated Fix this by checking if composer_workq is NULL before passing it to the destroy_workqueue() in vkms_release(). Fixes: 6c234fe37c57 ("drm/vkms: Implement CRC debugfs API") Signed-off-by: Yuan Can Reviewed-by: Melissa Wen Signed-off-by: Melissa Wen Link: https://patchwork.freedesktop.org/patch/msgid/20221101065156.41584-3-yuancan@huawei.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/vkms/vkms_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index cb0b6230c22c..838428988f79 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -61,7 +61,8 @@ static void vkms_release(struct drm_device *dev) { struct vkms_device *vkms = container_of(dev, struct vkms_device, drm); - destroy_workqueue(vkms->output.composer_workq); + if (vkms->output.composer_workq) + destroy_workqueue(vkms->output.composer_workq); } static void vkms_atomic_commit_tail(struct drm_atomic_state *old_state) From 09c6e21d6a1eaacac54a5d1ea7202e8383a886e6 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Mon, 13 Jun 2022 16:47:36 +0200 Subject: [PATCH 0267/1017] drm/vc4: dpi: Add option for inverting pixel clock and output enable [ Upstream commit 3c2707632146b22e97b0fbf6778bab8add2eaa1d ] DRM provides flags for inverting pixel clock and output enable signals, but these were not mapped to the relevant registers. Add those mappings. Signed-off-by: Dave Stevenson Link: https://lore.kernel.org/r/20220613144800.326124-10-maxime@cerno.tech Signed-off-by: Maxime Ripard Stable-dep-of: 0870d86eac8a ("drm/vc4: dpi: Fix format mapping for RGB565") Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_dpi.c | 64 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index a90f2545baee..0e25add2df07 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -148,35 +148,45 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) } drm_connector_list_iter_end(&conn_iter); - if (connector && connector->display_info.num_bus_formats) { - u32 bus_format = connector->display_info.bus_formats[0]; + if (connector) { + if (connector->display_info.num_bus_formats) { + u32 bus_format = connector->display_info.bus_formats[0]; - switch (bus_format) { - case MEDIA_BUS_FMT_RGB888_1X24: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, - DPI_FORMAT); - break; - case MEDIA_BUS_FMT_BGR888_1X24: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, - DPI_FORMAT); - dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER); - break; - case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2, - DPI_FORMAT); - break; - case MEDIA_BUS_FMT_RGB666_1X18: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, - DPI_FORMAT); - break; - case MEDIA_BUS_FMT_RGB565_1X16: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3, - DPI_FORMAT); - break; - default: - DRM_ERROR("Unknown media bus format %d\n", bus_format); - break; + switch (bus_format) { + case MEDIA_BUS_FMT_RGB888_1X24: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, + DPI_FORMAT); + break; + case MEDIA_BUS_FMT_BGR888_1X24: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, + DPI_FORMAT); + dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, + DPI_ORDER); + break; + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2, + DPI_FORMAT); + break; + case MEDIA_BUS_FMT_RGB666_1X18: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, + DPI_FORMAT); + break; + case MEDIA_BUS_FMT_RGB565_1X16: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3, + DPI_FORMAT); + break; + default: + DRM_ERROR("Unknown media bus format %d\n", + bus_format); + break; + } } + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) + dpi_c |= DPI_PIXEL_CLK_INVERT; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) + dpi_c |= DPI_OUTPUT_ENABLE_INVERT; } else { /* Default to 24bit if no connector found. */ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT); From 2adbcf94ebfcd183223d434227d55b9841458bf0 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 1 Dec 2022 09:42:52 +0100 Subject: [PATCH 0268/1017] drm/vc4: dpi: Fix format mapping for RGB565 [ Upstream commit 0870d86eac8a9abd89a0be1b719d5dc5bac936f0 ] The mapping is incorrect for RGB565_1X16 as it should be DPI_FORMAT_18BIT_666_RGB_1 instead of DPI_FORMAT_18BIT_666_RGB_3. Fixes: 08302c35b59d ("drm/vc4: Add DPI driver") Signed-off-by: Dave Stevenson Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20221013-rpi-dpi-improvements-v3-7-eb76e26a772d@cerno.tech Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_dpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index 0e25add2df07..9c8a71d7426a 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -172,7 +172,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) DPI_FORMAT); break; case MEDIA_BUS_FMT_RGB565_1X16: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3, + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1, DPI_FORMAT); break; default: From fdcacfd11015cd46aaad2d7a6be0b10ebe247102 Mon Sep 17 00:00:00 2001 From: Randolph Sapp Date: Thu, 1 Dec 2022 18:18:03 -0600 Subject: [PATCH 0269/1017] drm: tidss: Fix pixel format definition [ Upstream commit 2df0433b18f2735a49d2c3a968b40fa2881137c0 ] There was a long-standing bug from a typo that created 2 ARGB1555 and ABGR1555 pixel format entries. Weston 10 has a sanity check that alerted me to this issue. According to the Supported Pixel Data formats table we have the later entries should have been for Alpha-X instead. Signed-off-by: Randolph Sapp Fixes: 32a1795f57eecc ("drm/tidss: New driver for TI Keystone platform Display SubSystem") Reviewed-by: Aradhya Bhatia Acked-by: Andrew Davis Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20221202001803.1765805-1-rs@ti.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/tidss/tidss_dispc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c index b669168ae7cb..33716213a821 100644 --- a/drivers/gpu/drm/tidss/tidss_dispc.c +++ b/drivers/gpu/drm/tidss/tidss_dispc.c @@ -1855,8 +1855,8 @@ static const struct { { DRM_FORMAT_XBGR4444, 0x21, }, { DRM_FORMAT_RGBX4444, 0x22, }, - { DRM_FORMAT_ARGB1555, 0x25, }, - { DRM_FORMAT_ABGR1555, 0x26, }, + { DRM_FORMAT_XRGB1555, 0x25, }, + { DRM_FORMAT_XBGR1555, 0x26, }, { DRM_FORMAT_XRGB8888, 0x27, }, { DRM_FORMAT_XBGR8888, 0x28, }, From 8eb74bd9c9726425fe62330a2eda4d862edb6dd1 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 20 Jul 2022 23:22:27 +0800 Subject: [PATCH 0270/1017] gpu: ipu-v3: common: Add of_node_put() for reference returned by of_graph_get_port_by_id() [ Upstream commit 9afdf98cfdfa2ba8ec068cf08c5fcdc1ed8daf3f ] In ipu_add_client_devices(), we need to call of_node_put() for reference returned by of_graph_get_port_by_id() in fail path. Fixes: 17e052175039 ("gpu: ipu-v3: Do not bail out on missing optional port nodes") Signed-off-by: Liang He Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/20220720152227.1288413-1-windhl@126.com Signed-off-by: Philipp Zabel Link: https://patchwork.freedesktop.org/patch/msgid/20220720152227.1288413-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/gpu/ipu-v3/ipu-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index d166ee262ce4..22dae3f51051 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1168,6 +1168,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) pdev = platform_device_alloc(reg->name, id++); if (!pdev) { ret = -ENOMEM; + of_node_put(of_node); goto err_register; } From 1bab31a0969ca4ac90907a5d3b44af104229eafd Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Fri, 6 Jan 2023 10:30:11 +0800 Subject: [PATCH 0271/1017] drm/msm/hdmi: Add missing check for alloc_ordered_workqueue [ Upstream commit afe4cb96153a0d8003e4e4ebd91b5c543e10df84 ] Add check for the return value of alloc_ordered_workqueue as it may return NULL pointer and cause NULL pointer dereference in `hdmi_hdcp.c` and `hdmi_hpd.c`. Fixes: c6a57a50ad56 ("drm/msm/hdmi: add hdmi hdcp support (V3)") Signed-off-by: Jiasheng Jiang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/517211/ Link: https://lore.kernel.org/r/20230106023011.3985-1-jiasheng@iscas.ac.cn Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/hdmi/hdmi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index efb14043a6ec..bee208773bee 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -264,6 +264,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); + if (!hdmi->workq) { + ret = -ENOMEM; + goto fail; + } hdmi->i2c = msm_hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) { From 86704e50ffb589f81af74b6a9c48d9629fb89bfc Mon Sep 17 00:00:00 2001 From: Adam Skladowski Date: Sat, 31 Dec 2022 17:42:50 +0100 Subject: [PATCH 0272/1017] pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins [ Upstream commit a7cc0e2685082a0d79baec02df184dfa83cbfac3 ] Adjust names of function for wcss pins, also fix third gpio in bt group. Fixes: bcd11493f0ab ("pinctrl: qcom: Add a pinctrl driver for MSM8976 and 8956") Signed-off-by: Adam Skladowski Reviewed-by: Marijn Suijten Link: https://lore.kernel.org/r/20221231164250.74550-1-a39.skl@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/qcom/pinctrl-msm8976.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm8976.c b/drivers/pinctrl/qcom/pinctrl-msm8976.c index ec43edf9b660..e11d84584719 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8976.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8976.c @@ -733,7 +733,7 @@ static const char * const codec_int2_groups[] = { "gpio74", }; static const char * const wcss_bt_groups[] = { - "gpio39", "gpio47", "gpio88", + "gpio39", "gpio47", "gpio48", }; static const char * const sdc3_groups[] = { "gpio39", "gpio40", "gpio41", @@ -958,9 +958,9 @@ static const struct msm_pingroup msm8976_groups[] = { PINGROUP(37, NA, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA), PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b, NA), PINGROUP(39, wcss_bt, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), - PINGROUP(40, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), - PINGROUP(41, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), - PINGROUP(42, wcss_wlan, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), + PINGROUP(40, wcss_wlan2, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), + PINGROUP(41, wcss_wlan1, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), + PINGROUP(42, wcss_wlan0, sdc3, NA, qdss_tracedata_a, NA, NA, NA, NA, NA), PINGROUP(43, wcss_wlan, sdc3, NA, NA, qdss_tracedata_a, NA, NA, NA, NA), PINGROUP(44, wcss_wlan, sdc3, NA, NA, NA, NA, NA, NA, NA), PINGROUP(45, wcss_fm, NA, qdss_tracectl_a, NA, NA, NA, NA, NA, NA), From 8ab860dd8717a7e4a143988885fea0d7e5a9412e Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 12:24:56 +0400 Subject: [PATCH 0273/1017] pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain [ Upstream commit dcef18c8ac40aa85bb339f64c1dd31dd458b06fb ] of_irq_find_parent() returns a node pointer with refcount incremented, We should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak. Fixes: d86f4d71e42a ("pinctrl: stm32: check irq controller availability at probe") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20230102082503.3944927-1-linmq006@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/stm32/pinctrl-stm32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 60406f1f8337..2d852f15cc50 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1338,6 +1338,7 @@ static struct irq_domain *stm32_pctrl_get_irq_domain(struct device_node *np) return ERR_PTR(-ENXIO); domain = irq_find_host(parent); + of_node_put(parent); if (!domain) /* domain not registered yet */ return ERR_PTR(-EPROBE_DEFER); From 6da121152ada3f158dcab9430ada8291eb39c2bc Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Fri, 19 Mar 2021 16:14:41 +0800 Subject: [PATCH 0274/1017] pinctrl: rockchip: add support for rk3568 [ Upstream commit c0dadc0e47a895e95c17a4df1fa12737e1d57d6f ] RK3568 SoCs have 5 gpio controllers, each gpio has 32 pins. GPIO supports set iomux, pull, drive strength and schmitt. Signed-off-by: Jianqun Xu Link: https://lore.kernel.org/r/20210319081441.368358-1-jay.xu@rock-chips.com Signed-off-by: Linus Walleij Stable-dep-of: c818ae563bf9 ("pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups") Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-rockchip.c | 292 ++++++++++++++++++++++++++++- 1 file changed, 290 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 07b1204174bf..38ea70f49cb0 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -61,8 +61,17 @@ enum rockchip_pinctrl_type { RK3308, RK3368, RK3399, + RK3568, }; + +/** + * Generate a bitmask for setting a value (v) with a write mask bit in hiword + * register 31:16 area. + */ +#define WRITE_MASK_VAL(h, l, v) \ + (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) + /* * Encode variants of iomux registers into a type variable */ @@ -290,6 +299,25 @@ struct rockchip_pin_bank { .pull_type[3] = pull3, \ } +#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ + { \ + .bank_num = ID, \ + .pin = PIN, \ + .func = FUNC, \ + .route_offset = REG, \ + .route_val = VAL, \ + .route_location = FLAG, \ + } + +#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) + +#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) + +#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) + /** * struct rockchip_mux_recalced_data: represent a pin iomux data. * @num: bank number. @@ -1409,6 +1437,102 @@ static struct rockchip_mux_route_data rk3399_mux_route_data[] = { }, }; +static struct rockchip_mux_route_data rk3568_mux_route_data[] = { + RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ + RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ + RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ +}; + static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, int mux, u32 *loc, u32 *reg, u32 *value) { @@ -2117,6 +2241,68 @@ static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit = (pin_num % 8) * 2; } +#define RK3568_PULL_PMU_OFFSET 0x20 +#define RK3568_PULL_GRF_OFFSET 0x80 +#define RK3568_PULL_BITS_PER_PIN 2 +#define RK3568_PULL_PINS_PER_REG 8 +#define RK3568_PULL_BANK_STRIDE 0x10 + +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_PULL_PMU_OFFSET; + *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + + *bit = pin_num % RK3568_PULL_PINS_PER_REG; + *bit *= RK3568_PULL_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3568_PULL_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; + *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3568_PULL_PINS_PER_REG); + *bit *= RK3568_PULL_BITS_PER_PIN; + } +} + +#define RK3568_DRV_PMU_OFFSET 0x70 +#define RK3568_DRV_GRF_OFFSET 0x200 +#define RK3568_DRV_BITS_PER_PIN 8 +#define RK3568_DRV_PINS_PER_REG 2 +#define RK3568_DRV_BANK_STRIDE 0x40 + +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 32 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_DRV_PMU_OFFSET; + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + + *bit = pin_num % RK3568_DRV_PINS_PER_REG; + *bit *= RK3568_DRV_BITS_PER_PIN; + } else { + *regmap = info->regmap_base; + *reg = RK3568_DRV_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; + *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); + + *bit = (pin_num % RK3568_DRV_PINS_PER_REG); + *bit *= RK3568_DRV_BITS_PER_PIN; + } +} + static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { { 2, 4, 8, 12, -1, -1, -1, -1 }, { 3, 6, 9, 12, -1, -1, -1, -1 }, @@ -2217,6 +2403,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, bank->bank_num, pin_num, strength); ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ctrl->type == RK3568) { + rmask_bits = RK3568_DRV_BITS_PER_PIN; + ret = (1 << (strength + 1)) - 1; + goto config; + } ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { @@ -2286,6 +2477,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, return -EINVAL; } +config: /* enable the write to the equivalent lower bits */ data = ((1 << rmask_bits) - 1) << (bit + 16); rmask = data | (data >> 16); @@ -2388,6 +2580,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case RK3308: case RK3368: case RK3399: + case RK3568: pull_type = bank->pull_type[pin_num / 8]; ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); @@ -2397,6 +2590,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, break; } } + /* + * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, + * where that pull up value becomes 3. + */ + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { + if (ret == 1) + ret = 3; + } if (ret < 0) { dev_err(info->dev, "unsupported pull setting %d\n", @@ -2441,6 +2642,35 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +#define RK3568_SCHMITT_BITS_PER_PIN 2 +#define RK3568_SCHMITT_PINS_PER_REG 8 +#define RK3568_SCHMITT_BANK_STRIDE 0x10 +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 + +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK3568_SCHMITT_PMUGRF_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RK3568_SCHMITT_GRF_OFFSET; + *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; + } + + *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); + *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; + *bit *= RK3568_SCHMITT_BITS_PER_PIN; + + return 0; +} + static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2459,6 +2689,13 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) return ret; data >>= bit; + switch (ctrl->type) { + case RK3568: + return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); + default: + break; + } + return data & 0x1; } @@ -2480,8 +2717,17 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, return ret; /* enable the write to the equivalent lower bits */ - data = BIT(bit + 16) | (enable << bit); - rmask = BIT(bit + 16) | BIT(bit); + switch (ctrl->type) { + case RK3568: + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); + rmask = data | (data >> 16); + data |= ((enable ? 0x2 : 0x1) << bit); + break; + default: + data = BIT(bit + 16) | (enable << bit); + rmask = BIT(bit + 16) | BIT(bit); + break; + } return regmap_update_bits(regmap, reg, rmask, data); } @@ -2655,6 +2901,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, case RK3308: case RK3368: case RK3399: + case RK3568: return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); } @@ -4230,6 +4477,45 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = { .drv_calc_reg = rk3399_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3568_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT), +}; + +static struct rockchip_pin_ctrl rk3568_pin_ctrl = { + .pin_banks = rk3568_pin_banks, + .nr_banks = ARRAY_SIZE(rk3568_pin_banks), + .label = "RK3568-GPIO", + .type = RK3568, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x0, + .grf_drv_offset = 0x0200, + .pmu_drv_offset = 0x0070, + .iomux_routes = rk3568_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), + .pull_calc_reg = rk3568_calc_pull_reg_and_bit, + .drv_calc_reg = rk3568_calc_drv_reg_and_bit, + .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, +}; + static const struct of_device_id rockchip_pinctrl_dt_match[] = { { .compatible = "rockchip,px30-pinctrl", .data = &px30_pin_ctrl }, @@ -4259,6 +4545,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = { .data = &rk3368_pin_ctrl }, { .compatible = "rockchip,rk3399-pinctrl", .data = &rk3399_pin_ctrl }, + { .compatible = "rockchip,rk3568-pinctrl", + .data = &rk3568_pin_ctrl }, {}, }; From 3dd6f159385d13853e41e697cb71070a942f221c Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Tue, 20 Apr 2021 17:12:40 +0800 Subject: [PATCH 0275/1017] pinctrl: rockchip: do coding style for mux route struct [ Upstream commit fe202ea8e5b170ef7b3741da885e8cb7bae1106e ] The mux route tables take many lines for each SoC, and it will be more instances for newly SoC, that makes the file size increase larger. This patch only do coding style for mux route struct, by adding a new definition and replace the structs by script which supplied by huangtao@rock-chips.com sed -i -e " /static struct rockchip_mux_route_data /bcheck b :append-next-line N :check /^[^;]*$/bappend-next-line s/[[:blank:]]*.bank_num = \([[:digit:]]*,\)\n/\tRK_MUXROUTE_SAME(\1/g s/[[:blank:]]*.pin =[[:blank:]]*0,\n/ RK_PA0,/g s/[[:blank:]]*.pin =[[:blank:]]*1,\n/ RK_PA1,/g s/[[:blank:]]*.pin =[[:blank:]]*2,\n/ RK_PA2,/g s/[[:blank:]]*.pin =[[:blank:]]*3,\n/ RK_PA3,/g s/[[:blank:]]*.pin =[[:blank:]]*4,\n/ RK_PA4,/g s/[[:blank:]]*.pin =[[:blank:]]*5,\n/ RK_PA5,/g s/[[:blank:]]*.pin =[[:blank:]]*6,\n/ RK_PA6,/g s/[[:blank:]]*.pin =[[:blank:]]*7,\n/ RK_PA7,/g s/[[:blank:]]*.pin =[[:blank:]]*8,\n/ RK_PB0,/g s/[[:blank:]]*.pin =[[:blank:]]*9,\n/ RK_PB1,/g s/[[:blank:]]*.pin =[[:blank:]]*10,\n/ RK_PB2,/g s/[[:blank:]]*.pin =[[:blank:]]*11,\n/ RK_PB3,/g s/[[:blank:]]*.pin =[[:blank:]]*12,\n/ RK_PB4,/g s/[[:blank:]]*.pin =[[:blank:]]*13,\n/ RK_PB5,/g s/[[:blank:]]*.pin =[[:blank:]]*14,\n/ RK_PB6,/g s/[[:blank:]]*.pin =[[:blank:]]*15,\n/ RK_PB7,/g s/[[:blank:]]*.pin =[[:blank:]]*16,\n/ RK_PC0,/g s/[[:blank:]]*.pin =[[:blank:]]*17,\n/ RK_PC1,/g s/[[:blank:]]*.pin =[[:blank:]]*18,\n/ RK_PC2,/g s/[[:blank:]]*.pin =[[:blank:]]*19,\n/ RK_PC3,/g s/[[:blank:]]*.pin =[[:blank:]]*20,\n/ RK_PC4,/g s/[[:blank:]]*.pin =[[:blank:]]*21,\n/ RK_PC5,/g s/[[:blank:]]*.pin =[[:blank:]]*22,\n/ RK_PC6,/g s/[[:blank:]]*.pin =[[:blank:]]*23,\n/ RK_PC7,/g s/[[:blank:]]*.pin =[[:blank:]]*24,\n/ RK_PD0,/g s/[[:blank:]]*.pin =[[:blank:]]*25,\n/ RK_PD1,/g s/[[:blank:]]*.pin =[[:blank:]]*26,\n/ RK_PD2,/g s/[[:blank:]]*.pin =[[:blank:]]*27,\n/ RK_PD3,/g s/[[:blank:]]*.pin =[[:blank:]]*28,\n/ RK_PD4,/g s/[[:blank:]]*.pin =[[:blank:]]*29,\n/ RK_PD5,/g s/[[:blank:]]*.pin =[[:blank:]]*30,\n/ RK_PD6,/g s/[[:blank:]]*.pin =[[:blank:]]*31,\n/ RK_PD7,/g s/[[:blank:]]*.func = \([[:digit:]]*,\)\n/ \1/g s/[[:blank:]]*.route_location =[[:blank:]]*\([[:print:]]*,\)\n//g s/[[:blank:]]*.route_offset = \(0x[[:xdigit:]]*,\)\n/ \1/g s/[[:blank:]]*.route_val =[[:blank:]]*\([[:print:]]*\),\n/ \1),/g s/\t{\n//g s/\t}, {\n//g s/\t},//g s/[[:blank:]]*\(\/\*[[:print:]]*\*\/\)\n[[:blank:]]*RK_MUXROUTE_SAME(\([[:print:]]*\)),\n/\tRK_MUXROUTE_SAME(\2), \1\n/g s/[[:blank:]]*\(\/\*[[:print:]]*\*\/\)\n[[:blank:]]*RK_MUXROUTE_SAME(\([[:print:]]*\)),/\tRK_MUXROUTE_SAME(\2), \1\n/g " drivers/pinctrl/pinctrl-rockchip.c Reviewed-by: Heiko Stuebner Signed-off-by: Jianqun Xu Link: https://lore.kernel.org/r/20210420091240.1246429-1-jay.xu@rock-chips.com Signed-off-by: Linus Walleij Stable-dep-of: c818ae563bf9 ("pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups") Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-rockchip.c | 650 ++++------------------------- 1 file changed, 80 insertions(+), 570 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 38ea70f49cb0..944c7254f672 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -844,597 +844,107 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, } static struct rockchip_mux_route_data px30_mux_route_data[] = { - { - /* cif-d2m0 */ - .bank_num = 2, - .pin = 0, - .func = 1, - .route_offset = 0x184, - .route_val = BIT(16 + 7), - }, { - /* cif-d2m1 */ - .bank_num = 3, - .pin = 3, - .func = 3, - .route_offset = 0x184, - .route_val = BIT(16 + 7) | BIT(7), - }, { - /* pdm-m0 */ - .bank_num = 3, - .pin = 22, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 8), - }, { - /* pdm-m1 */ - .bank_num = 2, - .pin = 22, - .func = 1, - .route_offset = 0x184, - .route_val = BIT(16 + 8) | BIT(8), - }, { - /* uart2-rxm0 */ - .bank_num = 1, - .pin = 27, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 10), - }, { - /* uart2-rxm1 */ - .bank_num = 2, - .pin = 14, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 10) | BIT(10), - }, { - /* uart3-rxm0 */ - .bank_num = 0, - .pin = 17, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 9), - }, { - /* uart3-rxm1 */ - .bank_num = 1, - .pin = 15, - .func = 2, - .route_offset = 0x184, - .route_val = BIT(16 + 9) | BIT(9), - }, + RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */ + RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */ + RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */ + RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */ + RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */ + RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */ + RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */ + RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ }; static struct rockchip_mux_route_data rk3128_mux_route_data[] = { - { - /* spi-0 */ - .bank_num = 1, - .pin = 10, - .func = 1, - .route_offset = 0x144, - .route_val = BIT(16 + 3) | BIT(16 + 4), - }, { - /* spi-1 */ - .bank_num = 1, - .pin = 27, - .func = 3, - .route_offset = 0x144, - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3), - }, { - /* spi-2 */ - .bank_num = 0, - .pin = 13, - .func = 2, - .route_offset = 0x144, - .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4), - }, { - /* i2s-0 */ - .bank_num = 1, - .pin = 5, - .func = 1, - .route_offset = 0x144, - .route_val = BIT(16 + 5), - }, { - /* i2s-1 */ - .bank_num = 0, - .pin = 14, - .func = 1, - .route_offset = 0x144, - .route_val = BIT(16 + 5) | BIT(5), - }, { - /* emmc-0 */ - .bank_num = 1, - .pin = 22, - .func = 2, - .route_offset = 0x144, - .route_val = BIT(16 + 6), - }, { - /* emmc-1 */ - .bank_num = 2, - .pin = 4, - .func = 2, - .route_offset = 0x144, - .route_val = BIT(16 + 6) | BIT(6), - }, + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */ + RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */ + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */ + RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */ + RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */ }; static struct rockchip_mux_route_data rk3188_mux_route_data[] = { - { - /* non-iomuxed emmc/flash pins on flash-dqs */ - .bank_num = 0, - .pin = 24, - .func = 1, - .route_location = ROCKCHIP_ROUTE_GRF, - .route_offset = 0xa0, - .route_val = BIT(16 + 11), - }, { - /* non-iomuxed emmc/flash pins on emmc-clk */ - .bank_num = 0, - .pin = 24, - .func = 2, - .route_location = ROCKCHIP_ROUTE_GRF, - .route_offset = 0xa0, - .route_val = BIT(16 + 11) | BIT(11), - }, + RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */ + RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */ }; static struct rockchip_mux_route_data rk3228_mux_route_data[] = { - { - /* pwm0-0 */ - .bank_num = 0, - .pin = 26, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16), - }, { - /* pwm0-1 */ - .bank_num = 3, - .pin = 21, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16) | BIT(0), - }, { - /* pwm1-0 */ - .bank_num = 0, - .pin = 27, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 1), - }, { - /* pwm1-1 */ - .bank_num = 0, - .pin = 30, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 1) | BIT(1), - }, { - /* pwm2-0 */ - .bank_num = 0, - .pin = 28, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 2), - }, { - /* pwm2-1 */ - .bank_num = 1, - .pin = 12, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 2) | BIT(2), - }, { - /* pwm3-0 */ - .bank_num = 3, - .pin = 26, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 3), - }, { - /* pwm3-1 */ - .bank_num = 1, - .pin = 11, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* sdio-0_d0 */ - .bank_num = 1, - .pin = 1, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 4), - }, { - /* sdio-1_d0 */ - .bank_num = 3, - .pin = 2, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 4) | BIT(4), - }, { - /* spi-0_rx */ - .bank_num = 0, - .pin = 13, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 5), - }, { - /* spi-1_rx */ - .bank_num = 2, - .pin = 0, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 5) | BIT(5), - }, { - /* emmc-0_cmd */ - .bank_num = 1, - .pin = 22, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 7), - }, { - /* emmc-1_cmd */ - .bank_num = 2, - .pin = 4, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 7) | BIT(7), - }, { - /* uart2-0_rx */ - .bank_num = 1, - .pin = 19, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 8), - }, { - /* uart2-1_rx */ - .bank_num = 1, - .pin = 10, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 8) | BIT(8), - }, { - /* uart1-0_rx */ - .bank_num = 1, - .pin = 10, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 11), - }, { - /* uart1-1_rx */ - .bank_num = 3, - .pin = 13, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 11) | BIT(11), - }, + RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */ + RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */ + RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */ + RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */ + RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */ + RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */ + RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */ + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */ + RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */ + RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */ + RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */ + RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */ + RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */ + RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */ + RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */ + RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */ }; static struct rockchip_mux_route_data rk3288_mux_route_data[] = { - { - /* edphdmi_cecinoutt1 */ - .bank_num = 7, - .pin = 16, - .func = 2, - .route_offset = 0x264, - .route_val = BIT(16 + 12) | BIT(12), - }, { - /* edphdmi_cecinout */ - .bank_num = 7, - .pin = 23, - .func = 4, - .route_offset = 0x264, - .route_val = BIT(16 + 12), - }, + RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */ + RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */ }; static struct rockchip_mux_route_data rk3308_mux_route_data[] = { - { - /* rtc_clk */ - .bank_num = 0, - .pin = 19, - .func = 1, - .route_offset = 0x314, - .route_val = BIT(16 + 0) | BIT(0), - }, { - /* uart2_rxm0 */ - .bank_num = 1, - .pin = 22, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 2) | BIT(16 + 3), - }, { - /* uart2_rxm1 */ - .bank_num = 4, - .pin = 26, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), - }, { - /* i2c3_sdam0 */ - .bank_num = 0, - .pin = 15, - .func = 2, - .route_offset = 0x608, - .route_val = BIT(16 + 8) | BIT(16 + 9), - }, { - /* i2c3_sdam1 */ - .bank_num = 3, - .pin = 12, - .func = 2, - .route_offset = 0x608, - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8), - }, { - /* i2c3_sdam2 */ - .bank_num = 2, - .pin = 0, - .func = 3, - .route_offset = 0x608, - .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9), - }, { - /* i2s-8ch-1-sclktxm0 */ - .bank_num = 1, - .pin = 3, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3), - }, { - /* i2s-8ch-1-sclkrxm0 */ - .bank_num = 1, - .pin = 4, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3), - }, { - /* i2s-8ch-1-sclktxm1 */ - .bank_num = 1, - .pin = 13, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* i2s-8ch-1-sclkrxm1 */ - .bank_num = 1, - .pin = 14, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* pdm-clkm0 */ - .bank_num = 1, - .pin = 4, - .func = 3, - .route_offset = 0x308, - .route_val = BIT(16 + 12) | BIT(16 + 13), - }, { - /* pdm-clkm1 */ - .bank_num = 1, - .pin = 14, - .func = 4, - .route_offset = 0x308, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12), - }, { - /* pdm-clkm2 */ - .bank_num = 2, - .pin = 6, - .func = 2, - .route_offset = 0x308, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13), - }, { - /* pdm-clkm-m2 */ - .bank_num = 2, - .pin = 4, - .func = 3, - .route_offset = 0x600, - .route_val = BIT(16 + 2) | BIT(2), - }, { - /* spi1_miso */ - .bank_num = 3, - .pin = 10, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 9), - }, { - /* spi1_miso_m1 */ - .bank_num = 2, - .pin = 4, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 9) | BIT(9), - }, { - /* owire_m0 */ - .bank_num = 0, - .pin = 11, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 10) | BIT(16 + 11), - }, { - /* owire_m1 */ - .bank_num = 1, - .pin = 22, - .func = 7, - .route_offset = 0x314, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10), - }, { - /* owire_m2 */ - .bank_num = 2, - .pin = 2, - .func = 5, - .route_offset = 0x314, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11), - }, { - /* can_rxd_m0 */ - .bank_num = 0, - .pin = 11, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 12) | BIT(16 + 13), - }, { - /* can_rxd_m1 */ - .bank_num = 1, - .pin = 22, - .func = 5, - .route_offset = 0x314, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12), - }, { - /* can_rxd_m2 */ - .bank_num = 2, - .pin = 2, - .func = 4, - .route_offset = 0x314, - .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13), - }, { - /* mac_rxd0_m0 */ - .bank_num = 1, - .pin = 20, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 14), - }, { - /* mac_rxd0_m1 */ - .bank_num = 4, - .pin = 2, - .func = 2, - .route_offset = 0x314, - .route_val = BIT(16 + 14) | BIT(14), - }, { - /* uart3_rx */ - .bank_num = 3, - .pin = 12, - .func = 4, - .route_offset = 0x314, - .route_val = BIT(16 + 15), - }, { - /* uart3_rx_m1 */ - .bank_num = 0, - .pin = 17, - .func = 3, - .route_offset = 0x314, - .route_val = BIT(16 + 15) | BIT(15), - }, + RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ + RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ + RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ + RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ + RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ + RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ + RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */ + RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */ + RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ + RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ + RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ + RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */ + RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */ + RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */ + RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */ + RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */ + RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */ + RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */ + RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */ + RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */ }; static struct rockchip_mux_route_data rk3328_mux_route_data[] = { - { - /* uart2dbg_rxm0 */ - .bank_num = 1, - .pin = 1, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16) | BIT(16 + 1), - }, { - /* uart2dbg_rxm1 */ - .bank_num = 2, - .pin = 1, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16) | BIT(16 + 1) | BIT(0), - }, { - /* gmac-m1_rxd0 */ - .bank_num = 1, - .pin = 11, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 2) | BIT(2), - }, { - /* gmac-m1-optimized_rxd3 */ - .bank_num = 1, - .pin = 14, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 10) | BIT(10), - }, { - /* pdm_sdi0m0 */ - .bank_num = 2, - .pin = 19, - .func = 2, - .route_offset = 0x50, - .route_val = BIT(16 + 3), - }, { - /* pdm_sdi0m1 */ - .bank_num = 1, - .pin = 23, - .func = 3, - .route_offset = 0x50, - .route_val = BIT(16 + 3) | BIT(3), - }, { - /* spi_rxdm2 */ - .bank_num = 3, - .pin = 2, - .func = 4, - .route_offset = 0x50, - .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5), - }, { - /* i2s2_sdim0 */ - .bank_num = 1, - .pin = 24, - .func = 1, - .route_offset = 0x50, - .route_val = BIT(16 + 6), - }, { - /* i2s2_sdim1 */ - .bank_num = 3, - .pin = 2, - .func = 6, - .route_offset = 0x50, - .route_val = BIT(16 + 6) | BIT(6), - }, { - /* card_iom1 */ - .bank_num = 2, - .pin = 22, - .func = 3, - .route_offset = 0x50, - .route_val = BIT(16 + 7) | BIT(7), - }, { - /* tsp_d5m1 */ - .bank_num = 2, - .pin = 16, - .func = 3, - .route_offset = 0x50, - .route_val = BIT(16 + 8) | BIT(8), - }, { - /* cif_data5m1 */ - .bank_num = 2, - .pin = 16, - .func = 4, - .route_offset = 0x50, - .route_val = BIT(16 + 9) | BIT(9), - }, + RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */ + RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */ + RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */ + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */ + RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */ + RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */ + RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */ + RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */ + RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */ + RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */ + RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */ + RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */ }; static struct rockchip_mux_route_data rk3399_mux_route_data[] = { - { - /* uart2dbga_rx */ - .bank_num = 4, - .pin = 8, - .func = 2, - .route_offset = 0xe21c, - .route_val = BIT(16 + 10) | BIT(16 + 11), - }, { - /* uart2dbgb_rx */ - .bank_num = 4, - .pin = 16, - .func = 2, - .route_offset = 0xe21c, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10), - }, { - /* uart2dbgc_rx */ - .bank_num = 4, - .pin = 19, - .func = 1, - .route_offset = 0xe21c, - .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11), - }, { - /* pcie_clkreqn */ - .bank_num = 2, - .pin = 26, - .func = 2, - .route_offset = 0xe21c, - .route_val = BIT(16 + 14), - }, { - /* pcie_clkreqnb */ - .bank_num = 4, - .pin = 24, - .func = 1, - .route_offset = 0xe21c, - .route_val = BIT(16 + 14) | BIT(14), - }, + RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */ + RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */ + RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */ + RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */ + RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */ }; static struct rockchip_mux_route_data rk3568_mux_route_data[] = { From d562054a3a2eede3507a5461011ee82b671fcb88 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 2 Jan 2023 15:28:45 +0400 Subject: [PATCH 0276/1017] pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups [ Upstream commit c818ae563bf99457f02e8170aabd6b174f629f65 ] of_find_node_by_phandle() returns a node pointer with refcount incremented, We should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak. Fixes: d3e5116119bd ("pinctrl: add pinctrl driver for Rockchip SoCs") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20230102112845.3982407-1-linmq006@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 944c7254f672..764c96ddfc76 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2650,6 +2650,7 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np, np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); ret = pinconf_generic_parse_dt_config(np_config, NULL, &grp->data[j].configs, &grp->data[j].nconfigs); + of_node_put(np_config); if (ret) return ret; } From bc65127ba4c0091886811d94c7d46aecfd13c2f1 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 7 Dec 2022 12:53:13 +0100 Subject: [PATCH 0277/1017] drm/vc4: hvs: Set AXI panic modes [ Upstream commit df993fced230daa8452892406f3180c93ebf7e7b ] The HVS can change AXI request mode based on how full the COB FIFOs are. Until now the vc4 driver has been relying on the firmware to have set these to sensible values. With HVS channel 2 now being used for live video, change the panic mode for all channels to be explicitly set by the driver, and the same for all channels. Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5") Signed-off-by: Dave Stevenson Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-2-1f8e0770798b@cerno.tech Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++ drivers/gpu/drm/vc4/vc4_regs.h | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 95fa6fc052a7..f8f2fc3d15f7 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -677,6 +677,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) SCALER_DISPCTRL_DSPEISLUR(2) | SCALER_DISPCTRL_SCLEIRQ); + /* Set AXI panic mode. + * VC4 panics when < 2 lines in FIFO. + * VC5 panics when less than 1 line in the FIFO. + */ + dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK | + SCALER_DISPCTRL_PANIC1_MASK | + SCALER_DISPCTRL_PANIC2_MASK); + dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0); + dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1); + dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2); + HVS_WRITE(SCALER_DISPCTRL, dispctrl); ret = devm_request_irq(dev, platform_get_irq(pdev, 0), diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index be2c32a519b3..a324ef88ceaf 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -220,6 +220,12 @@ #define SCALER_DISPCTRL 0x00000000 /* Global register for clock gating the HVS */ # define SCALER_DISPCTRL_ENABLE BIT(31) +# define SCALER_DISPCTRL_PANIC0_MASK VC4_MASK(25, 24) +# define SCALER_DISPCTRL_PANIC0_SHIFT 24 +# define SCALER_DISPCTRL_PANIC1_MASK VC4_MASK(27, 26) +# define SCALER_DISPCTRL_PANIC1_SHIFT 26 +# define SCALER_DISPCTRL_PANIC2_MASK VC4_MASK(29, 28) +# define SCALER_DISPCTRL_PANIC2_SHIFT 28 # define SCALER_DISPCTRL_DSP3_MUX_MASK VC4_MASK(19, 18) # define SCALER_DISPCTRL_DSP3_MUX_SHIFT 18 From 15a6be1011c2965a3fbaaf2ce110c63d06351fe5 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 7 Dec 2022 12:53:17 +0100 Subject: [PATCH 0278/1017] drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5 [ Upstream commit 902973dc1a049c0d7bf0c222b8f2b3876f01b4a2 ] Same as the xRGB8888 formats, HVS5 has managed to swap the colour channels for the xRGB1555 formats as well. Add the relevant config for pixel_order_hvs5. Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5") Signed-off-by: Dave Stevenson Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-6-1f8e0770798b@cerno.tech Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_plane.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 4df222a83049..2e03c16c60bb 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -72,11 +72,13 @@ static const struct hvs_format { .drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, .pixel_order = HVS_PIXEL_ORDER_ABGR, + .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB, }, { .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551, .pixel_order = HVS_PIXEL_ORDER_ABGR, + .pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB, }, { .drm = DRM_FORMAT_RGB888, From d4438cbd9c04c7a5cee457193ece2e012cf9ed9b Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 7 Dec 2022 12:53:25 +0100 Subject: [PATCH 0279/1017] drm/vc4: hdmi: Correct interlaced timings again [ Upstream commit 771d6539f27bd55f43d8a95d53a7eeaaffa2681c ] The back porch timings were correct, only the sync offset was wrong. Correct timing is now reported for 1080i and 576i, but the h offset is incorrect for 480i for non-obvious reasons. Fixes: fb10dc451c0f ("drm/vc4: hdmi: Correct HDMI timing registers for interlaced modes") Signed-off-by: Dave Stevenson Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-14-1f8e0770798b@cerno.tech Signed-off-by: Maxime Ripard Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_hdmi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 539ebf85fd7c..7e8620838de9 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -567,11 +567,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep), VC5_HDMI_VERTB_VSPO) | - VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end, + VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end + + interlaced, VC4_HDMI_VERTB_VBP)); u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) | VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end - interlaced, + mode->crtc_vsync_end, VC4_HDMI_VERTB_VBP)); HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); From a3bf72eab8c8c2286fbcddb1d2776342f655332f Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 16 Jan 2023 15:07:54 +0800 Subject: [PATCH 0280/1017] ASoC: fsl_sai: initialize is_dsp_mode flag [ Upstream commit a23924b7dd7b748fff8e305e1daf590fed2af21b ] Initialize is_dsp_mode flag in the beginning of function fsl_sai_set_dai_fmt_tr(). When the DAIFMT is DAIFMT_DSP_B the first time, is_dsp_mode is true, then the second time DAIFMT is DAIFMT_I2S, is_dsp_mode still true, which is a wrong state. So need to initialize is_dsp_mode flag every time. Fixes: a3f7dcc9cc03 ("ASoC: fsl-sai: Add SND_SOC_DAIFMT_DSP_A/B support.") Signed-off-by: Shengjiu Wang Reviewed-by: Iuliana Prodan Link: https://lore.kernel.org/r/1673852874-32200-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/fsl_sai.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 3e5c1eaccd5e..6a5d2b08e271 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -230,6 +230,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, if (!sai->is_lsb_first) val_cr4 |= FSL_SAI_CR4_MF; + sai->is_dsp_mode = false; /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: From b26bd7791f3cdf3c3318162b1d40c9d1910facca Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Wed, 21 Dec 2022 20:39:56 +0530 Subject: [PATCH 0281/1017] drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup() [ Upstream commit dbeedbcb268d055d8895aceca427f897e12c2b50 ] Fix the below kernel panic due to null pointer access: [ 18.504431] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000048 [ 18.513464] Mem abort info: [ 18.516346] ESR = 0x0000000096000005 [ 18.520204] EC = 0x25: DABT (current EL), IL = 32 bits [ 18.525706] SET = 0, FnV = 0 [ 18.528878] EA = 0, S1PTW = 0 [ 18.532117] FSC = 0x05: level 1 translation fault [ 18.537138] Data abort info: [ 18.540110] ISV = 0, ISS = 0x00000005 [ 18.544060] CM = 0, WnR = 0 [ 18.547109] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000112826000 [ 18.553738] [0000000000000048] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 [ 18.562690] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP **Snip** [ 18.696758] Call trace: [ 18.699278] adreno_gpu_cleanup+0x30/0x88 [ 18.703396] a6xx_destroy+0xc0/0x130 [ 18.707066] a6xx_gpu_init+0x308/0x424 [ 18.710921] adreno_bind+0x178/0x288 [ 18.714590] component_bind_all+0xe0/0x214 [ 18.718797] msm_drm_bind+0x1d4/0x614 [ 18.722566] try_to_bring_up_aggregate_device+0x16c/0x1b8 [ 18.728105] __component_add+0xa0/0x158 [ 18.732048] component_add+0x20/0x2c [ 18.735719] adreno_probe+0x40/0xc0 [ 18.739300] platform_probe+0xb4/0xd4 [ 18.743068] really_probe+0xfc/0x284 [ 18.746738] __driver_probe_device+0xc0/0xec [ 18.751129] driver_probe_device+0x48/0x110 [ 18.755421] __device_attach_driver+0xa8/0xd0 [ 18.759900] bus_for_each_drv+0x90/0xdc [ 18.763843] __device_attach+0xfc/0x174 [ 18.767786] device_initial_probe+0x20/0x2c [ 18.772090] bus_probe_device+0x40/0xa0 [ 18.776032] deferred_probe_work_func+0x94/0xd0 [ 18.780686] process_one_work+0x190/0x3d0 [ 18.784805] worker_thread+0x280/0x3d4 [ 18.788659] kthread+0x104/0x1c0 [ 18.791981] ret_from_fork+0x10/0x20 [ 18.795654] Code: f9400408 aa0003f3 aa1f03f4 91142015 (f9402516) [ 18.801913] ---[ end trace 0000000000000000 ]--- [ 18.809039] Kernel panic - not syncing: Oops: Fatal exception Fixes: 17e822f7591f ("drm/msm: fix unbalanced pm_runtime_enable in adreno_gpu_{init, cleanup}") Signed-off-by: Akhil P Oommen Patchwork: https://patchwork.freedesktop.org/patch/515605/ Link: https://lore.kernel.org/r/20221221203925.v2.1.Ib978de92c4bd000b515486aad72e96c2481f84d0@changeid Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index de8cc25506d6..78181e2d78a9 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -954,13 +954,13 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { struct msm_gpu *gpu = &adreno_gpu->base; - struct msm_drm_private *priv = gpu->dev->dev_private; + struct msm_drm_private *priv = gpu->dev ? gpu->dev->dev_private : NULL; unsigned int i; for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) release_firmware(adreno_gpu->fw[i]); - if (pm_runtime_enabled(&priv->gpu_pdev->dev)) + if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev)) pm_runtime_disable(&priv->gpu_pdev->dev); msm_gpu_cleanup(&adreno_gpu->base); From 42fdae9f59b181fbee772a1d85fef6b7ee2e03b7 Mon Sep 17 00:00:00 2001 From: "Alexey V. Vissarionov" Date: Tue, 17 Jan 2023 14:15:23 +0300 Subject: [PATCH 0282/1017] ALSA: hda/ca0132: minor fix for allocation size [ Upstream commit 3ee0fe7fa39b14d1cea455b7041f2df933bd97d2 ] Although the "dma_chan" pointer occupies more or equal space compared to "*dma_chan", the allocation size should use the size of variable itself. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 01ef7dbffb41 ("ALSA: hda - Update CA0132 codec to load DSP firmware binary") Signed-off-by: Alexey V. Vissarionov Link: https://lore.kernel.org/r/20230117111522.GA15213@altlinux.org Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/patch_ca0132.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 82f14c3f642b..24c2638cde37 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -2331,7 +2331,7 @@ static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id, static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan) { int status = 0; - unsigned int size = sizeof(dma_chan); + unsigned int size = sizeof(*dma_chan); codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n"); status = dspio_scp(codec, MASTERCONTROL, 0x20, From 8dbd54d679e3ab37be43bc1ed9f463dbf83a2259 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 10 Jan 2023 00:15:55 +0100 Subject: [PATCH 0283/1017] drm/msm/dpu: Disallow unallocated resources to be returned [ Upstream commit abc40122d9a69f56c04efb5a7485795f5ac799d1 ] In the event that the topology requests resources that have not been created by the system (because they are typically not represented in dpu_mdss_cfg ^1), the resource(s) in global_state (in this case DSC blocks, until their allocation/assignment is being sanity-checked in "drm/msm/dpu: Reject topologies for which no DSC blocks are available") remain NULL but will still be returned out of dpu_rm_get_assigned_resources, where the caller expects to get an array containing num_blks valid pointers (but instead gets these NULLs). To prevent this from happening, where null-pointer dereferences typically result in a hard-to-debug platform lockup, num_blks shouldn't increase past NULL blocks and will print an error and break instead. After all, max_blks represents the static size of the maximum number of blocks whereas the actual amount varies per platform. ^1: which can happen after a git rebase ended up moving additions to _dpu_cfg to a different struct which has the same patch context. Fixes: bb00a452d6f7 ("drm/msm/dpu: Refactor resource manager") Signed-off-by: Marijn Suijten Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/517636/ Link: https://lore.kernel.org/r/20230109231556.344977-1-marijn.suijten@somainline.org Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 74a13ccad34c..948300529743 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -633,6 +633,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, blks_size, enc_id); break; } + if (!hw_blks[i]) { + DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n", + type, enc_id); + break; + } blks[num_blks++] = hw_blks[i]; } From 88618e800acf13f54ee435a132bd40466a02ea31 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 10:16:46 +0200 Subject: [PATCH 0284/1017] drm/bridge: lt9611: fix sleep mode setup [ Upstream commit ae2d329f104b75a0a78dcaded29fe6283289cdf9 ] On atomic_post_disable the bridge goes to the low power state. However the code disables too much of the chip, so the HPD event is not being detected and delivered to the host. Reduce the power saving in order to get the HPD event. Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-2-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 1dcc28a4d853..5e5641ac5ea3 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -446,12 +446,11 @@ static void lt9611_sleep_setup(struct lt9611 *lt9611) { 0x8023, 0x01 }, { 0x8157, 0x03 }, /* set addr pin as output */ { 0x8149, 0x0b }, - { 0x8151, 0x30 }, /* disable IRQ */ + { 0x8102, 0x48 }, /* MIPI Rx power down */ { 0x8123, 0x80 }, { 0x8130, 0x00 }, - { 0x8100, 0x01 }, /* bandgap power down */ - { 0x8101, 0x00 }, /* system clk power down */ + { 0x8011, 0x0a }, }; regmap_multi_reg_write(lt9611->regmap, From 3c865a014623f525acd822b00ee0804364802ce2 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 10:16:47 +0200 Subject: [PATCH 0285/1017] drm/bridge: lt9611: fix HPD reenablement [ Upstream commit a7790f6bd38f3642b60ae3504a2c749135b89451 ] The driver will reset the bridge in the atomic_pre_enable(). However this will also drop the HPD interrupt state. Instead of resetting the bridge, properly wake it up. This fixes the HPD interrupt delivery after the disable/enable cycle. Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-3-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 5e5641ac5ea3..fe660d667daf 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -880,12 +880,18 @@ static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge, static void lt9611_bridge_pre_enable(struct drm_bridge *bridge) { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); + static const struct reg_sequence reg_cfg[] = { + { 0x8102, 0x12 }, + { 0x8123, 0x40 }, + { 0x8130, 0xea }, + { 0x8011, 0xfa }, + }; if (!lt9611->sleep) return; - lt9611_reset(lt9611); - regmap_write(lt9611->regmap, 0x80ee, 0x01); + regmap_multi_reg_write(lt9611->regmap, + reg_cfg, ARRAY_SIZE(reg_cfg)); lt9611->sleep = false; } From bffd0078026fd9578e41fb57cdec87d35629b5b1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 10:16:48 +0200 Subject: [PATCH 0286/1017] drm/bridge: lt9611: fix polarity programming [ Upstream commit 0b157efa384ea417304b1da284ee2f603c607fc3 ] Fix programming of hsync and vsync polarities Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-4-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index fe660d667daf..4c56407c4cf0 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -205,7 +205,6 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod /* stage 2 */ { 0x834a, 0x40 }, - { 0x831d, 0x10 }, /* MK limit */ { 0x832d, 0x38 }, @@ -220,11 +219,19 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod { 0x8325, 0x00 }, { 0x832a, 0x01 }, { 0x834a, 0x10 }, - { 0x831d, 0x10 }, - { 0x8326, 0x37 }, }; + u8 pol = 0x10; - regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + pol |= 0x2; + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + pol |= 0x1; + regmap_write(lt9611->regmap, 0x831d, pol); + + if (mode->hdisplay == 3840) + regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2)); + else + regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); switch (mode->hdisplay) { case 640: @@ -234,7 +241,7 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod regmap_write(lt9611->regmap, 0x8326, 0x37); break; case 3840: - regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2)); + regmap_write(lt9611->regmap, 0x8326, 0x37); break; } From aa37ec52c1a98c7cf757e5204d93bf0873c07b99 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 10:16:49 +0200 Subject: [PATCH 0287/1017] drm/bridge: lt9611: fix programming of video modes [ Upstream commit ad188aa47edaa033a270e1a3efae43836ff47569 ] Program the upper part of the hfront_porch into the proper register. Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-5-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 4c56407c4cf0..4925566dfc54 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -185,7 +185,8 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611, regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256)); - regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256)); + regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256) | + ((hfront_porch / 256) << 4)); regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256)); } From ffd4cbd7eabd7c082504512ac90d236ee162b276 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 10:16:50 +0200 Subject: [PATCH 0288/1017] drm/bridge: lt9611: fix clock calculation [ Upstream commit 2576eb26494eb0509dd9ceb0cd27771a7a5e3674 ] Instead of having several fixed values for the pcr register, calculate it before programming. This allows the bridge to support most of the display modes. Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-6-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611.c | 32 +++++++++++-------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 4925566dfc54..bb13511dd426 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -190,8 +190,9 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611, regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256)); } -static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode) +static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int postdiv) { + unsigned int pcr_m = mode->clock * 5 * postdiv / 27000; const struct reg_sequence reg_cfg[] = { { 0x830b, 0x01 }, { 0x830c, 0x10 }, @@ -234,24 +235,14 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod else regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); - switch (mode->hdisplay) { - case 640: - regmap_write(lt9611->regmap, 0x8326, 0x14); - break; - case 1920: - regmap_write(lt9611->regmap, 0x8326, 0x37); - break; - case 3840: - regmap_write(lt9611->regmap, 0x8326, 0x37); - break; - } + regmap_write(lt9611->regmap, 0x8326, pcr_m); /* pcr rst */ regmap_write(lt9611->regmap, 0x8011, 0x5a); regmap_write(lt9611->regmap, 0x8011, 0xfa); } -static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode) +static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int *postdiv) { unsigned int pclk = mode->clock; const struct reg_sequence reg_cfg[] = { @@ -269,12 +260,16 @@ static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); - if (pclk > 150000) + if (pclk > 150000) { regmap_write(lt9611->regmap, 0x812d, 0x88); - else if (pclk > 70000) + *postdiv = 1; + } else if (pclk > 70000) { regmap_write(lt9611->regmap, 0x812d, 0x99); - else + *postdiv = 2; + } else { regmap_write(lt9611->regmap, 0x812d, 0xaa); + *postdiv = 4; + } /* * first divide pclk by 2 first @@ -917,14 +912,15 @@ static void lt9611_bridge_mode_set(struct drm_bridge *bridge, { struct lt9611 *lt9611 = bridge_to_lt9611(bridge); struct hdmi_avi_infoframe avi_frame; + unsigned int postdiv; int ret; lt9611_bridge_pre_enable(bridge); lt9611_mipi_input_digital(lt9611, mode); - lt9611_pll_setup(lt9611, mode); + lt9611_pll_setup(lt9611, mode, &postdiv); lt9611_mipi_video_setup(lt9611, mode); - lt9611_pcr_setup(lt9611, mode); + lt9611_pcr_setup(lt9611, mode, postdiv); ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, <9611->connector, From 10c58ca62a54bbf513b290f4ae05b26d9446a364 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 10:16:51 +0200 Subject: [PATCH 0289/1017] drm/bridge: lt9611: pass a pointer to the of node [ Upstream commit b0a7f8736789935f62d6df32d441cdf05a5c05d2 ] Pass a pointer to the OF node while registering lt9611 MIPI device. Fixes: 23278bf54afe ("drm/bridge: Introduce LT9611 DSI to HDMI bridge") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-7-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index bb13511dd426..0c6dea9ccb72 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -759,7 +759,7 @@ static const struct drm_connector_funcs lt9611_bridge_connector_funcs = { static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611, struct device_node *dsi_node) { - const struct mipi_dsi_device_info info = { "lt9611", 0, NULL }; + const struct mipi_dsi_device_info info = { "lt9611", 0, lt9611->dev->of_node}; struct mipi_dsi_device *dsi; struct mipi_dsi_host *host; int ret; From 23770064a339ae9130cbe03de4bf47989298de59 Mon Sep 17 00:00:00 2001 From: Daniel Mentz Date: Mon, 16 Jan 2023 17:49:07 -0500 Subject: [PATCH 0290/1017] drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness [ Upstream commit c9d27c6be518b4ef2966d9564654ef99292ea1b3 ] The MIPI DCS specification demands that brightness values are sent in big endian byte order. It also states that one parameter (i.e. one byte) shall be sent/received for 8 bit wide values, and two parameters shall be used for values that are between 9 and 16 bits wide. Add new functions to properly handle 16-bit brightness in big endian, since the two 8- and 16-bit cases are distinct from each other. [richard: use separate functions instead of switch/case] [richard: split into 16-bit component] Fixes: 1a9d759331b8 ("drm/dsi: Implement DCS set/get display brightness") Signed-off-by: Daniel Mentz Link: https://android.googlesource.com/kernel/msm/+/754affd62d0ee268c686c53169b1dbb7deac8550 [richard: fix 16-bit brightness_get] Signed-off-by: Richard Acayan Tested-by: Caleb Connolly Reviewed-by: Neil Armstrong Reviewed-by: Sam Ravnborg Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230116224909.23884-2-mailingradian@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_mipi_dsi.c | 52 ++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 4 +++ 2 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 2c43d54766f3..19fb1d93a4f0 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -1143,6 +1143,58 @@ int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, } EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); +/** + * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value + * of the display + * @dsi: DSI peripheral device + * @brightness: brightness value + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, + u16 brightness) +{ + u8 payload[2] = { brightness >> 8, brightness & 0xff }; + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, + payload, sizeof(payload)); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large); + +/** + * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit + * brightness value of the display + * @dsi: DSI peripheral device + * @brightness: brightness value + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, + u16 *brightness) +{ + u8 brightness_be[2]; + ssize_t err; + + err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, + brightness_be, sizeof(brightness_be)); + if (err <= 0) { + if (err == 0) + err = -ENODATA; + + return err; + } + + *brightness = (brightness_be[0] << 8) | brightness_be[1]; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); + static int mipi_dsi_drv_probe(struct device *dev) { struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 360e6377e84b..31ba85a4110a 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -283,6 +283,10 @@ int mipi_dsi_dcs_set_display_brightness(struct mipi_dsi_device *dsi, u16 brightness); int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi, u16 *brightness); +int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, + u16 brightness); +int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, + u16 *brightness); /** * struct mipi_dsi_driver - DSI driver From 70bc4db1fb7b47ef17b5342529d022497a6e1e7d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 18 Jan 2023 04:01:52 +0200 Subject: [PATCH 0291/1017] drm/msm: use strscpy instead of strncpy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d7fd8634f48d76aa799ed57beb7d87dab91bde80 ] Using strncpy can result in non-NULL-terminated destination string. Use strscpy instead. This fixes following warning: drivers/gpu/drm/msm/msm_fence.c: In function ‘msm_fence_context_alloc’: drivers/gpu/drm/msm/msm_fence.c:25:9: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation] 25 | strncpy(fctx->name, name, sizeof(fctx->name)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fixes: f97decac5f4c ("drm/msm: Support multiple ringbuffers") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/518787/ Link: https://lore.kernel.org/r/20230118020152.1689213-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index cd59a5918038..50a25c119f4d 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -20,7 +20,7 @@ msm_fence_context_alloc(struct drm_device *dev, const char *name) return ERR_PTR(-ENOMEM); fctx->dev = dev; - strncpy(fctx->name, name, sizeof(fctx->name)); + strscpy(fctx->name, name, sizeof(fctx->name)); fctx->context = dma_fence_context_alloc(1); init_waitqueue_head(&fctx->event); spin_lock_init(&fctx->spinlock); From 31f2f8de0ea7387cde18a24f94ba5e0b886b9842 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 6 Dec 2022 16:05:17 +0800 Subject: [PATCH 0292/1017] drm/msm/dpu: Add check for cstate [ Upstream commit c96988b7d99327bb08bd9efd29a203b22cd88ace ] As kzalloc may fail and return NULL pointer, it should be better to check cstate in order to avoid the NULL pointer dereference in __drm_atomic_helper_crtc_reset. Fixes: 1cff7440a86e ("drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for reset.") Signed-off-by: Jiasheng Jiang Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/514163/ Link: https://lore.kernel.org/r/20221206080517.43786-1-jiasheng@iscas.ac.cn Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index f56414a06ec4..d6e9efed8b6a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -682,7 +682,10 @@ static void dpu_crtc_reset(struct drm_crtc *crtc) if (crtc->state) dpu_crtc_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &cstate->base); + if (cstate) + __drm_atomic_helper_crtc_reset(crtc, &cstate->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); } /** From e9743b3052e125c44b555f07f2876a4bdccfd983 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 6 Dec 2022 16:02:36 +0800 Subject: [PATCH 0293/1017] drm/msm/dpu: Add check for pstates [ Upstream commit 93340e10b9c5fc86730d149636e0aa8b47bb5a34 ] As kzalloc may fail and return NULL pointer, it should be better to check pstates in order to avoid the NULL pointer dereference. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Jiasheng Jiang Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/514160/ Link: https://lore.kernel.org/r/20221206080236.43687-1-jiasheng@iscas.ac.cn Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index d6e9efed8b6a..5afb3c544653 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -834,6 +834,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_rect crtc_rect = { 0 }; pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL); + if (!pstates) + return -ENOMEM; if (!state->enable || !state->active) { DPU_DEBUG("crtc%d -> enable %d, active %d, skip atomic_check\n", From 49907c8873826ee771ba0ca1629e809c6479f617 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 6 Dec 2022 15:48:19 +0800 Subject: [PATCH 0294/1017] drm/msm/mdp5: Add check for kzalloc [ Upstream commit 13fcfcb2a9a4787fe4e49841d728f6f2e9fa6911 ] As kzalloc may fail and return NULL pointer, it should be better to check the return value in order to avoid the NULL pointer dereference. Fixes: 1cff7440a86e ("drm/msm: Convert to using __drm_atomic_helper_crtc_reset() for reset.") Signed-off-by: Jiasheng Jiang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/514154/ Link: https://lore.kernel.org/r/20221206074819.18134-1-jiasheng@iscas.ac.cn Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index ff4f207cbdea..60e7371cd0e0 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -1124,7 +1124,10 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc) if (crtc->state) mdp5_crtc_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); + if (mdp5_cstate) + __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); } static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { From a46d29437b0a2a948d368758cd50396272be910c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 13 Jan 2023 23:53:50 +0200 Subject: [PATCH 0295/1017] pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback() [ Upstream commit 2d578dd27871372f7159dd3206149ec616700d87 ] Remove wrong of_node_put() in bcm2835_of_gpio_ranges_fallback(), there is no counterpart of_node_get() for it. Fixes: d2b67744fd99 ("pinctrl: bcm2835: implement hook for missing gpio-ranges") Signed-off-by: Andy Shevchenko Reviewed-by: Stefan Wahren Tested-by: Stefan Wahren Tested-by: Florian Fainelli Reviewed-by: Florian Fainelli Acked-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/20230113215352.44272-3-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 39d2024dc2ee..c7ae9f900b53 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -356,8 +356,6 @@ static int bcm2835_of_gpio_ranges_fallback(struct gpio_chip *gc, { struct pinctrl_dev *pctldev = of_pinctrl_get(np); - of_node_put(np); - if (!pctldev) return 0; From d2eb2e7125143fc4531b938c2c47e365b9f1a436 Mon Sep 17 00:00:00 2001 From: Guodong Liu Date: Wed, 18 Jan 2023 14:20:35 +0800 Subject: [PATCH 0296/1017] pinctrl: mediatek: Initialize variable pullen and pullup to zero [ Upstream commit a298c70a10c604a6b3df5a0aa56597b705ba0f6b ] Coverity spotted that pullen and pullup is not initialized to zero in mtk_pctrl_show_one_pin. The uninitialized variable pullen is used in assignment statement "rsel = pullen;" in mtk_pctrl_show_one_pin, and Uninitialized variable pullup is used when calling scnprintf. Fix this coverity by initializing pullen and pullup as zero. Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.") Signed-off-by: Guodong Liu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230118062036.26258-2-Guodong.Liu@mediatek.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/mediatek/pinctrl-paris.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index d0a4ebbe1e7e..2a9d2801388d 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -574,7 +574,7 @@ static int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw, unsigned int gpio, char *buf, unsigned int bufLen) { - int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1; + int pinmux, pullup = 0, pullen = 0, len = 0, r1 = -1, r0 = -1; const struct mtk_pin_desc *desc; if (gpio >= hw->soc->npins) From 53f98ffcd89bf382ae3e4792cef5b1b25268424e Mon Sep 17 00:00:00 2001 From: Guodong Liu Date: Wed, 18 Jan 2023 14:20:36 +0800 Subject: [PATCH 0297/1017] pinctrl: mediatek: Initialize variable *buf to zero [ Upstream commit 2e34f82ba214134ecf590fbe0cdbd87401645a8a ] Coverity spotted that *buf is not initialized to zero in mtk_pctrl_dbg_show. Using uninitialized variable *buf as argument to %s when calling seq_printf. Fix this coverity by initializing *buf as zero. Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.") Signed-off-by: Guodong Liu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230118062036.26258-3-Guodong.Liu@mediatek.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/mediatek/pinctrl-paris.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 2a9d2801388d..e486d66e220b 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -637,7 +637,7 @@ static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int gpio) { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); - char buf[PIN_DBG_BUF_SZ]; + char buf[PIN_DBG_BUF_SZ] = { 0 }; (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ); From cfd710a7e5a53b3c537d6ba142bb9933bad87357 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Thu, 19 Jan 2023 15:39:00 +0200 Subject: [PATCH 0298/1017] gpu: host1x: Don't skip assigning syncpoints to channels [ Upstream commit eb258cc1fd458e584082be987dbc6ec42668c05e ] The code to write the syncpoint channel assignment register incorrectly skips the write if hypervisor registers are not available. The register, however, is within the guest aperture so remove the check and assign syncpoints properly even on virtualized systems. Fixes: c3f52220f276 ("gpu: host1x: Enable Tegra186 syncpoint protection") Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- drivers/gpu/host1x/hw/syncpt_hw.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c index dd39d67ccec3..8cf35b2eff3d 100644 --- a/drivers/gpu/host1x/hw/syncpt_hw.c +++ b/drivers/gpu/host1x/hw/syncpt_hw.c @@ -106,9 +106,6 @@ static void syncpt_assign_to_channel(struct host1x_syncpt *sp, #if HOST1X_HW >= 6 struct host1x *host = sp->host; - if (!host->hv_regs) - return; - host1x_sync_writel(host, HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff), HOST1X_SYNC_SYNCPT_CH_APP(sp->id)); From da5fd53999335be8296410b41304457788a4b1cf Mon Sep 17 00:00:00 2001 From: Xinlei Lee Date: Tue, 10 Jan 2023 13:54:51 +0800 Subject: [PATCH 0299/1017] drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd [ Upstream commit 91aeaed2c1147e3b1157dc084d23f190856a6c23 ] According to Figure 16 Turnaround Procedure on page 36 in [1], you can see the status of LP-00 -> LP10 -> LP11. This state can correspond to the state of DSI from LP00 -> LP11 in mtk_dsi_lane_ready function in mtk_dsi.c. LP-00 -> LP10 -> LP11 takes about 2*TLPX time (refer to [1] page 51 to see that TLPX is 50ns) The delay at the end of the mtk_dsi_lane_ready function should be greater than the 2*TLPX specified by the DSI spec, and less than the time specified by the DSI_RX (generally 6ms to 40ms), to avoid problems caused by the RX specification [1]:mipi_D-PHY_specification_v1-1 Fixes: 39e8d062b03c ("drm/mediatek: Keep dsi as LP00 before dcs cmds transfer") Signed-off-by: Xinlei Lee Acked-by: Sam Ravnborg Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1673330093-6771-2-git-send-email-xinlei.lee@mediatek.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 146c4d04f572..a6e71b7b69b8 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -704,7 +704,7 @@ static void mtk_dsi_lane_ready(struct mtk_dsi *dsi) mtk_dsi_clk_ulp_mode_leave(dsi); mtk_dsi_lane0_ulp_mode_leave(dsi); mtk_dsi_clk_hs_mode(dsi, 0); - msleep(20); + usleep_range(1000, 3000); /* The reaction time after pulling up the mipi signal for dsi_rx */ } } From 55bc7babc094db91342a8dc98270fe240e35e96b Mon Sep 17 00:00:00 2001 From: Miles Chen Date: Wed, 11 Jan 2023 10:44:41 +0800 Subject: [PATCH 0300/1017] drm/mediatek: Use NULL instead of 0 for NULL pointer [ Upstream commit 4744cde06f57dd6fbaac468663b1fe2f653eaa16 ] Use NULL for NULL pointer to fix the following sparse warning: drivers/gpu/drm/mediatek/mtk_drm_gem.c:265:27: sparse: warning: Using plain integer as NULL pointer Fixes: 3df64d7b0a4f ("drm/mediatek: Implement gem prime vmap/vunmap function") Signed-off-by: Miles Chen Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230111024443.24559-1-miles.chen@mediatek.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 0583e557ad37..43c54dde2f3f 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -266,6 +266,6 @@ void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) return; vunmap(vaddr); - mtk_gem->kvaddr = 0; + mtk_gem->kvaddr = NULL; kfree(mtk_gem->pages); } From 3a50d86696f6a7305b84987a9096ed111bf85e8f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 19 Jan 2023 15:12:55 -0800 Subject: [PATCH 0301/1017] drm/mediatek: Drop unbalanced obj unref [ Upstream commit 4deef811828e87e26a978d5d6433b261d4713849 ] In the error path, mtk_drm_gem_object_mmap() is dropping an obj reference that it doesn't own. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Rob Clark Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230119231255.2883365-1-robdclark@gmail.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 43c54dde2f3f..29702dd8631d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -142,8 +142,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie, mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs); - if (ret) - drm_gem_vm_close(vma); return ret; } From b64b6dff15a38468b8cd33fc7864fa4e02b0933a Mon Sep 17 00:00:00 2001 From: ruanjinjie Date: Mon, 5 Dec 2022 17:51:15 +0800 Subject: [PATCH 0302/1017] drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc [ Upstream commit 5bf1e3bd7da625ccf9a22c8cb7d65271e6e47f4c ] As the devm_kcalloc may return NULL, the return value needs to be checked to avoid NULL poineter dereference. Fixes: 31c5558dae05 ("drm/mediatek: Refactor plane init") Signed-off-by: ruanjinjie Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20221205095115.2905090-1-ruanjinjie@huawei.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index dfd5ed15a7f4..e83b1c406b96 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -803,6 +803,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, mtk_crtc->planes = devm_kcalloc(dev, num_comp_planes, sizeof(struct drm_plane), GFP_KERNEL); + if (!mtk_crtc->planes) + return -ENOMEM; for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i, From 6a89ddee1686a8872384aaa9f0bcfa6b675acd86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 22 Nov 2022 09:39:49 -0500 Subject: [PATCH 0303/1017] drm/mediatek: Clean dangling pointer on bind error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 36aa8c61af55675ed967900fbe5deb32d776f051 ] mtk_drm_bind() can fail, in which case drm_dev_put() is called, destroying the drm_device object. However a pointer to it was still being held in the private object, and that pointer would be passed along to DRM in mtk_drm_sys_prepare() if a suspend were triggered at that point, resulting in a panic. Clean the pointer when destroying the object in the error path to prevent this from happening. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20221122143949.3493104-1-nfraprado@collabora.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 59c85c63b7cc..719c46d245dd 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -378,6 +378,7 @@ static int mtk_drm_bind(struct device *dev) err_deinit: mtk_drm_kms_deinit(drm); err_free: + private->drm = NULL; drm_dev_put(drm); return ret; } From f2f6e683d9e76b2678a39b5d18a29098a41dc281 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 23 Jan 2023 23:17:20 +0000 Subject: [PATCH 0304/1017] ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress() [ Upstream commit ffe4c0f0bfaa571a676a0e946d4a6a0607f94294 ] commit d3268a40d4b19f ("ASoC: soc-compress.c: fix NULL dereference") enables DPCM capture, but it should independent from playback. This patch fixup it. Fixes: d3268a40d4b1 ("ASoC: soc-compress.c: fix NULL dereference") Link: https://lore.kernel.org/r/87tu0i6j7j.wl-kuninori.morimoto.gx@renesas.com Acked-by: Charles Keepax Acked-by: Pierre-Louis Bossart Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/871qnkvo1s.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/soc-compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index d0f3ff8edd90..8f4ebb189e01 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -822,7 +822,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) rtd->fe_compr = 1; if (rtd->dai_link->dpcm_playback) be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; - else if (rtd->dai_link->dpcm_capture) + if (rtd->dai_link->dpcm_capture) be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); } else { From 33033f392d8122a94074472191f961243079a14c Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Tue, 20 Dec 2022 17:02:47 +0800 Subject: [PATCH 0305/1017] gpio: vf610: connect GPIO label to dev name [ Upstream commit 6f8ecb7f85f441eb7d78ba2a4df45ee8a821934e ] Current GPIO label is fixed, so can't distinguish different GPIO controllers through labels. Use dev name instead. Fixes: 7f2691a19627 ("gpio: vf610: add gpiolib/IRQ chip driver for Vybrid") Signed-off-by: Clark Wang Signed-off-by: Haibo Chen Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin --- drivers/gpio/gpio-vf610.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index 1ae612c796ee..396a687e020f 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -304,7 +304,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) gc = &port->gc; gc->of_node = np; gc->parent = dev; - gc->label = "vf610-gpio"; + gc->label = dev_name(dev); gc->ngpio = VF610_GPIO_PER_PORT; gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT; From b33ca7b7bb66332e3498d0e3f3d912af5cbcc465 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 30 Jan 2023 15:01:40 +0100 Subject: [PATCH 0306/1017] spi: dw_bt1: fix MUX_MMIO dependencies [ Upstream commit d4bde04318c0d33705e9a77d4c7df72f262011e0 ] Selecting a symbol with additional dependencies requires adding the same dependency here: WARNING: unmet direct dependencies detected for MUX_MMIO Depends on [n]: MULTIPLEXER [=y] && OF [=n] Selected by [y]: - SPI_DW_BT1 [=y] && SPI [=y] && SPI_MASTER [=y] && SPI_DESIGNWARE [=y] && (MIPS_BAIKAL_T1 || COMPILE_TEST [=y]) Drop the 'select' here to avoid the problem. Anyone using the dw-bt1 SPI driver should make sure they include the mux driver as well now. Fixes: 7218838109fe ("spi: dw-bt1: Fix undefined devm_mux_control_get symbol") Fixes: abf00907538e ("spi: dw: Add Baikal-T1 SPI Controller glue driver") Link: https://lore.kernel.org/all/20221218192523.c6vnfo26ua6xqf26@mobilestation/ Signed-off-by: Arnd Bergmann Reviewed-by: Serge Semin Link: https://lore.kernel.org/r/20230130140156.3620863-1-arnd@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index aadaea052f51..4d98ce7571df 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -256,7 +256,6 @@ config SPI_DW_BT1 tristate "Baikal-T1 SPI driver for DW SPI core" depends on MIPS_BAIKAL_T1 || COMPILE_TEST select MULTIPLEXER - select MUX_MMIO help Baikal-T1 SoC is equipped with three DW APB SSI-based MMIO SPI controllers. Two of them are pretty much normal: with IRQ, DMA, From 1983a70778eb999f62fe4d6dfa8bcfefe0b7f47f Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 30 Jan 2023 14:06:40 +0200 Subject: [PATCH 0307/1017] ASoC: mchp-spdifrx: fix controls which rely on rsr register [ Upstream commit fa09fa60385abbf99342494b280da8b4aebbc0e9 ] The SPDIFRX block is clocked by 2 clocks: peripheral and generic clocks. Peripheral clock feeds user interface (registers) and generic clock feeds the receiver. To enable the receiver the generic clock needs to be enabled and also the ENABLE bit of MCHP_SPDIFRX_MR register need to be set. The signal control exported by mchp-spdifrx driver reports wrong status when the receiver is disabled. This can happen when requesting the signal and the capture was not previously started. To solve this the receiver needs to be enabled (by enabling generic clock and setting ENABLE bit of MR register) before reading the signal status. As with this fix there are 2 paths now that need to control the generic clock and ENABLE bit of SPDIFRX_MR register (one path though controls, one path though configuration) a mutex has been introduced. We can't rely on subsystem locking as the controls are protected by struct snd_card::controls_rwsem semaphore and configuration is protected by a different lock (embedded in snd_pcm_stream_lock_irq()). The introduction of mutex is also extended to other controls which rely on SPDIFRX_RSR.ULOCK bit as it has been discovered experimentally that having both clocks enabled but not the receiver (through ENABLE bit of SPDIFRX.MR) leads to inconsistent values of SPDIFRX_RSR.ULOCK. Thus on some controls we rely on software state (dev->trigger_enabled protected by mutex) to retrieve proper values. Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230130120647.638049-2-claudiu.beznea@microchip.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/atmel/mchp-spdifrx.c | 190 ++++++++++++++++++++++++--------- 1 file changed, 141 insertions(+), 49 deletions(-) diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index 46f3407ed0e8..c83f32a462f6 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -233,11 +233,13 @@ struct mchp_spdifrx_dev { struct mchp_spdifrx_mixer_control control; spinlock_t blockend_lock; /* protect access to blockend_refcount */ int blockend_refcount; + struct mutex mlock; struct device *dev; struct regmap *regmap; struct clk *pclk; struct clk *gclk; unsigned int fmt; + unsigned int trigger_enabled; unsigned int gclk_enabled:1; }; @@ -353,47 +355,40 @@ static int mchp_spdifrx_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); - u32 mr; - int running; - int ret; - - regmap_read(dev->regmap, SPDIFRX_MR, &mr); - running = !!(mr & SPDIFRX_MR_RXEN_ENABLE); + int ret = 0; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (!running) { - mr &= ~SPDIFRX_MR_RXEN_MASK; - mr |= SPDIFRX_MR_RXEN_ENABLE; - /* enable overrun interrupts */ - regmap_write(dev->regmap, SPDIFRX_IER, - SPDIFRX_IR_OVERRUN); - } + mutex_lock(&dev->mlock); + /* Enable overrun interrupts */ + regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_OVERRUN); + + /* Enable receiver. */ + regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, + SPDIFRX_MR_RXEN_ENABLE); + dev->trigger_enabled = true; + mutex_unlock(&dev->mlock); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (running) { - mr &= ~SPDIFRX_MR_RXEN_MASK; - mr |= SPDIFRX_MR_RXEN_DISABLE; - /* disable overrun interrupts */ - regmap_write(dev->regmap, SPDIFRX_IDR, - SPDIFRX_IR_OVERRUN); - } + mutex_lock(&dev->mlock); + /* Disable overrun interrupts */ + regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_OVERRUN); + + /* Disable receiver. */ + regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, + SPDIFRX_MR_RXEN_DISABLE); + dev->trigger_enabled = false; + mutex_unlock(&dev->mlock); break; default: - return -EINVAL; + ret = -EINVAL; } - ret = regmap_write(dev->regmap, SPDIFRX_MR, mr); - if (ret) { - dev_err(dev->dev, "unable to enable/disable RX: %d\n", ret); - return ret; - } - - return 0; + return ret; } static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream, @@ -413,13 +408,6 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - regmap_read(dev->regmap, SPDIFRX_MR, &mr); - - if (mr & SPDIFRX_MR_RXEN_ENABLE) { - dev_err(dev->dev, "PCM already running\n"); - return -EBUSY; - } - if (params_channels(params) != SPDIFRX_CHANNELS) { dev_err(dev->dev, "unsupported number of channels: %d\n", params_channels(params)); @@ -445,6 +433,13 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } + mutex_lock(&dev->mlock); + if (dev->trigger_enabled) { + dev_err(dev->dev, "PCM already running\n"); + ret = -EBUSY; + goto unlock; + } + if (dev->gclk_enabled) { clk_disable_unprepare(dev->gclk); dev->gclk_enabled = 0; @@ -455,19 +450,24 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream, dev_err(dev->dev, "unable to set gclk min rate: rate %u * ratio %u + 1\n", params_rate(params), SPDIFRX_GCLK_RATIO_MIN); - return ret; + goto unlock; } ret = clk_prepare_enable(dev->gclk); if (ret) { dev_err(dev->dev, "unable to enable gclk: %d\n", ret); - return ret; + goto unlock; } dev->gclk_enabled = 1; dev_dbg(dev->dev, "GCLK range min set to %d\n", params_rate(params) * SPDIFRX_GCLK_RATIO_MIN + 1); - return regmap_write(dev->regmap, SPDIFRX_MR, mr); + ret = regmap_write(dev->regmap, SPDIFRX_MR, mr); + +unlock: + mutex_unlock(&dev->mlock); + + return ret; } static int mchp_spdifrx_hw_free(struct snd_pcm_substream *substream, @@ -475,10 +475,12 @@ static int mchp_spdifrx_hw_free(struct snd_pcm_substream *substream, { struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); + mutex_lock(&dev->mlock); if (dev->gclk_enabled) { clk_disable_unprepare(dev->gclk); dev->gclk_enabled = 0; } + mutex_unlock(&dev->mlock); return 0; } @@ -627,10 +629,24 @@ static int mchp_spdifrx_ulock_get(struct snd_kcontrol *kcontrol, u32 val; bool ulock_old = ctrl->ulock; - regmap_read(dev->regmap, SPDIFRX_RSR, &val); - ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK); + mutex_lock(&dev->mlock); + + /* + * The RSR.ULOCK has wrong value if both pclk and gclk are enabled + * and the receiver is disabled. Thus we take into account the + * dev->trigger_enabled here to return a real status. + */ + if (dev->trigger_enabled) { + regmap_read(dev->regmap, SPDIFRX_RSR, &val); + ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK); + } else { + ctrl->ulock = 0; + } + uvalue->value.integer.value[0] = ctrl->ulock; + mutex_unlock(&dev->mlock); + return ulock_old != ctrl->ulock; } @@ -643,8 +659,22 @@ static int mchp_spdifrx_badf_get(struct snd_kcontrol *kcontrol, u32 val; bool badf_old = ctrl->badf; - regmap_read(dev->regmap, SPDIFRX_RSR, &val); - ctrl->badf = !!(val & SPDIFRX_RSR_BADF); + mutex_lock(&dev->mlock); + + /* + * The RSR.ULOCK has wrong value if both pclk and gclk are enabled + * and the receiver is disabled. Thus we take into account the + * dev->trigger_enabled here to return a real status. + */ + if (dev->trigger_enabled) { + regmap_read(dev->regmap, SPDIFRX_RSR, &val); + ctrl->badf = !!(val & SPDIFRX_RSR_BADF); + } else { + ctrl->badf = 0; + } + + mutex_unlock(&dev->mlock); + uvalue->value.integer.value[0] = ctrl->badf; return badf_old != ctrl->badf; @@ -656,11 +686,48 @@ static int mchp_spdifrx_signal_get(struct snd_kcontrol *kcontrol, struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); struct mchp_spdifrx_mixer_control *ctrl = &dev->control; - u32 val; + u32 val = ~0U, loops = 10; + int ret; bool signal_old = ctrl->signal; - regmap_read(dev->regmap, SPDIFRX_RSR, &val); - ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL); + mutex_lock(&dev->mlock); + + /* + * To get the signal we need to have receiver enabled. This + * could be enabled also from trigger() function thus we need to + * take care of not disabling the receiver when it runs. + */ + if (!dev->trigger_enabled) { + ret = clk_prepare_enable(dev->gclk); + if (ret) + goto unlock; + + regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, + SPDIFRX_MR_RXEN_ENABLE); + + /* Wait for RSR.ULOCK bit. */ + while (--loops) { + regmap_read(dev->regmap, SPDIFRX_RSR, &val); + if (!(val & SPDIFRX_RSR_ULOCK)) + break; + usleep_range(100, 150); + } + + regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, + SPDIFRX_MR_RXEN_DISABLE); + + clk_disable_unprepare(dev->gclk); + } else { + regmap_read(dev->regmap, SPDIFRX_RSR, &val); + } + +unlock: + mutex_unlock(&dev->mlock); + + if (!(val & SPDIFRX_RSR_ULOCK)) + ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL); + else + ctrl->signal = 0; uvalue->value.integer.value[0] = ctrl->signal; return signal_old != ctrl->signal; @@ -685,18 +752,32 @@ static int mchp_spdifrx_rate_get(struct snd_kcontrol *kcontrol, u32 val; int rate; - regmap_read(dev->regmap, SPDIFRX_RSR, &val); + mutex_lock(&dev->mlock); - /* if the receiver is not locked, ISF data is invalid */ - if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) { + /* + * The RSR.ULOCK has wrong value if both pclk and gclk are enabled + * and the receiver is disabled. Thus we take into account the + * dev->trigger_enabled here to return a real status. + */ + if (dev->trigger_enabled) { + regmap_read(dev->regmap, SPDIFRX_RSR, &val); + /* If the receiver is not locked, ISF data is invalid. */ + if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) { + ucontrol->value.integer.value[0] = 0; + goto unlock; + } + } else { + /* Reveicer is not locked, IFS data is invalid. */ ucontrol->value.integer.value[0] = 0; - return 0; + goto unlock; } rate = clk_get_rate(dev->gclk); ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val)); +unlock: + mutex_unlock(&dev->mlock); return 0; } @@ -912,7 +993,18 @@ static int mchp_spdifrx_probe(struct platform_device *pdev) "failed to get the PMC generated clock: %d\n", err); return err; } + + /* + * Signal control need a valid rate on gclk. hw_params() configures + * it propertly but requesting signal before any hw_params() has been + * called lead to invalid value returned for signal. Thus, configure + * gclk at a valid rate, here, in initialization, to simplify the + * control path. + */ + clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1); + spin_lock_init(&dev->blockend_lock); + mutex_init(&dev->mlock); dev->dev = &pdev->dev; dev->regmap = regmap; From 426423ed55def0667770b05ef8fcb1b3f6fe9317 Mon Sep 17 00:00:00 2001 From: Gu Shengxian Date: Tue, 6 Jul 2021 18:02:30 +0800 Subject: [PATCH 0308/1017] ASoC: atmel: fix spelling mistakes [ Upstream commit 55233b22502151e0b2d9cc599e1ddf1f5584c87a ] Fix some spelling mistakes as follows: regaedles ==> regardless prezent ==> present underrrun ==> underrun controlls ==> controls Signed-off-by: Gu Shengxian Link: https://lore.kernel.org/r/20210706100230.32633-1-gushengxian507419@gmail.com Signed-off-by: Mark Brown Stable-dep-of: a4c4161d6eae ("ASoC: mchp-spdifrx: fix return value in case completion times out") Signed-off-by: Sasha Levin --- sound/soc/atmel/mchp-spdifrx.c | 6 +++--- sound/soc/atmel/mchp-spdiftx.c | 2 +- sound/soc/atmel/tse850-pcm5142.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index c83f32a462f6..3962ce00ad34 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -56,7 +56,7 @@ /* Validity Bit Mode */ #define SPDIFRX_MR_VBMODE_MASK GENAMSK(1, 1) #define SPDIFRX_MR_VBMODE_ALWAYS_LOAD \ - (0 << 1) /* Load sample regardles of validity bit value */ + (0 << 1) /* Load sample regardless of validity bit value */ #define SPDIFRX_MR_VBMODE_DISCARD_IF_VB1 \ (1 << 1) /* Load sample only if validity bit is 0 */ @@ -523,7 +523,7 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev, /* check for new data available */ ret = wait_for_completion_interruptible_timeout(&ch_stat->done, msecs_to_jiffies(100)); - /* IP might not be started or valid stream might not be prezent */ + /* IP might not be started or valid stream might not be present */ if (ret < 0) { dev_dbg(dev->dev, "channel status for channel %d timeout\n", channel); @@ -575,7 +575,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev, mchp_spdifrx_isr_blockend_en(dev); ret = wait_for_completion_interruptible_timeout(&user_data->done, msecs_to_jiffies(100)); - /* IP might not be started or valid stream might not be prezent */ + /* IP might not be started or valid stream might not be present */ if (ret <= 0) { dev_dbg(dev->dev, "user data for channel %d timeout\n", channel); diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c index 0d2e3fa21519..bcca1cf3cd7b 100644 --- a/sound/soc/atmel/mchp-spdiftx.c +++ b/sound/soc/atmel/mchp-spdiftx.c @@ -80,7 +80,7 @@ #define SPDIFTX_MR_VALID1 BIT(24) #define SPDIFTX_MR_VALID2 BIT(25) -/* Disable Null Frame on underrrun */ +/* Disable Null Frame on underrun */ #define SPDIFTX_MR_DNFR_MASK GENMASK(27, 27) #define SPDIFTX_MR_DNFR_INVALID (0 << 27) #define SPDIFTX_MR_DNFR_VALID (1 << 27) diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c index 59e2edb22b3a..50c3dc6936f9 100644 --- a/sound/soc/atmel/tse850-pcm5142.c +++ b/sound/soc/atmel/tse850-pcm5142.c @@ -23,7 +23,7 @@ // IN2 +---o--+------------+--o---+ OUT2 // loop2 relays // -// The 'loop1' gpio pin controlls two relays, which are either in loop +// The 'loop1' gpio pin controls two relays, which are either in loop // position, meaning that input and output are directly connected, or // they are in mixer position, meaning that the signal is passed through // the 'Sum' mixer. Similarly for 'loop2'. From 45956f1764ca8067c1817fea060bf1835acc2cb8 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 30 Jan 2023 14:06:41 +0200 Subject: [PATCH 0309/1017] ASoC: mchp-spdifrx: fix return value in case completion times out [ Upstream commit a4c4161d6eae3ef5f486d1638ef452d9bc1376b0 ] wait_for_completion_interruptible_timeout() returns 0 in case of timeout. Check this into account when returning from function. Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230130120647.638049-3-claudiu.beznea@microchip.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/atmel/mchp-spdifrx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index 3962ce00ad34..076a78fd0b12 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -524,9 +524,10 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev, ret = wait_for_completion_interruptible_timeout(&ch_stat->done, msecs_to_jiffies(100)); /* IP might not be started or valid stream might not be present */ - if (ret < 0) { + if (ret <= 0) { dev_dbg(dev->dev, "channel status for channel %d timeout\n", channel); + return ret ? : -ETIMEDOUT; } memcpy(uvalue->value.iec958.status, ch_stat->data, @@ -580,7 +581,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev, dev_dbg(dev->dev, "user data for channel %d timeout\n", channel); mchp_spdifrx_isr_blockend_dis(dev); - return ret; + return ret ? : -ETIMEDOUT; } spin_lock_irqsave(&user_data->lock, flags); From d8f5539b5e7f37a522c69d7561d2419a435363b6 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 30 Jan 2023 14:06:42 +0200 Subject: [PATCH 0310/1017] ASoC: mchp-spdifrx: fix controls that works with completion mechanism [ Upstream commit d3681df44e856aab523a6eb7ba15b5e41efcbb1c ] Channel status get and channel subcode get controls relies on data returned by controls when certain IRQs are raised. To achieve that completions are used b/w controls and interrupt service routine. The concurrent accesses to these controls are protected by struct snd_card::controls_rwsem. Issues identified: - reinit_completion() may be called while waiting for completion which should be avoided - in case of multiple threads waiting, the complete() call in interrupt will signal only one waiting thread per interrupt which may lead to timeout for the others - in case of channel status get as the CSC interrupt is not refcounted ISR may disable interrupt for threads that were just enabled it. To solve these the access to controls were protected by a mutex. Along with this there is no need for spinlock to protect the software cache reads/updates b/w controls and ISR as the update is happening only when requested from control, and only one reader can reach the control. Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230130120647.638049-4-claudiu.beznea@microchip.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/atmel/mchp-spdifrx.c | 143 ++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index 076a78fd0b12..eb1b8724e11f 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -217,7 +217,6 @@ struct mchp_spdifrx_ch_stat { struct mchp_spdifrx_user_data { unsigned char data[SPDIFRX_UD_BITS / 8]; struct completion done; - spinlock_t lock; /* protect access to user data */ }; struct mchp_spdifrx_mixer_control { @@ -231,8 +230,6 @@ struct mchp_spdifrx_mixer_control { struct mchp_spdifrx_dev { struct snd_dmaengine_dai_dma_data capture; struct mchp_spdifrx_mixer_control control; - spinlock_t blockend_lock; /* protect access to blockend_refcount */ - int blockend_refcount; struct mutex mlock; struct device *dev; struct regmap *regmap; @@ -277,37 +274,11 @@ static void mchp_spdifrx_channel_user_data_read(struct mchp_spdifrx_dev *dev, } } -/* called from non-atomic context only */ -static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->blockend_lock, flags); - dev->blockend_refcount++; - /* don't enable BLOCKEND interrupt if it's already enabled */ - if (dev->blockend_refcount == 1) - regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND); - spin_unlock_irqrestore(&dev->blockend_lock, flags); -} - -/* called from atomic/non-atomic context */ -static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->blockend_lock, flags); - dev->blockend_refcount--; - /* don't enable BLOCKEND interrupt if it's already enabled */ - if (dev->blockend_refcount == 0) - regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); - spin_unlock_irqrestore(&dev->blockend_lock, flags); -} - static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id) { struct mchp_spdifrx_dev *dev = dev_id; struct mchp_spdifrx_mixer_control *ctrl = &dev->control; - u32 sr, imr, pending, idr = 0; + u32 sr, imr, pending; irqreturn_t ret = IRQ_NONE; int ch; @@ -322,13 +293,10 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id) if (pending & SPDIFRX_IR_BLOCKEND) { for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) { - spin_lock(&ctrl->user_data[ch].lock); mchp_spdifrx_channel_user_data_read(dev, ch); - spin_unlock(&ctrl->user_data[ch].lock); - complete(&ctrl->user_data[ch].done); } - mchp_spdifrx_isr_blockend_dis(dev); + regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); ret = IRQ_HANDLED; } @@ -336,7 +304,7 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id) if (pending & SPDIFRX_IR_CSC(ch)) { mchp_spdifrx_channel_status_read(dev, ch); complete(&ctrl->ch_stat[ch].done); - idr |= SPDIFRX_IR_CSC(ch); + regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(ch)); ret = IRQ_HANDLED; } } @@ -346,8 +314,6 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id) ret = IRQ_HANDLED; } - regmap_write(dev->regmap, SPDIFRX_IDR, idr); - return ret; } @@ -517,23 +483,51 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev, { struct mchp_spdifrx_mixer_control *ctrl = &dev->control; struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel]; - int ret; + int ret = 0; - regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel)); - /* check for new data available */ - ret = wait_for_completion_interruptible_timeout(&ch_stat->done, - msecs_to_jiffies(100)); - /* IP might not be started or valid stream might not be present */ - if (ret <= 0) { - dev_dbg(dev->dev, "channel status for channel %d timeout\n", - channel); - return ret ? : -ETIMEDOUT; + mutex_lock(&dev->mlock); + + /* + * We may reach this point with both clocks enabled but the receiver + * still disabled. To void waiting for completion and return with + * timeout check the dev->trigger_enabled. + * + * To retrieve data: + * - if the receiver is enabled CSC IRQ will update the data in software + * caches (ch_stat->data) + * - otherwise we just update it here the software caches with latest + * available information and return it; in this case we don't need + * spin locking as the IRQ is disabled and will not be raised from + * anywhere else. + */ + + if (dev->trigger_enabled) { + reinit_completion(&ch_stat->done); + regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel)); + /* Check for new data available */ + ret = wait_for_completion_interruptible_timeout(&ch_stat->done, + msecs_to_jiffies(100)); + /* Valid stream might not be present */ + if (ret <= 0) { + dev_dbg(dev->dev, "channel status for channel %d timeout\n", + channel); + regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(channel)); + ret = ret ? : -ETIMEDOUT; + goto unlock; + } else { + ret = 0; + } + } else { + /* Update software cache with latest channel status. */ + mchp_spdifrx_channel_status_read(dev, channel); } memcpy(uvalue->value.iec958.status, ch_stat->data, sizeof(ch_stat->data)); - return 0; +unlock: + mutex_unlock(&dev->mlock); + return ret; } static int mchp_spdifrx_cs1_get(struct snd_kcontrol *kcontrol, @@ -567,29 +561,49 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev, int channel, struct snd_ctl_elem_value *uvalue) { - unsigned long flags; struct mchp_spdifrx_mixer_control *ctrl = &dev->control; struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel]; - int ret; + int ret = 0; - reinit_completion(&user_data->done); - mchp_spdifrx_isr_blockend_en(dev); - ret = wait_for_completion_interruptible_timeout(&user_data->done, - msecs_to_jiffies(100)); - /* IP might not be started or valid stream might not be present */ - if (ret <= 0) { - dev_dbg(dev->dev, "user data for channel %d timeout\n", - channel); - mchp_spdifrx_isr_blockend_dis(dev); - return ret ? : -ETIMEDOUT; + mutex_lock(&dev->mlock); + + /* + * We may reach this point with both clocks enabled but the receiver + * still disabled. To void waiting for completion to just timeout we + * check here the dev->trigger_enabled flag. + * + * To retrieve data: + * - if the receiver is enabled we need to wait for blockend IRQ to read + * data to and update it for us in software caches + * - otherwise reading the SPDIFRX_CHUD() registers is enough. + */ + + if (dev->trigger_enabled) { + reinit_completion(&user_data->done); + regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND); + ret = wait_for_completion_interruptible_timeout(&user_data->done, + msecs_to_jiffies(100)); + /* Valid stream might not be present. */ + if (ret <= 0) { + dev_dbg(dev->dev, "user data for channel %d timeout\n", + channel); + regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); + ret = ret ? : -ETIMEDOUT; + goto unlock; + } else { + ret = 0; + } + } else { + /* Update software cache with last available data. */ + mchp_spdifrx_channel_user_data_read(dev, channel); } - spin_lock_irqsave(&user_data->lock, flags); memcpy(uvalue->value.iec958.subcode, user_data->data, sizeof(user_data->data)); - spin_unlock_irqrestore(&user_data->lock, flags); - return 0; +unlock: + mutex_unlock(&dev->mlock); + return ret; } static int mchp_spdifrx_subcode_ch1_get(struct snd_kcontrol *kcontrol, @@ -890,11 +904,9 @@ static int mchp_spdifrx_dai_probe(struct snd_soc_dai *dai) SPDIFRX_MR_AUTORST_NOACTION | SPDIFRX_MR_PACK_DISABLED); - dev->blockend_refcount = 0; for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) { init_completion(&ctrl->ch_stat[ch].done); init_completion(&ctrl->user_data[ch].done); - spin_lock_init(&ctrl->user_data[ch].lock); } /* Add controls */ @@ -1004,7 +1016,6 @@ static int mchp_spdifrx_probe(struct platform_device *pdev) */ clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1); - spin_lock_init(&dev->blockend_lock); mutex_init(&dev->mlock); dev->dev = &pdev->dev; From ce07bbe038aead7d9fc996e52a5d92d0243abaac Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 30 Jan 2023 14:06:43 +0200 Subject: [PATCH 0311/1017] ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove() [ Upstream commit aaecdc32b7e35b4f9b457fb3509414aa9a932589 ] CSC interrupts which might be used in controls are on bits 8 and 9 of SPDIFRX_IDR register. Thus disable all the interrupts that are exported by driver. Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230130120647.638049-5-claudiu.beznea@microchip.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/atmel/mchp-spdifrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index eb1b8724e11f..03b7037239b8 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -921,7 +921,7 @@ static int mchp_spdifrx_dai_remove(struct snd_soc_dai *dai) struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); /* Disable interrupts */ - regmap_write(dev->regmap, SPDIFRX_IDR, 0xFF); + regmap_write(dev->regmap, SPDIFRX_IDR, GENMASK(14, 0)); clk_disable_unprepare(dev->pclk); From b4d74716da0079ce6c8241e8ad74c7b14450efe8 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 2 Feb 2023 09:34:19 -0700 Subject: [PATCH 0312/1017] ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params() [ Upstream commit 218674a45930c700486d27b765bf2f1b43f8cbf7 ] Clang warns: ../sound/soc/atmel/mchp-spdifrx.c:455:3: error: variable 'mr' is uninitialized when used here [-Werror,-Wuninitialized] mr |= SPDIFRX_MR_ENDIAN_BIG; ^~ ../sound/soc/atmel/mchp-spdifrx.c:432:8: note: initialize the variable 'mr' to silence this warning u32 mr; ^ = 0 1 error generated. Zero initialize mr so that these bitwise OR and assignment operation works unconditionally. Fixes: fa09fa60385a ("ASoC: mchp-spdifrx: fix controls which rely on rsr register") Link: https://github.com/ClangBuiltLinux/linux/issues/1797 Signed-off-by: Nathan Chancellor Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230202-mchp-spdifrx-fix-uninit-mr-v1-1-629a045d7a2f@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/atmel/mchp-spdifrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index 03b7037239b8..39a3c2a33bdb 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -362,7 +362,7 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); - u32 mr; + u32 mr = 0; int ret; dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", From d9bcf67b8bb39e951e8e16c46e3a7274f3d3774f Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Thu, 2 Feb 2023 19:36:46 +0100 Subject: [PATCH 0313/1017] ASoC: dt-bindings: meson: fix gx-card codec node regex [ Upstream commit 480b26226873c88e482575ceb0d0a38d76e1be57 ] 'codec' is a valid node name when there is a single codec in the link. Fix the node regular expression to apply this. Fixes: fd00366b8e41 ("ASoC: meson: gx: add sound card dt-binding documentation") Signed-off-by: Jerome Brunet Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230202183653.486216-3-jbrunet@baylibre.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- .../devicetree/bindings/sound/amlogic,gx-sound-card.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml index 2e35aeaa8781..89e3819c6127 100644 --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml @@ -61,7 +61,7 @@ patternProperties: description: phandle of the CPU DAI patternProperties: - "^codec-[0-9]+$": + "^codec(-[0-9]+)?$": type: object description: |- Codecs: From 859bdc96ba89b253fc8e8997ef717b5c1e67c909 Mon Sep 17 00:00:00 2001 From: Jonathan Cormier Date: Thu, 26 Jan 2023 17:32:25 -0500 Subject: [PATCH 0314/1017] hwmon: (ltc2945) Handle error case in ltc2945_value_store [ Upstream commit 178b01eccfb0b8149682f61388400bd3d903dddc ] ltc2945_val_to_reg errors were not being handled which would have resulted in register being set to 0 (clamped) instead of being left alone. Fixes: 6700ce035f83 ("hwmon: Driver for Linear Technologies LTC2945") Signed-off-by: Jonathan Cormier Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/ltc2945.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hwmon/ltc2945.c b/drivers/hwmon/ltc2945.c index ba9c868a8641..65d792f18425 100644 --- a/drivers/hwmon/ltc2945.c +++ b/drivers/hwmon/ltc2945.c @@ -248,6 +248,8 @@ static ssize_t ltc2945_value_store(struct device *dev, /* convert to register value, then clamp and write result */ regval = ltc2945_val_to_reg(dev, reg, val); + if (regval < 0) + return regval; if (is_power_reg(reg)) { regval = clamp_val(regval, 0, 0xffffff); regbuf[0] = regval >> 16; From 0cb8a92a880d4cae226f52a72fcde495ef655e9a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 6 Feb 2023 20:36:02 +0100 Subject: [PATCH 0315/1017] drm/amdgpu: fix enum odm_combine_mode mismatch [ Upstream commit 087bad7eb1f6945f8232f132953ecc2bda8bd38d ] A conversion from 'bool' to 'enum odm_combine_mode' was incomplete, and gcc warns about this with many instances of display/dc/dml/dcn20/display_mode_vba_20.c:3899:44: warning: implicit conversion from 'enum ' to 'enum odm_combine_mode' [-Wenum-conversion] 3899 | locals->ODMCombineEnablePerState[i][k] = false; Change the ones that we get a warning for, using the same numerical values to leave the behavior unchanged. Fixes: 5fc11598166d ("drm/amd/display: expand dml structs") Link: https://lore.kernel.org/all/20201026210039.3884312-3-arnd@kernel.org/ Link: https://lore.kernel.org/all/20210927100659.1431744-1-arnd@kernel.org/ Signed-off-by: Arnd Bergmann Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../amd/display/dc/dml/dcn20/display_mode_vba_20.c | 8 ++++---- .../amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 10 +++++----- .../amd/display/dc/dml/dcn21/display_mode_vba_21.c | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index b3f0476899d3..14e7a59a9cd1 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -3897,14 +3897,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; if (mode_lib->vba.ODMCapability) { if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } } @@ -3957,7 +3957,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l locals->RequiredDISPCLK[i][j] = 0.0; locals->DISPCLK_DPPCLK_Support[i][j] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) { locals->NoOfDPP[i][j][k] = 1; locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k] diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index 1bcda7eba4a6..ee1c80366bd6 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -3974,17 +3974,17 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; if (mode_lib->vba.ODMCapability) { if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN20_MAX_DSC_IMAGE_WIDTH)) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } } @@ -4037,7 +4037,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode locals->RequiredDISPCLK[i][j] = 0.0; locals->DISPCLK_DPPCLK_Support[i][j] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) { locals->NoOfDPP[i][j][k] = 1; locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k] diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index c09bca335068..25693e62db80 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -3975,17 +3975,17 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine; if (mode_lib->vba.ODMCapability) { if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN21_MAX_DSC_IMAGE_WIDTH)) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } else if (locals->HActive[k] > DCN21_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) { - locals->ODMCombineEnablePerState[i][k] = true; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine; } } @@ -4038,7 +4038,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l locals->RequiredDISPCLK[i][j] = 0.0; locals->DISPCLK_DPPCLK_Support[i][j] = true; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { - locals->ODMCombineEnablePerState[i][k] = false; + locals->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) { locals->NoOfDPP[i][j][k] = 1; locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k] @@ -5213,7 +5213,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.ODMCombineEnabled[k] = locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k]; } else { - mode_lib->vba.ODMCombineEnabled[k] = false; + mode_lib->vba.ODMCombineEnabled[k] = dm_odm_combine_mode_disabled; } mode_lib->vba.DSCEnabled[k] = locals->RequiresDSC[mode_lib->vba.VoltageLevel][k]; From 30c7c72b6cf9d8c95f9b219c9d2e4e31b15bebe5 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Tue, 7 Feb 2023 16:21:59 +0100 Subject: [PATCH 0316/1017] scsi: mpt3sas: Fix a memory leak [ Upstream commit 54dd96015e8d7a2a07359e2dfebf05b529d1780c ] Add a forgotten kfree(). Fixes: dbec4c9040ed ("scsi: mpt3sas: lockless command submission") Link: https://lore.kernel.org/r/20230207152159.18627-1-thenzl@redhat.com Signed-off-by: Tomas Henzl Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/mpt3sas/mpt3sas_base.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index c1b76cda60db..2ad75c9a9088 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -4905,6 +4905,9 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) } dma_pool_destroy(ioc->pcie_sgl_dma_pool); } + kfree(ioc->pcie_sg_lookup); + ioc->pcie_sg_lookup = NULL; + if (ioc->config_page) { dexitprintk(ioc, ioc_info(ioc, "config_page(0x%p): free\n", From ca769960cb570b539acdd00e6b9cf0f9b5c5c66d Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Sat, 28 Jan 2023 19:08:32 +0800 Subject: [PATCH 0317/1017] scsi: aic94xx: Add missing check for dma_map_single() [ Upstream commit 32fe45274edb5926abc0fac7263d9f889d02d9cf ] Add check for dma_map_single() and return error if it fails in order to avoid invalid DMA address. Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") Link: https://lore.kernel.org/r/20230128110832.6792-1-jiasheng@iscas.ac.cn Signed-off-by: Jiasheng Jiang Reviewed-by: Jason Yan Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/aic94xx/aic94xx_task.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index f923ed019d4a..593b167ceefe 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -50,6 +50,9 @@ static int asd_map_scatterlist(struct sas_task *task, dma_addr_t dma = dma_map_single(&asd_ha->pcidev->dev, p, task->total_xfer_len, task->data_dir); + if (dma_mapping_error(&asd_ha->pcidev->dev, dma)) + return -ENOMEM; + sg_arr[0].bus_addr = cpu_to_le64((u64)dma); sg_arr[0].size = cpu_to_le32(task->total_xfer_len); sg_arr[0].flags |= ASD_SG_EL_LIST_EOL; From 59b0ce292a0990316abbf21490c6b88b814bb6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Tue, 23 Feb 2021 16:18:51 +0100 Subject: [PATCH 0318/1017] spi: bcm63xx-hsspi: fix pm_runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 216e8e80057a9f0b6366327881acf88eaf9f1fd4 ] The driver sets auto_runtime_pm to true, but it doesn't call pm_runtime_enable(), which results in "Failed to power device" when PM support is enabled. Signed-off-by: Álvaro Fernández Rojas Link: https://lore.kernel.org/r/20210223151851.4110-3-noltari@gmail.com Signed-off-by: Mark Brown Stable-dep-of: 811ff802aaf8 ("spi: bcm63xx-hsspi: Fix multi-bit mode setting") Signed-off-by: Sasha Levin --- drivers/spi/spi-bcm63xx-hsspi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 1f08d7553f07..b871fd810d80 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -21,6 +21,7 @@ #include #include #include +#include #define HSSPI_GLOBAL_CTRL_REG 0x0 #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0 @@ -439,13 +440,17 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) if (ret) goto out_put_master; + pm_runtime_enable(&pdev->dev); + /* register and we are done */ ret = devm_spi_register_master(dev, master); if (ret) - goto out_put_master; + goto out_pm_disable; return 0; +out_pm_disable: + pm_runtime_disable(&pdev->dev); out_put_master: spi_master_put(master); out_disable_pll_clk: From a79f1e71e7b57329b157569037d3f8e98be9bd6e Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 9 Feb 2023 12:02:41 -0800 Subject: [PATCH 0319/1017] spi: bcm63xx-hsspi: Fix multi-bit mode setting [ Upstream commit 811ff802aaf878ebbbaeac0307a0164fa21e7d40 ] Currently the driver always sets the controller to dual data bit mode for both tx and rx data in the profile mode control register even for single data bit transfer. Luckily the opcode is set correctly according to SPI transfer data bit width so it does not actually cause issues. This change fixes the problem by setting tx and rx data bit mode field correctly according to the actual SPI transfer tx and rx data bit width. Fixes: 142168eba9dc ("spi: bcm63xx-hsspi: add bcm63xx HSSPI driver") Signed-off-by: William Zhang Link: https://lore.kernel.org/r/20230209200246.141520-11-william.zhang@broadcom.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-bcm63xx-hsspi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index b871fd810d80..02f56fc001b4 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -163,6 +163,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; + u32 val = 0; bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); @@ -178,11 +179,16 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) step_size -= HSSPI_OPCODE_LEN; if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) || - (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) + (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) { opcode |= HSSPI_OP_MULTIBIT; - __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT | - 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff, + if (t->rx_nbits == SPI_NBITS_DUAL) + val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; + if (t->tx_nbits == SPI_NBITS_DUAL) + val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; + } + + __raw_writel(val | 0xff, bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); while (pending > 0) { From 4c6d18ea71d86efbdf8861628699af050fb71868 Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Sun, 12 Feb 2023 16:57:30 +0200 Subject: [PATCH 0320/1017] hwmon: (mlxreg-fan) Return zero speed for broken fan [ Upstream commit a1ffd3c46267ee5c807acd780e15df9bb692223f ] Currently for broken fan driver returns value calculated based on error code (0xFF) in related fan speed register. Thus, for such fan user gets fan{n}_fault to 1 and fan{n}_input with misleading value. Add check for fan fault prior return speed value and return zero if fault is detected. Fixes: 65afb4c8e7e4 ("hwmon: (mlxreg-fan) Add support for Mellanox FAN driver") Signed-off-by: Vadim Pasternak Link: https://lore.kernel.org/r/20230212145730.24247-1-vadimp@nvidia.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/mlxreg-fan.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c index bd8f5a3aaad9..052c897a635d 100644 --- a/drivers/hwmon/mlxreg-fan.c +++ b/drivers/hwmon/mlxreg-fan.c @@ -127,6 +127,12 @@ mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, if (err) return err; + if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) { + /* FAN is broken - return zero for FAN speed. */ + *val = 0; + return 0; + } + *val = MLXREG_FAN_GET_RPM(regval, fan->divider, fan->samples); break; From f23a4b9bf8950fd914c61c99e2189f3582909998 Mon Sep 17 00:00:00 2001 From: Steffen Aschbacher Date: Mon, 13 Feb 2023 09:38:05 +0200 Subject: [PATCH 0321/1017] ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init [ Upstream commit 771725efe5e2e5396dd9d1220437e5f9d6b9ca9d ] When the 'ti,gpio-config' property is not defined, the device_property_count_u32() will return an error, rather than zero. The current check, only handles a return value of zero, which assumes that the property is defined and has nothing defined. This change extends the check to also check for an error case (most likely to be hit by the case that the 'ti,gpio-config' is not defined). In case that the 'ti,gpio-config' and the returned 'gpio_count' is not correct, there is a 'if (gpio_count != ADCX140_NUM_GPIO_CFGS)' check, a few lines lower that will return -EINVAL. This means that someone tried to define 'ti,gpio-config', but with the wrong number of GPIOs. Fixes: d5214321498a ("ASoC: tlv320adcx140: Add support for configuring GPIO pin") Signed-off-by: Steffen Aschbacher Signed-off-by: Alexandru Ardelean Link: https://lore.kernel.org/r/20230213073805.14640-1-alex@shruggie.ro Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/tlv320adcx140.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 53a80246aee1..a6241a045369 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -870,7 +870,7 @@ static int adcx140_configure_gpio(struct adcx140_priv *adcx140) gpio_count = device_property_count_u32(adcx140->dev, "ti,gpio-config"); - if (gpio_count == 0) + if (gpio_count <= 0) return 0; if (gpio_count != ADCX140_NUM_GPIO_CFGS) From c550f65a54a0de1d8199e4dc146820d484856118 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 14 Feb 2023 13:06:05 -0500 Subject: [PATCH 0322/1017] dm: remove flush_scheduled_work() during local_exit() [ Upstream commit 0b22ff5360f5c4e11050b89206370fdf7dc0a226 ] Commit acfe0ad74d2e1 ("dm: allocate a special workqueue for deferred device removal") switched from using system workqueue to a single workqueue local to DM. But it didn't eliminate the call to flush_scheduled_work() that was introduced purely for the benefit of deferred device removal with commit 2c140a246dc ("dm: allow remove to be deferred"). Since DM core uses its own workqueue (and queue_work) there is no need to call flush_scheduled_work() from local_exit(). local_exit()'s destroy_workqueue(deferred_remove_workqueue) handles flushing work started with queue_work(). Fixes: acfe0ad74d2e1 ("dm: allocate a special workqueue for deferred device removal") Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/dm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 1005abf76860..7163ecc4d53f 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -265,7 +265,6 @@ out_uevent_exit: static void local_exit(void) { - flush_scheduled_work(); destroy_workqueue(deferred_remove_workqueue); unregister_blkdev(_major, _name); From d601f782824e3541887cc4628c3aa61526bda431 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 25 Mar 2021 14:51:36 -0400 Subject: [PATCH 0323/1017] NFS: Fix up handling of outstanding layoutcommit in nfs_update_inode() [ Upstream commit 709fa5769914b377af87962bbe4ff81ffb019b2d ] If there is an outstanding layoutcommit, then the list of attributes whose values are expected to change is not the full set. So let's be explicit about the full list. Signed-off-by: Trond Myklebust Stable-dep-of: b46d80bd2d6e ("nfs4trace: fix state manager flag printing") Signed-off-by: Sasha Levin --- fs/nfs/inode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 1adece1cff3e..36f415278c04 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1906,7 +1906,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfs_wcc_update_inode(inode, fattr); if (pnfs_layoutcommit_outstanding(inode)) { - nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR; + nfsi->cache_validity |= + save_cache_validity & + (NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | + NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE | + NFS_INO_REVAL_FORCED); cache_revalidated = false; } From 6d434b4c49f05924d722e773ee02240b64ffe19d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 7 Mar 2022 10:41:44 +1100 Subject: [PATCH 0324/1017] NFSv4: keep state manager thread active if swap is enabled [ Upstream commit 4dc73c679114a2f408567e2e44770ed934190db2 ] If we are swapping over NFSv4, we may not be able to allocate memory to start the state-manager thread at the time when we need it. So keep it always running when swap is enabled, and just signal it to start. This requires updating and testing the cl_swapper count on the root rpc_clnt after following all ->cl_parent links. Signed-off-by: NeilBrown Signed-off-by: Trond Myklebust Stable-dep-of: b46d80bd2d6e ("nfs4trace: fix state manager flag printing") Signed-off-by: Sasha Levin --- fs/nfs/file.c | 15 ++++++++++++--- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 20 ++++++++++++++++++++ fs/nfs/nfs4state.c | 40 +++++++++++++++++++++++++++++++++------- include/linux/nfs_xdr.h | 2 ++ net/sunrpc/clnt.c | 2 ++ 6 files changed, 70 insertions(+), 10 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index ad856b7b9a46..7be1a7f7fcb2 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -487,8 +487,9 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, { unsigned long blocks; long long isize; - struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host); - struct inode *inode = file->f_mapping->host; + struct inode *inode = file_inode(file); + struct rpc_clnt *clnt = NFS_CLIENT(inode); + struct nfs_client *cl = NFS_SERVER(inode)->nfs_client; spin_lock(&inode->i_lock); blocks = inode->i_blocks; @@ -501,14 +502,22 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, *span = sis->pages; + + if (cl->rpc_ops->enable_swap) + cl->rpc_ops->enable_swap(inode); + return rpc_clnt_swap_activate(clnt); } static void nfs_swap_deactivate(struct file *file) { - struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host); + struct inode *inode = file_inode(file); + struct rpc_clnt *clnt = NFS_CLIENT(inode); + struct nfs_client *cl = NFS_SERVER(inode)->nfs_client; rpc_clnt_swap_deactivate(clnt); + if (cl->rpc_ops->disable_swap) + cl->rpc_ops->disable_swap(file_inode(file)); } const struct address_space_operations nfs_file_aops = { diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6d916563356e..8b41c0b8624e 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -42,6 +42,7 @@ enum nfs4_client_state { NFS4CLNT_LEASE_MOVED, NFS4CLNT_DELEGATION_EXPIRED, NFS4CLNT_RUN_MANAGER, + NFS4CLNT_MANAGER_AVAILABLE, NFS4CLNT_RECALL_RUNNING, NFS4CLNT_RECALL_ANY_LAYOUT_READ, NFS4CLNT_RECALL_ANY_LAYOUT_RW, diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ee46ab09e330..8f502e2ac34f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -10385,6 +10385,24 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) return error + error2 + error3; } +static void nfs4_enable_swap(struct inode *inode) +{ + /* The state manager thread must always be running. + * It will notice the client is a swapper, and stay put. + */ + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; + + nfs4_schedule_state_manager(clp); +} + +static void nfs4_disable_swap(struct inode *inode) +{ + /* The state manager thread will now exit once it is + * woken. + */ + wake_up_var(&NFS_SERVER(inode)->nfs_client->cl_state); +} + static const struct inode_operations nfs4_dir_inode_operations = { .create = nfs_create, .lookup = nfs_lookup, @@ -10461,6 +10479,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .free_client = nfs4_free_client, .create_server = nfs4_create_server, .clone_server = nfs_clone_server, + .enable_swap = nfs4_enable_swap, + .disable_swap = nfs4_disable_swap, }; static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 175b2e064003..628e030f8e3b 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1208,10 +1208,17 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) { struct task_struct *task; char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; + struct rpc_clnt *cl = clp->cl_rpcclient; + + while (cl != cl->cl_parent) + cl = cl->cl_parent; set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); - if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) + if (test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) != 0) { + wake_up_var(&clp->cl_state); return; + } + set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); __module_get(THIS_MODULE); refcount_inc(&clp->cl_count); @@ -1229,6 +1236,7 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) if (!nfs_client_init_is_complete(clp)) nfs_mark_client_ready(clp, PTR_ERR(task)); nfs4_clear_state_manager_bit(clp); + clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); nfs_put_client(clp); module_put(THIS_MODULE); } @@ -2680,12 +2688,8 @@ static void nfs4_state_manager(struct nfs_client *clp) clear_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state); } - /* Did we race with an attempt to give us more work? */ - if (!test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)) - return; - if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) - return; - memflags = memalloc_nofs_save(); + return; + } while (refcount_read(&clp->cl_count) > 1 && !signalled()); goto out_drain; @@ -2706,9 +2710,31 @@ out_drain: static int nfs4_run_state_manager(void *ptr) { struct nfs_client *clp = ptr; + struct rpc_clnt *cl = clp->cl_rpcclient; + + while (cl != cl->cl_parent) + cl = cl->cl_parent; allow_signal(SIGKILL); +again: + set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); nfs4_state_manager(clp); + if (atomic_read(&cl->cl_swapper)) { + wait_var_event_interruptible(&clp->cl_state, + test_bit(NFS4CLNT_RUN_MANAGER, + &clp->cl_state)); + if (atomic_read(&cl->cl_swapper) && + test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)) + goto again; + /* Either no longer a swapper, or were signalled */ + } + clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); + + if (refcount_read(&clp->cl_count) > 1 && !signalled() && + test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && + !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state)) + goto again; + nfs_put_client(clp); module_put_and_exit(0); return 0; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 5491ad5f48a9..33442fd018a0 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1789,6 +1789,8 @@ struct nfs_rpc_ops { struct nfs_server *(*create_server)(struct fs_context *); struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, rpc_authflavor_t); + void (*enable_swap)(struct inode *inode); + void (*disable_swap)(struct inode *inode); }; /* diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index c478108ca6a6..e190d38c4c82 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -3026,6 +3026,8 @@ rpc_clnt_swap_activate_callback(struct rpc_clnt *clnt, int rpc_clnt_swap_activate(struct rpc_clnt *clnt) { + while (clnt != clnt->cl_parent) + clnt = clnt->cl_parent; if (atomic_inc_return(&clnt->cl_swapper) == 1) return rpc_clnt_iterate_for_each_xprt(clnt, rpc_clnt_swap_activate_callback, NULL); From 242df51a829185cef75c7bdb4495ebb1b19f7dfa Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Tue, 14 Feb 2023 08:18:23 -0500 Subject: [PATCH 0325/1017] nfs4trace: fix state manager flag printing [ Upstream commit b46d80bd2d6e7e063c625a20de54248afe8d4889 ] __print_flags wants a mask, not the enum value. Add two more flags. Fixes: 511ba52e4c01 ("NFS4: Trace state recovery operation") Signed-off-by: Benjamin Coddington Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/nfs4trace.h | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index 484c1da96dea..d862df9761e7 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -584,32 +584,34 @@ TRACE_DEFINE_ENUM(NFS4CLNT_MOVED); TRACE_DEFINE_ENUM(NFS4CLNT_LEASE_MOVED); TRACE_DEFINE_ENUM(NFS4CLNT_DELEGATION_EXPIRED); TRACE_DEFINE_ENUM(NFS4CLNT_RUN_MANAGER); +TRACE_DEFINE_ENUM(NFS4CLNT_MANAGER_AVAILABLE); TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_RUNNING); TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_ANY_LAYOUT_READ); TRACE_DEFINE_ENUM(NFS4CLNT_RECALL_ANY_LAYOUT_RW); +TRACE_DEFINE_ENUM(NFS4CLNT_DELEGRETURN_DELAYED); #define show_nfs4_clp_state(state) \ __print_flags(state, "|", \ - { NFS4CLNT_MANAGER_RUNNING, "MANAGER_RUNNING" }, \ - { NFS4CLNT_CHECK_LEASE, "CHECK_LEASE" }, \ - { NFS4CLNT_LEASE_EXPIRED, "LEASE_EXPIRED" }, \ - { NFS4CLNT_RECLAIM_REBOOT, "RECLAIM_REBOOT" }, \ - { NFS4CLNT_RECLAIM_NOGRACE, "RECLAIM_NOGRACE" }, \ - { NFS4CLNT_DELEGRETURN, "DELEGRETURN" }, \ - { NFS4CLNT_SESSION_RESET, "SESSION_RESET" }, \ - { NFS4CLNT_LEASE_CONFIRM, "LEASE_CONFIRM" }, \ - { NFS4CLNT_SERVER_SCOPE_MISMATCH, \ - "SERVER_SCOPE_MISMATCH" }, \ - { NFS4CLNT_PURGE_STATE, "PURGE_STATE" }, \ - { NFS4CLNT_BIND_CONN_TO_SESSION, \ - "BIND_CONN_TO_SESSION" }, \ - { NFS4CLNT_MOVED, "MOVED" }, \ - { NFS4CLNT_LEASE_MOVED, "LEASE_MOVED" }, \ - { NFS4CLNT_DELEGATION_EXPIRED, "DELEGATION_EXPIRED" }, \ - { NFS4CLNT_RUN_MANAGER, "RUN_MANAGER" }, \ - { NFS4CLNT_RECALL_RUNNING, "RECALL_RUNNING" }, \ - { NFS4CLNT_RECALL_ANY_LAYOUT_READ, "RECALL_ANY_LAYOUT_READ" }, \ - { NFS4CLNT_RECALL_ANY_LAYOUT_RW, "RECALL_ANY_LAYOUT_RW" }) + { BIT(NFS4CLNT_MANAGER_RUNNING), "MANAGER_RUNNING" }, \ + { BIT(NFS4CLNT_CHECK_LEASE), "CHECK_LEASE" }, \ + { BIT(NFS4CLNT_LEASE_EXPIRED), "LEASE_EXPIRED" }, \ + { BIT(NFS4CLNT_RECLAIM_REBOOT), "RECLAIM_REBOOT" }, \ + { BIT(NFS4CLNT_RECLAIM_NOGRACE), "RECLAIM_NOGRACE" }, \ + { BIT(NFS4CLNT_DELEGRETURN), "DELEGRETURN" }, \ + { BIT(NFS4CLNT_SESSION_RESET), "SESSION_RESET" }, \ + { BIT(NFS4CLNT_LEASE_CONFIRM), "LEASE_CONFIRM" }, \ + { BIT(NFS4CLNT_SERVER_SCOPE_MISMATCH), "SERVER_SCOPE_MISMATCH" }, \ + { BIT(NFS4CLNT_PURGE_STATE), "PURGE_STATE" }, \ + { BIT(NFS4CLNT_BIND_CONN_TO_SESSION), "BIND_CONN_TO_SESSION" }, \ + { BIT(NFS4CLNT_MOVED), "MOVED" }, \ + { BIT(NFS4CLNT_LEASE_MOVED), "LEASE_MOVED" }, \ + { BIT(NFS4CLNT_DELEGATION_EXPIRED), "DELEGATION_EXPIRED" }, \ + { BIT(NFS4CLNT_RUN_MANAGER), "RUN_MANAGER" }, \ + { BIT(NFS4CLNT_MANAGER_AVAILABLE), "MANAGER_AVAILABLE" }, \ + { BIT(NFS4CLNT_RECALL_RUNNING), "RECALL_RUNNING" }, \ + { BIT(NFS4CLNT_RECALL_ANY_LAYOUT_READ), "RECALL_ANY_LAYOUT_READ" }, \ + { BIT(NFS4CLNT_RECALL_ANY_LAYOUT_RW), "RECALL_ANY_LAYOUT_RW" }, \ + { BIT(NFS4CLNT_DELEGRETURN_DELAYED), "DELERETURN_DELAYED" }) TRACE_EVENT(nfs4_state_mgr, TP_PROTO( From ac3a513d4fa888a3d3778419a19fe75cc856eade Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 8 Feb 2023 15:45:38 +1100 Subject: [PATCH 0326/1017] NFS: fix disabling of swap [ Upstream commit 5bab56fff53ce161ed859d9559a10361d4f79578 ] When swap is activated to a file on an NFSv4 mount we arrange that the state manager thread is always present as starting a new thread requires memory allocations that might block waiting for swap. Unfortunately the code for allowing the state manager thread to exit when swap is disabled was not tested properly and does not work. This can be seen by examining /proc/fs/nfsfs/servers after disabling swap and unmounting the filesystem. The servers file will still list one entry. Also a "ps" listing will show the state manager thread is still present. There are two problems. 1/ rpc_clnt_swap_deactivate() doesn't walk up the ->cl_parent list to find the primary client on which the state manager runs. 2/ The thread is not woken up properly and it immediately goes back to sleep without checking whether it is really needed. Using nfs4_schedule_state_manager() ensures a proper wake-up. Reported-by: Olga Kornievskaia Fixes: 4dc73c679114 ("NFSv4: keep state manager thread active if swap is enabled") Signed-off-by: NeilBrown Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/nfs4proc.c | 4 +++- net/sunrpc/clnt.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8f502e2ac34f..8653335c17b6 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -10400,7 +10400,9 @@ static void nfs4_disable_swap(struct inode *inode) /* The state manager thread will now exit once it is * woken. */ - wake_up_var(&NFS_SERVER(inode)->nfs_client->cl_state); + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; + + nfs4_schedule_state_manager(clp); } static const struct inode_operations nfs4_dir_inode_operations = { diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index e190d38c4c82..c6e8bd78e35d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -3047,6 +3047,8 @@ rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt, void rpc_clnt_swap_deactivate(struct rpc_clnt *clnt) { + while (clnt != clnt->cl_parent) + clnt = clnt->cl_parent; if (atomic_dec_if_positive(&clnt->cl_swapper) == 0) rpc_clnt_iterate_for_each_xprt(clnt, rpc_clnt_swap_deactivate_callback, NULL); From c785a87d9a7745b06ef48e0d4bc905a102b3272d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 15 Feb 2023 14:01:28 +0100 Subject: [PATCH 0327/1017] spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one() [ Upstream commit e6a0b671880207566e1ece983bf989dde60bc1d7 ] wait_for_completion_timeout() never returns a <0 value. It returns either on timeout or a positive value (at least 1, or number of jiffies left till timeout) So, fix the error handling path and return -ETIMEDOUT should a timeout occur. Fixes: b0823ee35cf9 ("spi: Add spi driver for Socionext SynQuacer platform") Signed-off-by: Christophe JAILLET Acked-by: Jassi Brar Link: https://lore.kernel.org/r/c2040bf3cfa201fd8890cfab14fa5a701ffeca14.1676466072.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-synquacer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c index 47cbe73137c2..dc188f9202c9 100644 --- a/drivers/spi/spi-synquacer.c +++ b/drivers/spi/spi-synquacer.c @@ -472,10 +472,9 @@ static int synquacer_spi_transfer_one(struct spi_master *master, read_fifo(sspi); } - if (status < 0) { - dev_err(sspi->dev, "failed to transfer. status: 0x%x\n", - status); - return status; + if (status == 0) { + dev_err(sspi->dev, "failed to transfer. Timeout.\n"); + return -ETIMEDOUT; } return 0; From f69065e1bd901781d04f91b1cc95a980642f97b2 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Wed, 15 Feb 2023 13:28:51 +0000 Subject: [PATCH 0328/1017] ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared [ Upstream commit fdff966bfde7cf0c85562d2bfb1ff1ba83da5f7b ] Add struct snd_pcm_substream forward declaration Fixes: 078a85f2806f ("ASoC: dapm: Only power up active channels from a DAI") Signed-off-by: Lucas Tanure Reviewed-by: Charles Keepax Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230215132851.1626881-1-lucas.tanure@collabora.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- include/sound/soc-dapm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index c3039e97929a..32e93d55acf7 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -16,6 +16,7 @@ #include struct device; +struct snd_pcm_substream; struct snd_soc_pcm_runtime; struct soc_enum; From 2ca8ae5cf61e5598dcbc5f66c114649660e997ec Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sun, 12 Feb 2023 18:59:59 +0000 Subject: [PATCH 0329/1017] HID: bigben: use spinlock to protect concurrent accesses [ Upstream commit 9fefb6201c4f8dd9f58c581b2a66e5cde2895ea2 ] bigben driver has a worker that may access data concurrently. Proct the accesses using a spinlock. Fixes: 256a90ed9e46 ("HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad") Signed-off-by: Pietro Borrello Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-1-7860c5763c38@diag.uniroma1.it Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-bigbenff.c | 52 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c index e8b16665860d..ed3d2d7bc1dd 100644 --- a/drivers/hid/hid-bigbenff.c +++ b/drivers/hid/hid-bigbenff.c @@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = { struct bigben_device { struct hid_device *hid; struct hid_report *report; + spinlock_t lock; bool removed; u8 led_state; /* LED1 = 1 .. LED4 = 8 */ u8 right_motor_on; /* right motor off/on 0/1 */ @@ -190,12 +191,27 @@ static void bigben_worker(struct work_struct *work) struct bigben_device *bigben = container_of(work, struct bigben_device, worker); struct hid_field *report_field = bigben->report->field[0]; + bool do_work_led = false; + bool do_work_ff = false; + u8 *buf; + u32 len; + unsigned long flags; if (bigben->removed || !report_field) return; + buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL); + if (!buf) + return; + + len = hid_report_len(bigben->report); + + /* LED work */ + spin_lock_irqsave(&bigben->lock, flags); + if (bigben->work_led) { bigben->work_led = false; + do_work_led = true; report_field->value[0] = 0x01; /* 1 = led message */ report_field->value[1] = 0x08; /* reserved value, always 8 */ report_field->value[2] = bigben->led_state; @@ -204,11 +220,22 @@ static void bigben_worker(struct work_struct *work) report_field->value[5] = 0x00; /* padding */ report_field->value[6] = 0x00; /* padding */ report_field->value[7] = 0x00; /* padding */ - hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT); + hid_output_report(bigben->report, buf); } + spin_unlock_irqrestore(&bigben->lock, flags); + + if (do_work_led) { + hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len, + bigben->report->type, HID_REQ_SET_REPORT); + } + + /* FF work */ + spin_lock_irqsave(&bigben->lock, flags); + if (bigben->work_ff) { bigben->work_ff = false; + do_work_ff = true; report_field->value[0] = 0x02; /* 2 = rumble effect message */ report_field->value[1] = 0x08; /* reserved value, always 8 */ report_field->value[2] = bigben->right_motor_on; @@ -217,8 +244,17 @@ static void bigben_worker(struct work_struct *work) report_field->value[5] = 0x00; /* padding */ report_field->value[6] = 0x00; /* padding */ report_field->value[7] = 0x00; /* padding */ - hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT); + hid_output_report(bigben->report, buf); } + + spin_unlock_irqrestore(&bigben->lock, flags); + + if (do_work_ff) { + hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len, + bigben->report->type, HID_REQ_SET_REPORT); + } + + kfree(buf); } static int hid_bigben_play_effect(struct input_dev *dev, void *data, @@ -228,6 +264,7 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data, struct bigben_device *bigben = hid_get_drvdata(hid); u8 right_motor_on; u8 left_motor_force; + unsigned long flags; if (!bigben) { hid_err(hid, "no device data\n"); @@ -242,9 +279,12 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data, if (right_motor_on != bigben->right_motor_on || left_motor_force != bigben->left_motor_force) { + spin_lock_irqsave(&bigben->lock, flags); bigben->right_motor_on = right_motor_on; bigben->left_motor_force = left_motor_force; bigben->work_ff = true; + spin_unlock_irqrestore(&bigben->lock, flags); + schedule_work(&bigben->worker); } @@ -259,6 +299,7 @@ static void bigben_set_led(struct led_classdev *led, struct bigben_device *bigben = hid_get_drvdata(hid); int n; bool work; + unsigned long flags; if (!bigben) { hid_err(hid, "no device data\n"); @@ -267,6 +308,7 @@ static void bigben_set_led(struct led_classdev *led, for (n = 0; n < NUM_LEDS; n++) { if (led == bigben->leds[n]) { + spin_lock_irqsave(&bigben->lock, flags); if (value == LED_OFF) { work = (bigben->led_state & BIT(n)); bigben->led_state &= ~BIT(n); @@ -274,6 +316,7 @@ static void bigben_set_led(struct led_classdev *led, work = !(bigben->led_state & BIT(n)); bigben->led_state |= BIT(n); } + spin_unlock_irqrestore(&bigben->lock, flags); if (work) { bigben->work_led = true; @@ -307,8 +350,12 @@ static enum led_brightness bigben_get_led(struct led_classdev *led) static void bigben_remove(struct hid_device *hid) { struct bigben_device *bigben = hid_get_drvdata(hid); + unsigned long flags; + spin_lock_irqsave(&bigben->lock, flags); bigben->removed = true; + spin_unlock_irqrestore(&bigben->lock, flags); + cancel_work_sync(&bigben->worker); hid_hw_stop(hid); } @@ -362,6 +409,7 @@ static int bigben_probe(struct hid_device *hid, set_bit(FF_RUMBLE, hidinput->input->ffbit); INIT_WORK(&bigben->worker, bigben_worker); + spin_lock_init(&bigben->lock); error = input_ff_create_memless(hidinput->input, NULL, hid_bigben_play_effect); From ec8b79668ebf0df155b360b5480362f07cdd37d2 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sun, 12 Feb 2023 19:00:00 +0000 Subject: [PATCH 0330/1017] HID: bigben_worker() remove unneeded check on report_field [ Upstream commit 27d2a2fd844ec7da70d19fabb482304fd1e0595b ] bigben_worker() checks report_field to be non-NULL. The check has been added in commit 918aa1ef104d ("HID: bigbenff: prevent null pointer dereference") to prevent a NULL pointer crash. However, the true root cause was a missing check for output reports, patched in commit c7bf714f8755 ("HID: check empty report_list in bigben_probe()"), where the type-confused report list_entry was overlapping with a NULL pointer, which was then causing the crash. Fixes: 918aa1ef104d ("HID: bigbenff: prevent null pointer dereference") Signed-off-by: Pietro Borrello Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-2-7860c5763c38@diag.uniroma1.it Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-bigbenff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c index ed3d2d7bc1dd..b98c5f31c184 100644 --- a/drivers/hid/hid-bigbenff.c +++ b/drivers/hid/hid-bigbenff.c @@ -197,7 +197,7 @@ static void bigben_worker(struct work_struct *work) u32 len; unsigned long flags; - if (bigben->removed || !report_field) + if (bigben->removed) return; buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL); From fddde36316da8acb45a3cca2e5fda102f5215877 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sun, 12 Feb 2023 19:00:01 +0000 Subject: [PATCH 0331/1017] HID: bigben: use spinlock to safely schedule workers [ Upstream commit 76ca8da989c7d97a7f76c75d475fe95a584439d7 ] Use spinlocks to deal with workers introducing a wrapper bigben_schedule_work(), and several spinlock checks. Otherwise, bigben_set_led() may schedule bigben->worker after the structure has been freed, causing a use-after-free. Fixes: 4eb1b01de5b9 ("HID: hid-bigbenff: fix race condition for scheduled work during removal") Signed-off-by: Pietro Borrello Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-3-7860c5763c38@diag.uniroma1.it Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-bigbenff.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c index b98c5f31c184..9d6560db762b 100644 --- a/drivers/hid/hid-bigbenff.c +++ b/drivers/hid/hid-bigbenff.c @@ -185,6 +185,15 @@ struct bigben_device { struct work_struct worker; }; +static inline void bigben_schedule_work(struct bigben_device *bigben) +{ + unsigned long flags; + + spin_lock_irqsave(&bigben->lock, flags); + if (!bigben->removed) + schedule_work(&bigben->worker); + spin_unlock_irqrestore(&bigben->lock, flags); +} static void bigben_worker(struct work_struct *work) { @@ -197,9 +206,6 @@ static void bigben_worker(struct work_struct *work) u32 len; unsigned long flags; - if (bigben->removed) - return; - buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL); if (!buf) return; @@ -285,7 +291,7 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data, bigben->work_ff = true; spin_unlock_irqrestore(&bigben->lock, flags); - schedule_work(&bigben->worker); + bigben_schedule_work(bigben); } return 0; @@ -320,7 +326,7 @@ static void bigben_set_led(struct led_classdev *led, if (work) { bigben->work_led = true; - schedule_work(&bigben->worker); + bigben_schedule_work(bigben); } return; } @@ -450,7 +456,7 @@ static int bigben_probe(struct hid_device *hid, bigben->left_motor_force = 0; bigben->work_led = true; bigben->work_ff = true; - schedule_work(&bigben->worker); + bigben_schedule_work(bigben); hid_info(hid, "LED and force feedback support for BigBen gamepad\n"); From e73640184cb6f74b9c425f6e503f98ea102e0670 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sun, 12 Feb 2023 00:01:44 +0000 Subject: [PATCH 0332/1017] hid: bigben_probe(): validate report count [ Upstream commit b94335f899542a0da5fafc38af8edcaf90195843 ] bigben_probe() does not validate that the output report has the needed report values in the first field. A malicious device registering a report with one field and a single value causes an head OOB write in bigben_worker() when accessing report_field->value[1] to report_field->value[7]. Use hid_validate_values() which takes care of all the needed checks. Fixes: 256a90ed9e46 ("HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad") Signed-off-by: Pietro Borrello Link: https://lore.kernel.org/r/20230211-bigben-oob-v1-1-d2849688594c@diag.uniroma1.it Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-bigbenff.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c index 9d6560db762b..a02cb517b4c4 100644 --- a/drivers/hid/hid-bigbenff.c +++ b/drivers/hid/hid-bigbenff.c @@ -371,7 +371,6 @@ static int bigben_probe(struct hid_device *hid, { struct bigben_device *bigben; struct hid_input *hidinput; - struct list_head *report_list; struct led_classdev *led; char *name; size_t name_sz; @@ -396,14 +395,12 @@ static int bigben_probe(struct hid_device *hid, return error; } - report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - if (list_empty(report_list)) { + bigben->report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 8); + if (!bigben->report) { hid_err(hid, "no output report found\n"); error = -ENODEV; goto error_hw_stop; } - bigben->report = list_entry(report_list->next, - struct hid_report, list); if (list_empty(&hid->inputs)) { hid_err(hid, "no inputs found\n"); From 9e8ccaf4ff2c4808004276267365da72693b9ddc Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Fri, 27 Jan 2023 11:18:56 -0500 Subject: [PATCH 0333/1017] nfsd: fix race to check ls_layouts [ Upstream commit fb610c4dbc996415d57d7090957ecddd4fd64fb6 ] Its possible for __break_lease to find the layout's lease before we've added the layout to the owner's ls_layouts list. In that case, setting ls_recalled = true without actually recalling the layout will cause the server to never send a recall callback. Move the check for ls_layouts before setting ls_recalled. Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls") Signed-off-by: Benjamin Coddington Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4layouts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index a97873f2d22b..2673019d30ec 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -322,11 +322,11 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls) if (ls->ls_recalled) goto out_unlock; - ls->ls_recalled = true; - atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls); if (list_empty(&ls->ls_layouts)) goto out_unlock; + ls->ls_recalled = true; + atomic_inc(&ls->ls_stid.sc_file->fi_lo_recalls); trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid); refcount_inc(&ls->ls_stid.sc_count); From caac205e0d5b44c4c23a10c6c0976d50ebe16ac2 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Fri, 18 Nov 2022 16:42:07 +0800 Subject: [PATCH 0334/1017] cifs: Fix lost destroy smbd connection when MR allocate failed [ Upstream commit e9d3401d95d62a9531082cd2453ed42f2740e3fd ] If the MR allocate failed, the smb direct connection info is NULL, then smbd_destroy() will directly return, then the connection info will be leaked. Let's set the smb direct connection info to the server before call smbd_destroy(). Fixes: c7398583340a ("CIFS: SMBD: Implement RDMA memory registration") Signed-off-by: Zhang Xiaoxu Acked-by: Paulo Alcantara (SUSE) Reviewed-by: David Howells Reviewed-by: Tom Talpey Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/smbdirect.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index f73f9b062525..c93d4ec843be 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -1691,6 +1691,7 @@ static struct smbd_connection *_smbd_get_connection( allocate_mr_failed: /* At this point, need to a full transport shutdown */ + server->smbd_conn = info; smbd_destroy(server); return NULL; From cfd85a0922c4696d768965e686ad805a58d9d834 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Fri, 18 Nov 2022 16:42:08 +0800 Subject: [PATCH 0335/1017] cifs: Fix warning and UAF when destroy the MR list [ Upstream commit 3e161c2791f8e661eed24a2c624087084d910215 ] If the MR allocate failed, the MR recovery work not initialized and list not cleared. Then will be warning and UAF when release the MR: WARNING: CPU: 4 PID: 824 at kernel/workqueue.c:3066 __flush_work.isra.0+0xf7/0x110 CPU: 4 PID: 824 Comm: mount.cifs Not tainted 6.1.0-rc5+ #82 RIP: 0010:__flush_work.isra.0+0xf7/0x110 Call Trace: __cancel_work_timer+0x2ba/0x2e0 smbd_destroy+0x4e1/0x990 _smbd_get_connection+0x1cbd/0x2110 smbd_get_connection+0x21/0x40 cifs_get_tcp_session+0x8ef/0xda0 mount_get_conns+0x60/0x750 cifs_mount+0x103/0xd00 cifs_smb3_do_mount+0x1dd/0xcb0 smb3_get_tree+0x1d5/0x300 vfs_get_tree+0x41/0xf0 path_mount+0x9b3/0xdd0 __x64_sys_mount+0x190/0x1d0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 BUG: KASAN: use-after-free in smbd_destroy+0x4fc/0x990 Read of size 8 at addr ffff88810b156a08 by task mount.cifs/824 CPU: 4 PID: 824 Comm: mount.cifs Tainted: G W 6.1.0-rc5+ #82 Call Trace: dump_stack_lvl+0x34/0x44 print_report+0x171/0x472 kasan_report+0xad/0x130 smbd_destroy+0x4fc/0x990 _smbd_get_connection+0x1cbd/0x2110 smbd_get_connection+0x21/0x40 cifs_get_tcp_session+0x8ef/0xda0 mount_get_conns+0x60/0x750 cifs_mount+0x103/0xd00 cifs_smb3_do_mount+0x1dd/0xcb0 smb3_get_tree+0x1d5/0x300 vfs_get_tree+0x41/0xf0 path_mount+0x9b3/0xdd0 __x64_sys_mount+0x190/0x1d0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Allocated by task 824: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_kmalloc+0x7a/0x90 _smbd_get_connection+0x1b6f/0x2110 smbd_get_connection+0x21/0x40 cifs_get_tcp_session+0x8ef/0xda0 mount_get_conns+0x60/0x750 cifs_mount+0x103/0xd00 cifs_smb3_do_mount+0x1dd/0xcb0 smb3_get_tree+0x1d5/0x300 vfs_get_tree+0x41/0xf0 path_mount+0x9b3/0xdd0 __x64_sys_mount+0x190/0x1d0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Freed by task 824: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_save_free_info+0x2a/0x40 ____kasan_slab_free+0x143/0x1b0 __kmem_cache_free+0xc8/0x330 _smbd_get_connection+0x1c6a/0x2110 smbd_get_connection+0x21/0x40 cifs_get_tcp_session+0x8ef/0xda0 mount_get_conns+0x60/0x750 cifs_mount+0x103/0xd00 cifs_smb3_do_mount+0x1dd/0xcb0 smb3_get_tree+0x1d5/0x300 vfs_get_tree+0x41/0xf0 path_mount+0x9b3/0xdd0 __x64_sys_mount+0x190/0x1d0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Let's initialize the MR recovery work before MR allocate to prevent the warning, remove the MRs from the list to prevent the UAF. Fixes: c7398583340a ("CIFS: SMBD: Implement RDMA memory registration") Acked-by: Paulo Alcantara (SUSE) Reviewed-by: Tom Talpey Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/smbdirect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index c93d4ec843be..bcc611069308 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -2240,6 +2240,7 @@ static int allocate_mr_list(struct smbd_connection *info) atomic_set(&info->mr_ready_count, 0); atomic_set(&info->mr_used_count, 0); init_waitqueue_head(&info->wait_for_mr_cleanup); + INIT_WORK(&info->mr_recovery_work, smbd_mr_recovery_work); /* Allocate more MRs (2x) than hardware responder_resources */ for (i = 0; i < info->responder_resources * 2; i++) { smbdirect_mr = kzalloc(sizeof(*smbdirect_mr), GFP_KERNEL); @@ -2267,13 +2268,13 @@ static int allocate_mr_list(struct smbd_connection *info) list_add_tail(&smbdirect_mr->list, &info->mr_list); atomic_inc(&info->mr_ready_count); } - INIT_WORK(&info->mr_recovery_work, smbd_mr_recovery_work); return 0; out: kfree(smbdirect_mr); list_for_each_entry_safe(smbdirect_mr, tmp, &info->mr_list, list) { + list_del(&smbdirect_mr->list); ib_dereg_mr(smbdirect_mr->mr); kfree(smbdirect_mr->sgl); kfree(smbdirect_mr); From deece7bd60b0890dc9cb9b7e7295ca994a38abde Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 1 Feb 2023 15:08:50 +0100 Subject: [PATCH 0336/1017] gfs2: jdata writepage fix [ Upstream commit cbb60951ce18c9b6e91d2eb97deb41d8ff616622 ] The ->writepage() and ->writepages() operations are supposed to write entire pages. However, on filesystems with a block size smaller than PAGE_SIZE, __gfs2_jdata_writepage() only adds the first block to the current transaction instead of adding the entire page. Fix that. Fixes: 18ec7d5c3f43 ("[GFS2] Make journaled data files identical to normal files on disk") Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin --- fs/gfs2/aops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index cc4f987687f3..530659554870 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -152,7 +152,6 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w { struct inode *inode = page->mapping->host; struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_sbd *sdp = GFS2_SB(inode); if (PageChecked(page)) { ClearPageChecked(page); @@ -160,7 +159,7 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w create_empty_buffers(page, inode->i_sb->s_blocksize, BIT(BH_Dirty)|BIT(BH_Uptodate)); } - gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize); + gfs2_page_add_databufs(ip, page, 0, PAGE_SIZE); } return gfs2_write_jdata_page(page, wbc); } From 071b7f572051259f9f5aaae1cecda1a7055a03d5 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 5 Jan 2023 00:26:09 -0800 Subject: [PATCH 0337/1017] perf llvm: Fix inadvertent file creation [ Upstream commit 9f19aab47ced012eddef1e2bc96007efc7713b61 ] The LLVM template is first echo-ed into command_out and then command_out executed. The echo surrounds the template with double quotes, however, the template itself may contain quotes. This is generally innocuous but in tools/perf/tests/bpf-script-test-prologue.c we see: ... SEC("func=null_lseek file->f_mode offset orig") ... where the first double quote ends the double quote of the echo, then the > redirects output into a file called f_mode. To avoid this inadvertent behavior substitute redirects and similar characters to be ASCII control codes, then substitute the output in the echo back again. Fixes: 5eab5a7ee032acaa ("perf llvm: Display eBPF compiling command in debug output") Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: bpf@vger.kernel.org Cc: Ingo Molnar Cc: Jiri Olsa Cc: llvm@lists.linux.dev Cc: Mark Rutland Cc: Namhyung Kim Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: Peter Zijlstra Cc: Tom Rix Link: https://lore.kernel.org/r/20230105082609.344538-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/llvm-utils.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 0bf6b4d4c90a..570cde4640d0 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -525,14 +525,37 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, pr_debug("llvm compiling command template: %s\n", template); + /* + * Below, substitute control characters for values that can cause the + * echo to misbehave, then substitute the values back. + */ err = -ENOMEM; - if (asprintf(&command_echo, "echo -n \"%s\"", template) < 0) + if (asprintf(&command_echo, "echo -n \a%s\a", template) < 0) goto errout; +#define SWAP_CHAR(a, b) do { if (*p == a) *p = b; } while (0) + for (char *p = command_echo; *p; p++) { + SWAP_CHAR('<', '\001'); + SWAP_CHAR('>', '\002'); + SWAP_CHAR('"', '\003'); + SWAP_CHAR('\'', '\004'); + SWAP_CHAR('|', '\005'); + SWAP_CHAR('&', '\006'); + SWAP_CHAR('\a', '"'); + } err = read_from_pipe(command_echo, (void **) &command_out, NULL); if (err) goto errout; + for (char *p = command_out; *p; p++) { + SWAP_CHAR('\001', '<'); + SWAP_CHAR('\002', '>'); + SWAP_CHAR('\003', '"'); + SWAP_CHAR('\004', '\''); + SWAP_CHAR('\005', '|'); + SWAP_CHAR('\006', '&'); + } +#undef SWAP_CHAR pr_debug("llvm compiling command : %s\n", command_out); err = read_from_pipe(template, &obj_buf, &obj_buf_sz); From 1d6101d9222e1ca8c01b3fa9ebf0dcf7bcd82564 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Tue, 20 Dec 2022 16:18:07 +0400 Subject: [PATCH 0338/1017] leds: led-core: Fix refcount leak in of_led_get() [ Upstream commit da1afe8e6099980fe1e2fd7436dca284af9d3f29 ] class_find_device_by_of_node() calls class_find_device(), it will take the reference, use the put_device() to drop the reference when not need anymore. Fixes: 699a8c7c4bd3 ("leds: Add of_led_get() and led_put()") Signed-off-by: Miaoqian Lin Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20221220121807.1543790-1-linmq006@gmail.com Signed-off-by: Sasha Levin --- drivers/leds/led-class.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index e28a4bb71603..fcb9eee3b609 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -236,6 +236,7 @@ struct led_classdev *of_led_get(struct device_node *np, int index) led_dev = class_find_device_by_of_node(leds_class, led_node); of_node_put(led_node); + put_device(led_dev); if (!led_dev) return ERR_PTR(-EPROBE_DEFER); From 93925ab9dd74dc65e1c63b829c0bee8467be29d0 Mon Sep 17 00:00:00 2001 From: Yicong Yang Date: Tue, 7 Feb 2023 11:50:57 +0800 Subject: [PATCH 0339/1017] perf tools: Fix auto-complete on aarch64 [ Upstream commit ffd1240e8f0814262ceb957dbe961f6e0aef1e7a ] On aarch64 CPU related events are not under event_source/devices/cpu/events, they're under event_source/devices/armv8_pmuv3_0/events on my machine. Using current auto-complete script will generate below error: [root@localhost bin]# perf stat -e ls: cannot access '/sys/bus/event_source/devices/cpu/events': No such file or directory Fix this by not testing /sys/bus/event_source/devices/cpu/events on aarch64 machine. Fixes: 74cd5815d9af6e6c ("perf tool: Improve bash command line auto-complete for multiple events with comma") Reviewed-by: James Clark Signed-off-by: Yicong Yang Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linux-arm-kernel@lists.infradead.org Cc: linuxarm@huawei.com Cc: prime.zeng@hisilicon.com Link: https://lore.kernel.org/r/20230207035057.43394-1-yangyicong@huawei.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/perf-completion.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh index fdf75d45efff..978249d7868c 100644 --- a/tools/perf/perf-completion.sh +++ b/tools/perf/perf-completion.sh @@ -165,7 +165,12 @@ __perf_main () local cur1=${COMP_WORDS[COMP_CWORD]} local raw_evts=$($cmd list --raw-dump) - local arr s tmp result + local arr s tmp result cpu_evts + + # aarch64 doesn't have /sys/bus/event_source/devices/cpu/events + if [[ `uname -m` != aarch64 ]]; then + cpu_evts=$(ls /sys/bus/event_source/devices/cpu/events) + fi if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then OLD_IFS="$IFS" @@ -183,9 +188,9 @@ __perf_main () fi done - evts=${result}" "$(ls /sys/bus/event_source/devices/cpu/events) + evts=${result}" "${cpu_evts} else - evts=${raw_evts}" "$(ls /sys/bus/event_source/devices/cpu/events) + evts=${raw_evts}" "${cpu_evts} fi if [[ "$cur1" == , ]]; then From b8dc9f6fde194631f6e6158a65cdfcc77f597de3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 4 Feb 2023 16:43:57 -0800 Subject: [PATCH 0340/1017] sparc: allow PM configs for sparc32 COMPILE_TEST [ Upstream commit 7be6a87c2473957090995b7eb541e31d57a2c801 ] When doing randconfig builds for sparc32 with COMPILE_TEST, some (non-Sparc) drivers cause kconfig warnings with the Kconfig symbols PM, PM_GENERIC_DOMAINS, or PM_GENERIC_DOMAINS_OF. This is due to arch/sparc/Kconfig not using the PM Kconfig for Sparc32: if SPARC64 source "kernel/power/Kconfig" endif Arnd suggested adding "|| COMPILE_TEST" to the conditional, instead of trying to track down every driver that selects any of these PM symbols. Fixes the following kconfig warnings: WARNING: unmet direct dependencies detected for PM Depends on [n]: SPARC64 [=n] Selected by [y]: - SUN20I_PPU [=y] && (ARCH_SUNXI || COMPILE_TEST [=y]) WARNING: unmet direct dependencies detected for PM Depends on [n]: SPARC64 [=n] Selected by [y]: - SUN20I_PPU [=y] && (ARCH_SUNXI || COMPILE_TEST [=y]) WARNING: unmet direct dependencies detected for PM_GENERIC_DOMAINS Depends on [n]: SPARC64 [=n] && PM [=y] Selected by [y]: - QCOM_GDSC [=y] && COMMON_CLK [=y] && PM [=y] - SUN20I_PPU [=y] && (ARCH_SUNXI || COMPILE_TEST [=y]) - MESON_GX_PM_DOMAINS [=y] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y] - BCM2835_POWER [=y] && (ARCH_BCM2835 || COMPILE_TEST [=y] && OF [=y]) && PM [=y] - BCM_PMB [=y] && (ARCH_BCMBCA || COMPILE_TEST [=y] && OF [=y]) && PM [=y] - ROCKCHIP_PM_DOMAINS [=y] && (ARCH_ROCKCHIP || COMPILE_TEST [=y]) && PM [=y] Selected by [m]: - ARM_SCPI_POWER_DOMAIN [=m] && (ARM_SCPI_PROTOCOL [=m] || COMPILE_TEST [=y] && OF [=y]) && PM [=y] - MESON_EE_PM_DOMAINS [=m] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y] - QCOM_AOSS_QMP [=m] && (ARCH_QCOM || COMPILE_TEST [=y]) && MAILBOX [=y] && COMMON_CLK [=y] && PM [=y] WARNING: unmet direct dependencies detected for PM_GENERIC_DOMAINS_OF Depends on [n]: SPARC64 [=n] && PM_GENERIC_DOMAINS [=y] && OF [=y] Selected by [y]: - MESON_GX_PM_DOMAINS [=y] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y] Selected by [m]: - MESON_EE_PM_DOMAINS [=m] && (ARCH_MESON || COMPILE_TEST [=y]) && PM [=y] && OF [=y] Link: https://lkml.kernel.org/r/20230205004357.29459-1-rdunlap@infradead.org Fixes: bdde6b3c8ba4 ("sparc64: Hibernation support") Signed-off-by: Randy Dunlap Suggested-by: Arnd Bergmann Acked-by: Sam Ravnborg Cc: "David S. Miller" Cc: Kirill Tkhai Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- arch/sparc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 530b7ec5d3ca..b5ed89342059 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -293,7 +293,7 @@ config FORCE_MAX_ZONEORDER This config option is actually maximum order plus one. For example, a value of 13 means that the largest free memory block is 2^12 pages. -if SPARC64 +if SPARC64 || COMPILE_TEST source "kernel/power/Kconfig" endif From b18946a9cee2d239a556d6f94f2ea118c84d7a9e Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Sun, 22 Jan 2023 08:32:50 +0900 Subject: [PATCH 0341/1017] selftests/ftrace: Fix bash specific "==" operator [ Upstream commit 1e6b485c922fbedf41d5a9f4e6449c5aeb923a32 ] Since commit a1d6cd88c897 ("selftests/ftrace: event_triggers: wait longer for test_event_enable") introduced bash specific "==" comparation operator, that test will fail when we run it on a posix-shell. `checkbashisms` warned it as below. possible bashism in ftrace/func_event_triggers.tc line 45 (should be 'b = a'): if [ "$e" == $val ]; then This replaces it with "=". Fixes: a1d6cd88c897 ("selftests/ftrace: event_triggers: wait longer for test_event_enable") Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Steven Rostedt (Google) Signed-off-by: Shuah Khan Signed-off-by: Sasha Levin --- .../selftests/ftrace/test.d/ftrace/func_event_triggers.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc index 27a68bbe778b..d9b812795077 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc @@ -42,7 +42,7 @@ test_event_enabled() { while [ $check_times -ne 0 ]; do e=`cat $EVENT_ENABLE` - if [ "$e" == $val ]; then + if [ "$e" = $val ]; then return 0 fi sleep $SLEEP_TIME From 455cf05161be58d3f3892d001f09a5c315a27680 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 6 Feb 2023 20:40:57 +0100 Subject: [PATCH 0342/1017] printf: fix errname.c list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 0c2baf6509af1d11310ae4c1c839481a6e9a4bc4 ] On most architectures, gcc -Wextra warns about the list of error numbers containing both EDEADLK and EDEADLOCK: lib/errname.c:15:67: warning: initialized field overwritten [-Woverride-init] 15 | #define E(err) [err + BUILD_BUG_ON_ZERO(err <= 0 || err > 300)] = "-" #err | ^~~ lib/errname.c:172:2: note: in expansion of macro 'E' 172 | E(EDEADLK), /* EDEADLOCK */ | ^ On parisc, a similar error happens with -ECANCELLED, which is an alias for ECANCELED. Make the EDEADLK printing conditional on the number being distinct from EDEADLOCK, and remove the -ECANCELLED bit completely as it can never be hit. To ensure these are correct, add static_assert lines that verify all the remaining aliases are in fact identical to the canonical name. Fixes: 57f5677e535b ("printf: add support for printing symbolic error names") Cc: Petr Mladek Suggested-by: Rasmus Villemoes Acked-by: Uwe Kleine-König Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/all/20210514213456.745039-1-arnd@kernel.org/ Link: https://lore.kernel.org/all/20210927123409.1109737-1-arnd@kernel.org/ Signed-off-by: Arnd Bergmann Reviewed-by: Sergey Senozhatsky Acked-by: Rasmus Villemoes Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20230206194126.380350-1-arnd@kernel.org Signed-off-by: Sasha Levin --- lib/errname.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/errname.c b/lib/errname.c index 0c4d3e66170e..a5799a8c9cab 100644 --- a/lib/errname.c +++ b/lib/errname.c @@ -20,6 +20,7 @@ static const char *names_0[] = { E(EADDRNOTAVAIL), E(EADV), E(EAFNOSUPPORT), + E(EAGAIN), /* EWOULDBLOCK */ E(EALREADY), E(EBADE), E(EBADF), @@ -30,15 +31,17 @@ static const char *names_0[] = { E(EBADSLT), E(EBFONT), E(EBUSY), -#ifdef ECANCELLED - E(ECANCELLED), -#endif + E(ECANCELED), /* ECANCELLED */ E(ECHILD), E(ECHRNG), E(ECOMM), E(ECONNABORTED), + E(ECONNREFUSED), /* EREFUSED */ E(ECONNRESET), + E(EDEADLK), /* EDEADLOCK */ +#if EDEADLK != EDEADLOCK /* mips, sparc, powerpc */ E(EDEADLOCK), +#endif E(EDESTADDRREQ), E(EDOM), E(EDOTDOT), @@ -165,14 +168,17 @@ static const char *names_0[] = { E(EUSERS), E(EXDEV), E(EXFULL), - - E(ECANCELED), /* ECANCELLED */ - E(EAGAIN), /* EWOULDBLOCK */ - E(ECONNREFUSED), /* EREFUSED */ - E(EDEADLK), /* EDEADLOCK */ }; #undef E +#ifdef EREFUSED /* parisc */ +static_assert(EREFUSED == ECONNREFUSED); +#endif +#ifdef ECANCELLED /* parisc */ +static_assert(ECANCELLED == ECANCELED); +#endif +static_assert(EAGAIN == EWOULDBLOCK); /* everywhere */ + #define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err static const char *names_512[] = { E(ERESTARTSYS), From 8a041377a4583850be020db01fd8f45bad0abaaf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 15 Feb 2023 14:00:58 +0100 Subject: [PATCH 0343/1017] objtool: add UACCESS exceptions for __tsan_volatile_read/write [ Upstream commit d5d469247264e56960705dc5ae7e1d014861fe40 ] A lot of the tsan helpers are already excempt from the UACCESS warnings, but some more functions were added that need the same thing: kernel/kcsan/core.o: warning: objtool: __tsan_volatile_read16+0x0: call to __tsan_unaligned_read16() with UACCESS enabled kernel/kcsan/core.o: warning: objtool: __tsan_volatile_write16+0x0: call to __tsan_unaligned_write16() with UACCESS enabled vmlinux.o: warning: objtool: __tsan_unaligned_volatile_read16+0x4: call to __tsan_unaligned_read16() with UACCESS enabled vmlinux.o: warning: objtool: __tsan_unaligned_volatile_write16+0x4: call to __tsan_unaligned_write16() with UACCESS enabled As Marco points out, these functions don't even call each other explicitly but instead gcc (but not clang) notices the functions being identical and turns one symbol into a direct branch to the other. Link: https://lkml.kernel.org/r/20230215130058.3836177-4-arnd@kernel.org Fixes: 75d75b7a4d54 ("kcsan: Support distinguishing volatile accesses") Signed-off-by: Arnd Bergmann Acked-by: Marco Elver Cc: Alexander Potapenko Cc: Andrey Konovalov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Josh Poimboeuf Cc: Kuan-Ying Lee Cc: Peter Zijlstra (Intel) Cc: Vincenzo Frascino Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- tools/objtool/check.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ff47aed7ef6f..5c4190382a51 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -864,6 +864,8 @@ static const char *uaccess_safe_builtin[] = { "__tsan_atomic64_compare_exchange_val", "__tsan_atomic_thread_fence", "__tsan_atomic_signal_fence", + "__tsan_unaligned_read16", + "__tsan_unaligned_write16", /* KCOV */ "write_comp_data", "check_kcov_mode", From 3ee13bdf0d25ae8752ae6185b6d13bbb0d5a8e30 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Thu, 8 Dec 2022 14:15:55 +0800 Subject: [PATCH 0344/1017] mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read() [ Upstream commit 8b450dcff23aa254844492831a8e2b508a9d522d ] `req` is allocated in pcf50633_adc_async_read(), but adc_enqueue_request() could fail to insert the `req` into queue. We need to check the return value and free it in the case of failure. Fixes: 08c3e06a5eb2 ("mfd: PCF50633 adc driver") Signed-off-by: Qiheng Lin Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20221208061555.8776-1-linqiheng@huawei.com Signed-off-by: Sasha Levin --- drivers/mfd/pcf50633-adc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c index 5cd653e61512..191b1bc6141c 100644 --- a/drivers/mfd/pcf50633-adc.c +++ b/drivers/mfd/pcf50633-adc.c @@ -136,6 +136,7 @@ int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg, void *callback_param) { struct pcf50633_adc_request *req; + int ret; /* req is freed when the result is ready, in interrupt handler */ req = kmalloc(sizeof(*req), GFP_KERNEL); @@ -147,7 +148,11 @@ int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg, req->callback = callback; req->callback_param = callback_param; - return adc_enqueue_request(pcf, req); + ret = adc_enqueue_request(pcf, req); + if (ret) + kfree(req); + + return ret; } EXPORT_SYMBOL_GPL(pcf50633_adc_async_read); From 7fd6fd898b64834e3e7d7b344ced7b7dba62c9ab Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 26 Dec 2022 06:21:43 +0200 Subject: [PATCH 0345/1017] clk: qcom: gcc-qcs404: disable gpll[04]_out_aux parents [ Upstream commit 712c64caf31374de57aa193a9dff57172b2f6f82 ] On the QCS404 platform the driver for the Global Clock Controller doens't define gpll0_out_aux and gpll4_out_aux clocks, so it's not possible to use them as parents. Remove entries for these clocks. Note: backporting this patch to earlier kernels would also require a previous patch which switches the gcc driver to use ARRAY_SIZE for parent data arrays. Fixes: 652f1813c113 ("clk: qcom: gcc: Add global clock controller driver for QCS404") Signed-off-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221226042154.2666748-6-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/clk/qcom/gcc-qcs404.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index 46d314d69250..4299fe8f1927 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -25,11 +25,9 @@ enum { P_CORE_BI_PLL_TEST_SE, P_DSI0_PHY_PLL_OUT_BYTECLK, P_DSI0_PHY_PLL_OUT_DSICLK, - P_GPLL0_OUT_AUX, P_GPLL0_OUT_MAIN, P_GPLL1_OUT_MAIN, P_GPLL3_OUT_MAIN, - P_GPLL4_OUT_AUX, P_GPLL4_OUT_MAIN, P_GPLL6_OUT_AUX, P_HDMI_PHY_PLL_CLK, @@ -109,28 +107,24 @@ static const char * const gcc_parent_names_4[] = { static const struct parent_map gcc_parent_map_5[] = { { P_XO, 0 }, { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_5[] = { "cxo", "dsi0pll_byteclk_src", - "gpll0_out_aux", "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_6[] = { { P_XO, 0 }, { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, - { P_GPLL0_OUT_AUX, 3 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_6[] = { "cxo", "dsi0_phy_pll_out_byteclk", - "gpll0_out_aux", "core_bi_pll_test_se", }; @@ -139,7 +133,6 @@ static const struct parent_map gcc_parent_map_7[] = { { P_GPLL0_OUT_MAIN, 1 }, { P_GPLL3_OUT_MAIN, 2 }, { P_GPLL6_OUT_AUX, 3 }, - { P_GPLL4_OUT_AUX, 4 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; @@ -148,7 +141,6 @@ static const char * const gcc_parent_names_7[] = { "gpll0_out_main", "gpll3_out_main", "gpll6_out_aux", - "gpll4_out_aux", "core_bi_pll_test_se", }; @@ -207,14 +199,12 @@ static const char * const gcc_parent_names_11[] = { static const struct parent_map gcc_parent_map_12[] = { { P_XO, 0 }, { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_12[] = { "cxo", "dsi0pll_pclk_src", - "gpll0_out_aux", "core_bi_pll_test_se", }; @@ -237,40 +227,34 @@ static const char * const gcc_parent_names_13[] = { static const struct parent_map gcc_parent_map_14[] = { { P_XO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, - { P_GPLL4_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_14[] = { "cxo", "gpll0_out_main", - "gpll4_out_aux", "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_15[] = { { P_XO, 0 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_15[] = { "cxo", - "gpll0_out_aux", "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_16[] = { { P_XO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_16[] = { "cxo", "gpll0_out_main", - "gpll0_out_aux", "core_bi_pll_test_se", }; From c7950aa8728085d4ef374f2b03572ffaf8eeed3c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 26 Dec 2022 06:21:44 +0200 Subject: [PATCH 0346/1017] clk: qcom: gcc-qcs404: fix names of the DSI clocks used as parents [ Upstream commit 47d94d30cd3dcc743241b4208b1eec7247610c84 ] The QCS404 uses 28nm LPM DSI PHY, which registers dsi0pll and dsi0pllbyte clocks. Fix all DSI PHY clock names used as parents inside the GCC driver. Fixes: 652f1813c113 ("clk: qcom: gcc: Add global clock controller driver for QCS404") Reviewed-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221226042154.2666748-7-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/clk/qcom/gcc-qcs404.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index 4299fe8f1927..a7a9884799cd 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -112,7 +112,7 @@ static const struct parent_map gcc_parent_map_5[] = { static const char * const gcc_parent_names_5[] = { "cxo", - "dsi0pll_byteclk_src", + "dsi0pllbyte", "core_bi_pll_test_se", }; @@ -124,7 +124,7 @@ static const struct parent_map gcc_parent_map_6[] = { static const char * const gcc_parent_names_6[] = { "cxo", - "dsi0_phy_pll_out_byteclk", + "dsi0pllbyte", "core_bi_pll_test_se", }; @@ -167,7 +167,7 @@ static const struct parent_map gcc_parent_map_9[] = { static const char * const gcc_parent_names_9[] = { "cxo", "gpll0_out_main", - "dsi0_phy_pll_out_dsiclk", + "dsi0pll", "gpll6_out_aux", "core_bi_pll_test_se", }; @@ -204,7 +204,7 @@ static const struct parent_map gcc_parent_map_12[] = { static const char * const gcc_parent_names_12[] = { "cxo", - "dsi0pll_pclk_src", + "dsi0pll", "core_bi_pll_test_se", }; From c90fa32bd4d200fa972b39e0d3b28f6c900b23e8 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 23 Dec 2022 23:13:21 +0100 Subject: [PATCH 0347/1017] RISC-V: fix funct4 definition for c.jalr in parse_asm.h [ Upstream commit a3775634f6da23f5511d0282d7e792cf606e5f3b ] The opcode definition for c.jalr is c.jalr c_rs1_n0 1..0=2 15..13=4 12=1 6..2=0 This means funct4 consisting of bit [15:12] is 1001b, so the value is 0x9. Fixes: edde5584c7ab ("riscv: Add SW single-step support for KDB") Reported-by: Andrew Jones Reviewed-by: Andrew Jones Reviewed-by: Lad Prabhakar Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20221223221332.4127602-2-heiko@sntech.de Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/include/asm/parse_asm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/parse_asm.h b/arch/riscv/include/asm/parse_asm.h index f36368de839f..7fee806805c1 100644 --- a/arch/riscv/include/asm/parse_asm.h +++ b/arch/riscv/include/asm/parse_asm.h @@ -125,7 +125,7 @@ #define FUNCT3_C_J 0xa000 #define FUNCT3_C_JAL 0x2000 #define FUNCT4_C_JR 0x8000 -#define FUNCT4_C_JALR 0xf000 +#define FUNCT4_C_JALR 0x9000 #define FUNCT12_SRET 0x10200000 From b7fb5b5d2c8c6196d8b8dccaaefc40dbf59f31d9 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 29 Dec 2022 12:15:24 -0600 Subject: [PATCH 0348/1017] mtd: rawnand: sunxi: Fix the size of the last OOB region [ Upstream commit 34569d869532b54d6e360d224a0254dcdd6a1785 ] The previous code assigned to the wrong structure member. Fixes: c66811e6d350 ("mtd: nand: sunxi: switch to mtd_ooblayout_ops") Signed-off-by: Samuel Holland Acked-By: Dhruva Gole Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20221229181526.53766-6-samuel@sholland.org Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/sunxi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 2a7ca3072f35..52eb28f3277c 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1587,7 +1587,7 @@ static int sunxi_nand_ooblayout_free(struct mtd_info *mtd, int section, if (section < ecc->steps) oobregion->length = 4; else - oobregion->offset = mtd->oobsize - oobregion->offset; + oobregion->length = mtd->oobsize - oobregion->offset; return 0; } From a6a70ab2bbe24704b5241d4cab6f4e031ceef3ce Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Tue, 3 Jan 2023 11:58:31 -0600 Subject: [PATCH 0349/1017] Input: iqs269a - drop unused device node references [ Upstream commit 59bc9cb3b80abaa42643abede0d5db8477901d9c ] Each call to device/fwnode_get_named_child_node() must be matched with a call to fwnode_handle_put() once the corresponding node is no longer in use. This ensures a reference count remains balanced in the case of dynamic device tree support. Currently, the driver does not call fwnode_handle_put() on nested event nodes. This patch solves this problem by adding the missing instances of fwnode_handle_put(). As part of this change, the logic which parses each channel's key code is gently refactored in order to reduce the number of places from which fwnode_handle_put() is called. Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/Y7Rsx68k/gvDVXAt@nixie71 Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/misc/iqs269a.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index a348247d3d38..ea3c97c5f764 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -694,6 +694,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, dev_err(&client->dev, "Invalid channel %u threshold: %u\n", reg, val); + fwnode_handle_put(ev_node); return -EINVAL; } @@ -707,6 +708,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, dev_err(&client->dev, "Invalid channel %u hysteresis: %u\n", reg, val); + fwnode_handle_put(ev_node); return -EINVAL; } @@ -721,8 +723,16 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, } } - if (fwnode_property_read_u32(ev_node, "linux,code", &val)) + error = fwnode_property_read_u32(ev_node, "linux,code", &val); + fwnode_handle_put(ev_node); + if (error == -EINVAL) { continue; + } else if (error) { + dev_err(&client->dev, + "Failed to read channel %u code: %d\n", reg, + error); + return error; + } switch (reg) { case IQS269_CHx_HALL_ACTIVE: From b7afc359f6e57dc9d0e0a58d3072692a237c5998 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Tue, 3 Jan 2023 11:58:59 -0600 Subject: [PATCH 0350/1017] Input: iqs269a - increase interrupt handler return delay [ Upstream commit e023cc4abde3c01b895660b0e5a8488deb36b8c1 ] The time the device takes to deassert its RDY output following an I2C stop condition scales with the core clock frequency. To prevent level-triggered interrupts from being reasserted after the interrupt handler returns, increase the time before returning to account for the worst-case delay (~140 us) plus margin. Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/Y7Rs484ypy4dab5G@nixie71 Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/misc/iqs269a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index ea3c97c5f764..ea3401a1000f 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -153,7 +153,7 @@ #define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US #define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US -#define iqs269_irq_wait() usleep_range(100, 150) +#define iqs269_irq_wait() usleep_range(200, 250) enum iqs269_local_cap_size { IQS269_LOCAL_CAP_SIZE_0, From 9a6dca86cfae3cefe857633d6670a5c9a64e31c3 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Tue, 3 Jan 2023 11:59:12 -0600 Subject: [PATCH 0351/1017] Input: iqs269a - configure device with a single block write [ Upstream commit 3689abfc4e369a643d758a02fb9ad0b2403d6d6d ] Unless it is being done as part of servicing a soft reset interrupt, configuring channels on-the-fly (as is the case when writing to the ati_trigger attribute) may cause GPIO3 (which reflects the state of touch for a selected channel) to be inadvertently asserted. To solve this problem, follow the vendor's recommendation and write all channel configuration as well as the REDO_ATI register field as part of a single block write. This ensures the device has been told to re-calibrate itself following an I2C stop condition, after which sensing resumes and GPIO3 may be asserted. Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/Y7Rs8GyV7g0nF5Yy@nixie71 Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/misc/iqs269a.c | 98 ++++++++++++++---------------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index ea3401a1000f..1530efd301c2 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -96,8 +96,6 @@ #define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4) #define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0) -#define IQS269_CHx_SETTINGS 0x8C - #define IQS269_CHx_ENG_A_MEAS_CAP_SIZE BIT(15) #define IQS269_CHx_ENG_A_RX_GND_INACTIVE BIT(13) #define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE BIT(12) @@ -245,6 +243,18 @@ struct iqs269_ver_info { u8 padding; } __packed; +struct iqs269_ch_reg { + u8 rx_enable; + u8 tx_enable; + __be16 engine_a; + __be16 engine_b; + __be16 ati_comp; + u8 thresh[3]; + u8 hyst; + u8 assoc_select; + u8 assoc_weight; +} __packed; + struct iqs269_sys_reg { __be16 general; u8 active; @@ -266,18 +276,7 @@ struct iqs269_sys_reg { u8 timeout_swipe; u8 thresh_swipe; u8 redo_ati; -} __packed; - -struct iqs269_ch_reg { - u8 rx_enable; - u8 tx_enable; - __be16 engine_a; - __be16 engine_b; - __be16 ati_comp; - u8 thresh[3]; - u8 hyst; - u8 assoc_select; - u8 assoc_weight; + struct iqs269_ch_reg ch_reg[IQS269_NUM_CH]; } __packed; struct iqs269_flags { @@ -292,7 +291,6 @@ struct iqs269_private { struct regmap *regmap; struct mutex lock; struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)]; - struct iqs269_ch_reg ch_reg[IQS269_NUM_CH]; struct iqs269_sys_reg sys_reg; struct input_dev *keypad; struct input_dev *slider[IQS269_NUM_SL]; @@ -307,6 +305,7 @@ struct iqs269_private { static int iqs269_ati_mode_set(struct iqs269_private *iqs269, unsigned int ch_num, unsigned int mode) { + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; u16 engine_a; if (ch_num >= IQS269_NUM_CH) @@ -317,12 +316,12 @@ static int iqs269_ati_mode_set(struct iqs269_private *iqs269, mutex_lock(&iqs269->lock); - engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a); + engine_a = be16_to_cpu(ch_reg[ch_num].engine_a); engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK; engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT); - iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a); + ch_reg[ch_num].engine_a = cpu_to_be16(engine_a); iqs269->ati_current = false; mutex_unlock(&iqs269->lock); @@ -333,13 +332,14 @@ static int iqs269_ati_mode_set(struct iqs269_private *iqs269, static int iqs269_ati_mode_get(struct iqs269_private *iqs269, unsigned int ch_num, unsigned int *mode) { + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; u16 engine_a; if (ch_num >= IQS269_NUM_CH) return -EINVAL; mutex_lock(&iqs269->lock); - engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a); + engine_a = be16_to_cpu(ch_reg[ch_num].engine_a); mutex_unlock(&iqs269->lock); engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK; @@ -351,6 +351,7 @@ static int iqs269_ati_mode_get(struct iqs269_private *iqs269, static int iqs269_ati_base_set(struct iqs269_private *iqs269, unsigned int ch_num, unsigned int base) { + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; u16 engine_b; if (ch_num >= IQS269_NUM_CH) @@ -379,12 +380,12 @@ static int iqs269_ati_base_set(struct iqs269_private *iqs269, mutex_lock(&iqs269->lock); - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK; engine_b |= base; - iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); + ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); iqs269->ati_current = false; mutex_unlock(&iqs269->lock); @@ -395,13 +396,14 @@ static int iqs269_ati_base_set(struct iqs269_private *iqs269, static int iqs269_ati_base_get(struct iqs269_private *iqs269, unsigned int ch_num, unsigned int *base) { + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; u16 engine_b; if (ch_num >= IQS269_NUM_CH) return -EINVAL; mutex_lock(&iqs269->lock); - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); mutex_unlock(&iqs269->lock); switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) { @@ -429,6 +431,7 @@ static int iqs269_ati_base_get(struct iqs269_private *iqs269, static int iqs269_ati_target_set(struct iqs269_private *iqs269, unsigned int ch_num, unsigned int target) { + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; u16 engine_b; if (ch_num >= IQS269_NUM_CH) @@ -439,12 +442,12 @@ static int iqs269_ati_target_set(struct iqs269_private *iqs269, mutex_lock(&iqs269->lock); - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK; engine_b |= target / 32; - iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); + ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); iqs269->ati_current = false; mutex_unlock(&iqs269->lock); @@ -455,13 +458,14 @@ static int iqs269_ati_target_set(struct iqs269_private *iqs269, static int iqs269_ati_target_get(struct iqs269_private *iqs269, unsigned int ch_num, unsigned int *target) { + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; u16 engine_b; if (ch_num >= IQS269_NUM_CH) return -EINVAL; mutex_lock(&iqs269->lock); - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); mutex_unlock(&iqs269->lock); *target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32; @@ -531,13 +535,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, if (fwnode_property_present(ch_node, "azoteq,slider1-select")) iqs269->sys_reg.slider_select[1] |= BIT(reg); - ch_reg = &iqs269->ch_reg[reg]; - - error = regmap_raw_read(iqs269->regmap, - IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2, - ch_reg, sizeof(*ch_reg)); - if (error) - return error; + ch_reg = &iqs269->sys_reg.ch_reg[reg]; error = iqs269_parse_mask(ch_node, "azoteq,rx-enable", &ch_reg->rx_enable); @@ -1042,10 +1040,8 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269) static int iqs269_dev_init(struct iqs269_private *iqs269) { - struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg; - struct iqs269_ch_reg *ch_reg; unsigned int val; - int error, i; + int error; mutex_lock(&iqs269->lock); @@ -1055,27 +1051,8 @@ static int iqs269_dev_init(struct iqs269_private *iqs269) if (error) goto err_mutex; - for (i = 0; i < IQS269_NUM_CH; i++) { - if (!(sys_reg->active & BIT(i))) - continue; - - ch_reg = &iqs269->ch_reg[i]; - - error = regmap_raw_write(iqs269->regmap, - IQS269_CHx_SETTINGS + i * - sizeof(*ch_reg) / 2, ch_reg, - sizeof(*ch_reg)); - if (error) - goto err_mutex; - } - - /* - * The REDO-ATI and ATI channel selection fields must be written in the - * same block write, so every field between registers 0x80 through 0x8B - * (inclusive) must be written as well. - */ - error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg, - sizeof(*sys_reg)); + error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, + &iqs269->sys_reg, sizeof(iqs269->sys_reg)); if (error) goto err_mutex; @@ -1349,6 +1326,7 @@ static ssize_t hall_bin_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iqs269_private *iqs269 = dev_get_drvdata(dev); + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; struct i2c_client *client = iqs269->client; unsigned int val; int error; @@ -1363,8 +1341,8 @@ static ssize_t hall_bin_show(struct device *dev, if (error) return error; - switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable & - iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) { + switch (ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable & + ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) { case IQS269_HALL_PAD_R: val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK; val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT; @@ -1444,9 +1422,10 @@ static ssize_t rx_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iqs269_private *iqs269 = dev_get_drvdata(dev); + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; return scnprintf(buf, PAGE_SIZE, "%u\n", - iqs269->ch_reg[iqs269->ch_num].rx_enable); + ch_reg[iqs269->ch_num].rx_enable); } static ssize_t rx_enable_store(struct device *dev, @@ -1454,6 +1433,7 @@ static ssize_t rx_enable_store(struct device *dev, size_t count) { struct iqs269_private *iqs269 = dev_get_drvdata(dev); + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; unsigned int val; int error; @@ -1466,7 +1446,7 @@ static ssize_t rx_enable_store(struct device *dev, mutex_lock(&iqs269->lock); - iqs269->ch_reg[iqs269->ch_num].rx_enable = val; + ch_reg[iqs269->ch_num].rx_enable = val; iqs269->ati_current = false; mutex_unlock(&iqs269->lock); From 44a2a912c75049fa6cb2306ec8bc1276544b0c62 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 May 2021 02:45:15 +0900 Subject: [PATCH 0352/1017] linux/kconfig.h: replace IF_ENABLED() with PTR_IF() in [ Upstream commit 0ab1438bad43d95877f848b7df551bd431680270 ] is included from all the kernel-space source files, including C, assembly, linker scripts. It is intended to contain a minimal set of macros to evaluate CONFIG options. IF_ENABLED() is an intruder here because (x ? y : z) is C code, which should not be included from assembly files or linker scripts. Also, is no longer self-contained because NULL is defined in . Move IF_ENABLED() out to as PTR_IF(). PTF_IF() takes the general boolean expression instead of a CONFIG option so that it fits better in . Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Stable-dep-of: 18ab69c8ca56 ("Input: iqs269a - do not poll during suspend or resume") Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-ingenic.c | 3 +++ include/linux/kernel.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index e0df5ad6741d..4d07c531371c 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -2826,6 +2827,8 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) return 0; } +#define IF_ENABLED(cfg, ptr) PTR_IF(IS_ENABLED(cfg), (ptr)) + static const struct of_device_id ingenic_pinctrl_of_match[] = { { .compatible = "ingenic,jz4740-pinctrl", .data = &jz4740_chip_info }, { .compatible = "ingenic,jz4725b-pinctrl", .data = &jz4725b_chip_info }, diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 394f10fc29aa..66948e1bf4fa 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -47,6 +47,8 @@ */ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) +#define PTR_IF(cond, ptr) ((cond) ? (ptr) : NULL) + #define u64_to_user_ptr(x) ( \ { \ typecheck(u64, (x)); \ From 7beb9b4538e785a72061a4cff9afa18d77b943f4 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Fri, 23 Dec 2022 17:40:17 +0300 Subject: [PATCH 0353/1017] clk: renesas: cpg-mssr: Fix use after free if cpg_mssr_common_init() failed [ Upstream commit fbfd614aeaa2853c2c575299dfe2458db8eff67e ] If cpg_mssr_common_init() fails after assigning priv to global variable cpg_mssr_priv, it deallocates priv, but cpg_mssr_priv keeps dangling pointer that potentially can be used later. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 1f7db7bbf031 ("clk: renesas: cpg-mssr: Add early clock support") Signed-off-by: Alexey Khoroshilov Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/1671806417-32623-1-git-send-email-khoroshilov@ispras.ru Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 94db88370337..12e5a7881977 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -960,7 +960,6 @@ static int __init cpg_mssr_common_init(struct device *dev, goto out_err; } - cpg_mssr_priv = priv; priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; @@ -990,6 +989,8 @@ static int __init cpg_mssr_common_init(struct device *dev, if (error) goto out_err; + cpg_mssr_priv = priv; + return 0; out_err: From 092f17eca84be0f0b7bd9dc70a9e3bd9e93e3329 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jan 2023 09:23:34 +0100 Subject: [PATCH 0354/1017] clk: renesas: cpg-mssr: Remove superfluous check in resume code [ Upstream commit 1c052043c79af5f70e80e2acd4dd70904ae08666 ] When the code flow arrives at printing the error message in cpg_mssr_resume_noirq(), we know for sure that we are not running on an RZ/A Soc, as the code checked for that before. Fixes: ace342097768e35f ("clk: renesas: cpg-mssr: Fix STBCR suspend/resume handling") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/144a3e66d748c0c17f3524ac8fa6ece5bf5b6f1e.1673425314.git.geert+renesas@glider.be Signed-off-by: Sasha Levin --- drivers/clk/renesas/renesas-cpg-mssr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 12e5a7881977..a5a68e1e7549 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -914,9 +914,8 @@ static int cpg_mssr_resume_noirq(struct device *dev) } if (!i) - dev_warn(dev, "Failed to enable %s%u[0x%x]\n", - priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? - "STB" : "SMSTP", reg, oldval & mask); + dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg, + oldval & mask); } return 0; From 092effd9f99282dbc936b9597dfec0e8d8cb66fa Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 4 Jan 2023 19:00:29 +0800 Subject: [PATCH 0355/1017] clk: imx: avoid memory leak [ Upstream commit f4419db4086e8c31821da14140e81498516a3c75 ] In case imx_register_uart_clocks return early, the imx_uart_clocks memory will be no freed. So execute kfree always to avoid memory leak. Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout") Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Signed-off-by: Abel Vesa Link: https://lore.kernel.org/r/20230104110032.1220721-2-peng.fan@oss.nxp.com Signed-off-by: Sasha Levin --- drivers/clk/imx/clk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 7cc669934253..d4cf0c7045ab 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -201,9 +201,10 @@ static int __init imx_clk_disable_uart(void) clk_disable_unprepare(imx_uart_clocks[i]); clk_put(imx_uart_clocks[i]); } - kfree(imx_uart_clocks); } + kfree(imx_uart_clocks); + return 0; } late_initcall_sync(imx_clk_disable_uart); From 7f2034b9b0610c0fa1cc623287c315de70faec9f Mon Sep 17 00:00:00 2001 From: Luca Ellero Date: Thu, 26 Jan 2023 11:52:25 +0100 Subject: [PATCH 0356/1017] Input: ads7846 - don't report pressure for ads7845 [ Upstream commit d50584d783313c8b05b84d0b07a2142f1bde46dd ] ADS7845 doesn't support pressure. Avoid the following error reported by libinput-list-devices: "ADS7845 Touchscreen: kernel bug: device has min == max on ABS_PRESSURE". Fixes: ffa458c1bd9b ("spi: ads7846 driver") Signed-off-by: Luca Ellero Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230126105227.47648-2-l.ellero@asem.it Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/touchscreen/ads7846.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index ff97897feaf2..370e0dbc02de 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1381,8 +1381,9 @@ static int ads7846_probe(struct spi_device *spi) pdata->y_min ? : 0, pdata->y_max ? : MAX_12BIT, 0, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, - pdata->pressure_min, pdata->pressure_max, 0, 0); + if (ts->model != 7845) + input_set_abs_params(input_dev, ABS_PRESSURE, + pdata->pressure_min, pdata->pressure_max, 0, 0); /* * Parse common framework properties. Must be done here to ensure the From a6c43844462ec89b6fe796ba91614f7f9f280fc2 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 11 Nov 2020 16:39:05 -0800 Subject: [PATCH 0357/1017] Input: ads7846 - convert to full duplex [ Upstream commit 9c9509717b53e701469493a8d87ed42c7d782502 ] Starting with 3eac5c7e44f3 ("Input: ads7846 - extend the driver for ads7845 controller support"), the ads7845 was partially converted to full duplex mode. Since it is not touchscreen controller specific, it is better to extend this conversion to cover entire driver. This will reduce CPU load and make driver more readable. Signed-off-by: Oleksij Rempel Link: https://lore.kernel.org/r/20201110085041.16303-2-o.rempel@pengutronix.de Signed-off-by: Dmitry Torokhov Stable-dep-of: 13f82ca3878d ("Input: ads7846 - always set last command to PWRDOWN") Signed-off-by: Sasha Levin --- drivers/input/touchscreen/ads7846.c | 192 +++++++++------------------- 1 file changed, 62 insertions(+), 130 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 370e0dbc02de..04ca0e13acd3 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -63,19 +63,26 @@ /* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) -struct ts_event { +struct ads7846_buf { + u8 cmd; /* - * For portability, we can't read 12 bit values using SPI (which - * would make the controller deliver them as native byte order u16 - * with msbs zeroed). Instead, we read them as two 8-bit values, - * *** WHICH NEED BYTESWAPPING *** and range adjustment. + * This union is a temporary hack. The driver does an in-place + * endianness conversion. This will be cleaned up in the next + * patch. */ - u16 x; - u16 y; - u16 z1, z2; - bool ignore; - u8 x_buf[3]; - u8 y_buf[3]; + union { + __be16 data_be16; + u16 data; + }; +} __packed; + + +struct ts_event { + bool ignore; + struct ads7846_buf x; + struct ads7846_buf y; + struct ads7846_buf z1; + struct ads7846_buf z2; }; /* @@ -84,11 +91,12 @@ struct ts_event { * systems where main memory is not DMA-coherent (most non-x86 boards). */ struct ads7846_packet { - u8 read_x, read_y, read_z1, read_z2, pwrdown; - u16 dummy; /* for the pwrdown read */ - struct ts_event tc; - /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */ - u8 read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3]; + struct ts_event tc; + struct ads7846_buf read_x_cmd; + struct ads7846_buf read_y_cmd; + struct ads7846_buf read_z1_cmd; + struct ads7846_buf read_z2_cmd; + struct ads7846_buf pwrdown_cmd; }; struct ads7846 { @@ -687,16 +695,9 @@ static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) int value; struct spi_transfer *t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); + struct ads7846_buf *buf = t->rx_buf; - if (ts->model == 7845) { - value = be16_to_cpup((__be16 *)&(((char *)t->rx_buf)[1])); - } else { - /* - * adjust: on-wire is a must-ignore bit, a BE12 value, then - * padding; built from two 8 bit values written msb-first. - */ - value = be16_to_cpup((__be16 *)t->rx_buf); - } + value = be16_to_cpup(&buf->data_be16); /* enforce ADC output is 12 bits width */ return (value >> 3) & 0xfff; @@ -706,8 +707,9 @@ static void ads7846_update_value(struct spi_message *m, int val) { struct spi_transfer *t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); + struct ads7846_buf *buf = t->rx_buf; - *(u16 *)t->rx_buf = val; + buf->data = val; } static void ads7846_read_state(struct ads7846 *ts) @@ -775,16 +777,14 @@ static void ads7846_report_state(struct ads7846 *ts) * from on-the-wire format as part of debouncing to get stable * readings. */ + x = packet->tc.x.data; + y = packet->tc.y.data; if (ts->model == 7845) { - x = *(u16 *)packet->tc.x_buf; - y = *(u16 *)packet->tc.y_buf; z1 = 0; z2 = 0; } else { - x = packet->tc.x; - y = packet->tc.y; - z1 = packet->tc.z1; - z2 = packet->tc.z2; + z1 = packet->tc.z1.data; + z2 = packet->tc.z2.data; } /* range filtering */ @@ -1002,26 +1002,11 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, spi_message_init(m); m->context = ts; - if (ts->model == 7845) { - packet->read_y_cmd[0] = READ_Y(vref); - packet->read_y_cmd[1] = 0; - packet->read_y_cmd[2] = 0; - x->tx_buf = &packet->read_y_cmd[0]; - x->rx_buf = &packet->tc.y_buf[0]; - x->len = 3; - spi_message_add_tail(x, m); - } else { - /* y- still on; turn on only y+ (and ADC) */ - packet->read_y = READ_Y(vref); - x->tx_buf = &packet->read_y; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &packet->tc.y; - x->len = 2; - spi_message_add_tail(x, m); - } + packet->read_y_cmd.cmd = READ_Y(vref); + x->tx_buf = &packet->read_y_cmd; + x->rx_buf = &packet->tc.y; + x->len = 3; + spi_message_add_tail(x, m); /* * The first sample after switching drivers can be low quality; @@ -1031,15 +1016,11 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, if (pdata->settle_delay_usecs) { x->delay.value = pdata->settle_delay_usecs; x->delay.unit = SPI_DELAY_UNIT_USECS; - x++; - x->tx_buf = &packet->read_y; - x->len = 1; - spi_message_add_tail(x, m); - x++; + x->tx_buf = &packet->read_y_cmd; x->rx_buf = &packet->tc.y; - x->len = 2; + x->len = 3; spi_message_add_tail(x, m); } @@ -1048,28 +1029,13 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, spi_message_init(m); m->context = ts; - if (ts->model == 7845) { - x++; - packet->read_x_cmd[0] = READ_X(vref); - packet->read_x_cmd[1] = 0; - packet->read_x_cmd[2] = 0; - x->tx_buf = &packet->read_x_cmd[0]; - x->rx_buf = &packet->tc.x_buf[0]; - x->len = 3; - spi_message_add_tail(x, m); - } else { - /* turn y- off, x+ on, then leave in lowpower */ - x++; - packet->read_x = READ_X(vref); - x->tx_buf = &packet->read_x; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &packet->tc.x; - x->len = 2; - spi_message_add_tail(x, m); - } + /* turn y- off, x+ on, then leave in lowpower */ + x++; + packet->read_x_cmd.cmd = READ_X(vref); + x->tx_buf = &packet->read_x_cmd; + x->rx_buf = &packet->tc.x; + x->len = 3; + spi_message_add_tail(x, m); /* ... maybe discard first sample ... */ if (pdata->settle_delay_usecs) { @@ -1077,13 +1043,9 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, x->delay.unit = SPI_DELAY_UNIT_USECS; x++; - x->tx_buf = &packet->read_x; - x->len = 1; - spi_message_add_tail(x, m); - - x++; + x->tx_buf = &packet->read_x_cmd; x->rx_buf = &packet->tc.x; - x->len = 2; + x->len = 3; spi_message_add_tail(x, m); } @@ -1095,14 +1057,10 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, m->context = ts; x++; - packet->read_z1 = READ_Z1(vref); - x->tx_buf = &packet->read_z1; - x->len = 1; - spi_message_add_tail(x, m); - - x++; + packet->read_z1_cmd.cmd = READ_Z1(vref); + x->tx_buf = &packet->read_z1_cmd; x->rx_buf = &packet->tc.z1; - x->len = 2; + x->len = 3; spi_message_add_tail(x, m); /* ... maybe discard first sample ... */ @@ -1111,13 +1069,9 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, x->delay.unit = SPI_DELAY_UNIT_USECS; x++; - x->tx_buf = &packet->read_z1; - x->len = 1; - spi_message_add_tail(x, m); - - x++; + x->tx_buf = &packet->read_z1_cmd; x->rx_buf = &packet->tc.z1; - x->len = 2; + x->len = 3; spi_message_add_tail(x, m); } @@ -1127,14 +1081,10 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, m->context = ts; x++; - packet->read_z2 = READ_Z2(vref); - x->tx_buf = &packet->read_z2; - x->len = 1; - spi_message_add_tail(x, m); - - x++; + packet->read_z2_cmd.cmd = READ_Z2(vref); + x->tx_buf = &packet->read_z2_cmd; x->rx_buf = &packet->tc.z2; - x->len = 2; + x->len = 3; spi_message_add_tail(x, m); /* ... maybe discard first sample ... */ @@ -1143,13 +1093,9 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, x->delay.unit = SPI_DELAY_UNIT_USECS; x++; - x->tx_buf = &packet->read_z2; - x->len = 1; - spi_message_add_tail(x, m); - - x++; + x->tx_buf = &packet->read_z2_cmd; x->rx_buf = &packet->tc.z2; - x->len = 2; + x->len = 3; spi_message_add_tail(x, m); } } @@ -1160,24 +1106,10 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, spi_message_init(m); m->context = ts; - if (ts->model == 7845) { - x++; - packet->pwrdown_cmd[0] = PWRDOWN; - packet->pwrdown_cmd[1] = 0; - packet->pwrdown_cmd[2] = 0; - x->tx_buf = &packet->pwrdown_cmd[0]; - x->len = 3; - } else { - x++; - packet->pwrdown = PWRDOWN; - x->tx_buf = &packet->pwrdown; - x->len = 1; - spi_message_add_tail(x, m); - - x++; - x->rx_buf = &packet->dummy; - x->len = 2; - } + x++; + packet->pwrdown_cmd.cmd = PWRDOWN; + x->tx_buf = &packet->pwrdown_cmd; + x->len = 3; CS_CHANGE(*x); spi_message_add_tail(x, m); From d247f3527b314d2b197b9cea5615edeaa488bfa9 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 20 Jan 2021 23:18:28 -0800 Subject: [PATCH 0358/1017] Input: ads7846 - convert to one message [ Upstream commit 6965eece2a89c3f1d00881c6052ee1e987870c08 ] Convert multiple full duplex transfers in to a single transfer to reduce CPU load. Current driver version support following filtering modes: - ads7846_no_filter() - not filtered - ads7846_debounce_filter() - driver specific debounce filter - pdata->filter - platform specific debounce filter (do any platform provides such filter?) Without filter this HW is not really usable, since the physic of resistive touchscreen can provide some bounce effects. With driver internal filter, we have constant amount of retries + debounce retries if some anomaly was detected. High amount of tiny SPI transfers is the primer reason of high CPU load and interrupt frequency. This patch create one SPI transfer with all fields and not optional retires. If bounce anomaly was detected, we will make more transfer if needed. Without this patch, we will get about 10% CPU load on iMX6S on pen-down event. For example by holding stylus on the screen. With this patch, depending in the amount of retries, the CPU load will be 1% with "ti,debounce-rep = <3>". One buffer transfer allows us to use PIO FIFO or DMA engine, depending on the platform. Signed-off-by: Oleksij Rempel Link: https://lore.kernel.org/r/20201110085041.16303-3-o.rempel@pengutronix.de Signed-off-by: Dmitry Torokhov Stable-dep-of: 13f82ca3878d ("Input: ads7846 - always set last command to PWRDOWN") Signed-off-by: Sasha Levin --- drivers/input/touchscreen/ads7846.c | 376 ++++++++++++++-------------- 1 file changed, 193 insertions(+), 183 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 04ca0e13acd3..0610fab5ed93 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -65,24 +65,13 @@ struct ads7846_buf { u8 cmd; - /* - * This union is a temporary hack. The driver does an in-place - * endianness conversion. This will be cleaned up in the next - * patch. - */ - union { - __be16 data_be16; - u16 data; - }; + __be16 data; } __packed; - -struct ts_event { - bool ignore; - struct ads7846_buf x; - struct ads7846_buf y; - struct ads7846_buf z1; - struct ads7846_buf z2; +struct ads7846_buf_layout { + unsigned int offset; + unsigned int count; + unsigned int skip; }; /* @@ -91,12 +80,18 @@ struct ts_event { * systems where main memory is not DMA-coherent (most non-x86 boards). */ struct ads7846_packet { - struct ts_event tc; - struct ads7846_buf read_x_cmd; - struct ads7846_buf read_y_cmd; - struct ads7846_buf read_z1_cmd; - struct ads7846_buf read_z2_cmd; + unsigned int count; + unsigned int count_skip; + unsigned int cmds; + unsigned int last_cmd_idx; + struct ads7846_buf_layout l[5]; + struct ads7846_buf *rx; + struct ads7846_buf *tx; + struct ads7846_buf pwrdown_cmd; + + bool ignore; + u16 x, y, z1, z2; }; struct ads7846 { @@ -195,7 +190,6 @@ struct ads7846 { #define READ_Y(vref) (READ_12BIT_DFR(y, 1, vref)) #define READ_Z1(vref) (READ_12BIT_DFR(z1, 1, vref)) #define READ_Z2(vref) (READ_12BIT_DFR(z2, 1, vref)) - #define READ_X(vref) (READ_12BIT_DFR(x, 1, vref)) #define PWRDOWN (READ_12BIT_DFR(y, 0, 0)) /* LAST */ @@ -208,6 +202,21 @@ struct ads7846 { #define REF_ON (READ_12BIT_DFR(x, 1, 1)) #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) +/* Order commands in the most optimal way to reduce Vref switching and + * settling time: + * Measure: X; Vref: X+, X-; IN: Y+ + * Measure: Y; Vref: Y+, Y-; IN: X+ + * Measure: Z1; Vref: Y+, X-; IN: X+ + * Measure: Z2; Vref: Y+, X-; IN: Y- + */ +enum ads7846_cmds { + ADS7846_X, + ADS7846_Y, + ADS7846_Z1, + ADS7846_Z2, + ADS7846_PWDOWN, +}; + static int get_pendown_state(struct ads7846 *ts) { if (ts->get_pendown_state) @@ -690,26 +699,109 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val) return ADS7846_FILTER_OK; } -static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) +static int ads7846_get_value(struct ads7846_buf *buf) { int value; - struct spi_transfer *t = - list_entry(m->transfers.prev, struct spi_transfer, transfer_list); - struct ads7846_buf *buf = t->rx_buf; - value = be16_to_cpup(&buf->data_be16); + value = be16_to_cpup(&buf->data); /* enforce ADC output is 12 bits width */ return (value >> 3) & 0xfff; } -static void ads7846_update_value(struct spi_message *m, int val) +static void ads7846_set_cmd_val(struct ads7846 *ts, enum ads7846_cmds cmd_idx, + u16 val) { - struct spi_transfer *t = - list_entry(m->transfers.prev, struct spi_transfer, transfer_list); - struct ads7846_buf *buf = t->rx_buf; + struct ads7846_packet *packet = ts->packet; - buf->data = val; + switch (cmd_idx) { + case ADS7846_Y: + packet->y = val; + break; + case ADS7846_X: + packet->x = val; + break; + case ADS7846_Z1: + packet->z1 = val; + break; + case ADS7846_Z2: + packet->z2 = val; + break; + default: + WARN_ON_ONCE(1); + } +} + +static u8 ads7846_get_cmd(enum ads7846_cmds cmd_idx, int vref) +{ + switch (cmd_idx) { + case ADS7846_Y: + return READ_Y(vref); + case ADS7846_X: + return READ_X(vref); + + /* 7846 specific commands */ + case ADS7846_Z1: + return READ_Z1(vref); + case ADS7846_Z2: + return READ_Z2(vref); + case ADS7846_PWDOWN: + return PWRDOWN; + default: + WARN_ON_ONCE(1); + } + + return 0; +} + +static bool ads7846_cmd_need_settle(enum ads7846_cmds cmd_idx) +{ + switch (cmd_idx) { + case ADS7846_X: + case ADS7846_Y: + case ADS7846_Z1: + case ADS7846_Z2: + return true; + case ADS7846_PWDOWN: + return false; + default: + WARN_ON_ONCE(1); + } + + return false; +} + +static int ads7846_filter(struct ads7846 *ts) +{ + struct ads7846_packet *packet = ts->packet; + int action; + int val; + unsigned int cmd_idx, b; + + packet->ignore = false; + for (cmd_idx = packet->last_cmd_idx; cmd_idx < packet->cmds - 1; cmd_idx++) { + struct ads7846_buf_layout *l = &packet->l[cmd_idx]; + + packet->last_cmd_idx = cmd_idx; + + for (b = l->skip; b < l->count; b++) { + val = ads7846_get_value(&packet->rx[l->offset + b]); + + action = ts->filter(ts->filter_data, cmd_idx, &val); + if (action == ADS7846_FILTER_REPEAT) { + if (b == l->count - 1) + return -EAGAIN; + } else if (action == ADS7846_FILTER_OK) { + ads7846_set_cmd_val(ts, cmd_idx, val); + break; + } else { + packet->ignore = true; + return 0; + } + } + } + + return 0; } static void ads7846_read_state(struct ads7846 *ts) @@ -717,52 +809,26 @@ static void ads7846_read_state(struct ads7846 *ts) struct ads7846_packet *packet = ts->packet; struct spi_message *m; int msg_idx = 0; - int val; - int action; int error; - while (msg_idx < ts->msg_count) { + packet->last_cmd_idx = 0; + while (true) { ts->wait_for_sync(); m = &ts->msg[msg_idx]; error = spi_sync(ts->spi, m); if (error) { dev_err(&ts->spi->dev, "spi_sync --> %d\n", error); - packet->tc.ignore = true; + packet->ignore = true; return; } - /* - * Last message is power down request, no need to convert - * or filter the value. - */ - if (msg_idx < ts->msg_count - 1) { + error = ads7846_filter(ts); + if (error) + continue; - val = ads7846_get_value(ts, m); - - action = ts->filter(ts->filter_data, msg_idx, &val); - switch (action) { - case ADS7846_FILTER_REPEAT: - continue; - - case ADS7846_FILTER_IGNORE: - packet->tc.ignore = true; - msg_idx = ts->msg_count - 1; - continue; - - case ADS7846_FILTER_OK: - ads7846_update_value(m, val); - packet->tc.ignore = false; - msg_idx++; - break; - - default: - BUG(); - } - } else { - msg_idx++; - } + return; } } @@ -772,19 +838,14 @@ static void ads7846_report_state(struct ads7846 *ts) unsigned int Rt; u16 x, y, z1, z2; - /* - * ads7846_get_value() does in-place conversion (including byte swap) - * from on-the-wire format as part of debouncing to get stable - * readings. - */ - x = packet->tc.x.data; - y = packet->tc.y.data; + x = packet->x; + y = packet->y; if (ts->model == 7845) { z1 = 0; z2 = 0; } else { - z1 = packet->tc.z1.data; - z2 = packet->tc.z2.data; + z1 = packet->z1; + z2 = packet->z2; } /* range filtering */ @@ -817,9 +878,9 @@ static void ads7846_report_state(struct ads7846 *ts) * the maximum. Don't report it to user space, repeat at least * once more the measurement */ - if (packet->tc.ignore || Rt > ts->pressure_max) { + if (packet->ignore || Rt > ts->pressure_max) { dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", - packet->tc.ignore, Rt); + packet->ignore, Rt); return; } @@ -980,13 +1041,59 @@ static int ads7846_setup_pendown(struct spi_device *spi, * Set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ -static void ads7846_setup_spi_msg(struct ads7846 *ts, +static int ads7846_setup_spi_msg(struct ads7846 *ts, const struct ads7846_platform_data *pdata) { struct spi_message *m = &ts->msg[0]; struct spi_transfer *x = ts->xfer; struct ads7846_packet *packet = ts->packet; int vref = pdata->keep_vref_on; + unsigned int count, offset = 0; + unsigned int cmd_idx, b; + unsigned long time; + size_t size = 0; + + /* time per bit */ + time = NSEC_PER_SEC / ts->spi->max_speed_hz; + + count = pdata->settle_delay_usecs * NSEC_PER_USEC / time; + packet->count_skip = DIV_ROUND_UP(count, 24); + + if (ts->debounce_max && ts->debounce_rep) + /* ads7846_debounce_filter() is making ts->debounce_rep + 2 + * reads. So we need to get all samples for normal case. */ + packet->count = ts->debounce_rep + 2; + else + packet->count = 1; + + if (ts->model == 7846) + packet->cmds = 5; /* x, y, z1, z2, pwdown */ + else + packet->cmds = 3; /* x, y, pwdown */ + + for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) { + struct ads7846_buf_layout *l = &packet->l[cmd_idx]; + unsigned int max_count; + + if (ads7846_cmd_need_settle(cmd_idx)) + max_count = packet->count + packet->count_skip; + else + max_count = packet->count; + + l->offset = offset; + offset += max_count; + l->count = max_count; + l->skip = packet->count_skip; + size += sizeof(*packet->tx) * max_count; + } + + packet->tx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL); + if (!packet->tx) + return -ENOMEM; + + packet->rx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL); + if (!packet->rx) + return -ENOMEM; if (ts->model == 7873) { /* @@ -1002,117 +1109,20 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts, spi_message_init(m); m->context = ts; - packet->read_y_cmd.cmd = READ_Y(vref); - x->tx_buf = &packet->read_y_cmd; - x->rx_buf = &packet->tc.y; - x->len = 3; - spi_message_add_tail(x, m); + for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) { + struct ads7846_buf_layout *l = &packet->l[cmd_idx]; + u8 cmd = ads7846_get_cmd(cmd_idx, vref); - /* - * The first sample after switching drivers can be low quality; - * optionally discard it, using a second one after the signals - * have had enough time to stabilize. - */ - if (pdata->settle_delay_usecs) { - x->delay.value = pdata->settle_delay_usecs; - x->delay.unit = SPI_DELAY_UNIT_USECS; - x++; - - x->tx_buf = &packet->read_y_cmd; - x->rx_buf = &packet->tc.y; - x->len = 3; - spi_message_add_tail(x, m); + for (b = 0; b < l->count; b++) + packet->tx[l->offset + b].cmd = cmd; } - ts->msg_count++; - m++; - spi_message_init(m); - m->context = ts; - - /* turn y- off, x+ on, then leave in lowpower */ - x++; - packet->read_x_cmd.cmd = READ_X(vref); - x->tx_buf = &packet->read_x_cmd; - x->rx_buf = &packet->tc.x; - x->len = 3; + x->tx_buf = packet->tx; + x->rx_buf = packet->rx; + x->len = size; spi_message_add_tail(x, m); - /* ... maybe discard first sample ... */ - if (pdata->settle_delay_usecs) { - x->delay.value = pdata->settle_delay_usecs; - x->delay.unit = SPI_DELAY_UNIT_USECS; - - x++; - x->tx_buf = &packet->read_x_cmd; - x->rx_buf = &packet->tc.x; - x->len = 3; - spi_message_add_tail(x, m); - } - - /* turn y+ off, x- on; we'll use formula #2 */ - if (ts->model == 7846) { - ts->msg_count++; - m++; - spi_message_init(m); - m->context = ts; - - x++; - packet->read_z1_cmd.cmd = READ_Z1(vref); - x->tx_buf = &packet->read_z1_cmd; - x->rx_buf = &packet->tc.z1; - x->len = 3; - spi_message_add_tail(x, m); - - /* ... maybe discard first sample ... */ - if (pdata->settle_delay_usecs) { - x->delay.value = pdata->settle_delay_usecs; - x->delay.unit = SPI_DELAY_UNIT_USECS; - - x++; - x->tx_buf = &packet->read_z1_cmd; - x->rx_buf = &packet->tc.z1; - x->len = 3; - spi_message_add_tail(x, m); - } - - ts->msg_count++; - m++; - spi_message_init(m); - m->context = ts; - - x++; - packet->read_z2_cmd.cmd = READ_Z2(vref); - x->tx_buf = &packet->read_z2_cmd; - x->rx_buf = &packet->tc.z2; - x->len = 3; - spi_message_add_tail(x, m); - - /* ... maybe discard first sample ... */ - if (pdata->settle_delay_usecs) { - x->delay.value = pdata->settle_delay_usecs; - x->delay.unit = SPI_DELAY_UNIT_USECS; - - x++; - x->tx_buf = &packet->read_z2_cmd; - x->rx_buf = &packet->tc.z2; - x->len = 3; - spi_message_add_tail(x, m); - } - } - - /* power down */ - ts->msg_count++; - m++; - spi_message_init(m); - m->context = ts; - - x++; - packet->pwrdown_cmd.cmd = PWRDOWN; - x->tx_buf = &packet->pwrdown_cmd; - x->len = 3; - - CS_CHANGE(*x); - spi_message_add_tail(x, m); + return 0; } #ifdef CONFIG_OF From 8d9b9e56c2b618bd3e45fdbdc2cc966d9f5efb50 Mon Sep 17 00:00:00 2001 From: Luca Ellero Date: Thu, 26 Jan 2023 11:52:26 +0100 Subject: [PATCH 0359/1017] Input: ads7846 - always set last command to PWRDOWN [ Upstream commit 13f82ca3878db8284a70ef9711d7f710a31eb562 ] Controllers that report pressure (e.g. ADS7846) use 5 commands and the correct sequence is READ_X, READ_Y, READ_Z1, READ_Z2, PWRDOWN. Controllers that don't report pressure (e.g. ADS7845/ADS7843) use only 3 commands and the correct sequence should be READ_X, READ_Y, PWRDOWN. But the sequence sent was incorrect: READ_X, READ_Y, READ_Z1. Fix this by setting the third (and last) command to PWRDOWN. Fixes: ffa458c1bd9b ("spi: ads7846 driver") Signed-off-by: Luca Ellero Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230126105227.47648-3-l.ellero@asem.it Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/touchscreen/ads7846.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 0610fab5ed93..9f5cc42a567a 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1075,6 +1075,9 @@ static int ads7846_setup_spi_msg(struct ads7846 *ts, struct ads7846_buf_layout *l = &packet->l[cmd_idx]; unsigned int max_count; + if (cmd_idx == packet->cmds - 1) + cmd_idx = ADS7846_PWDOWN; + if (ads7846_cmd_need_settle(cmd_idx)) max_count = packet->count + packet->count_skip; else @@ -1111,7 +1114,12 @@ static int ads7846_setup_spi_msg(struct ads7846 *ts, for (cmd_idx = 0; cmd_idx < packet->cmds; cmd_idx++) { struct ads7846_buf_layout *l = &packet->l[cmd_idx]; - u8 cmd = ads7846_get_cmd(cmd_idx, vref); + u8 cmd; + + if (cmd_idx == packet->cmds - 1) + cmd_idx = ADS7846_PWDOWN; + + cmd = ads7846_get_cmd(cmd_idx, vref); for (b = 0; b < l->count; b++) packet->tx[l->offset + b].cmd = cmd; From 1957c5b5ec4bb492150acb9ce97afcf1b07bc2a8 Mon Sep 17 00:00:00 2001 From: Luca Ellero Date: Thu, 26 Jan 2023 11:52:27 +0100 Subject: [PATCH 0360/1017] Input: ads7846 - don't check penirq immediately for 7845 [ Upstream commit fa9f4275b20ec7b2a8fb05c66362d10b36f9efec ] To discard false readings, one should use "ti,penirq-recheck-delay-usecs". Checking get_pendown_state() at the beginning, most of the time fails causing malfunctioning. Fixes: ffa458c1bd9b ("spi: ads7846 driver") Signed-off-by: Luca Ellero Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230126105227.47648-4-l.ellero@asem.it Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/touchscreen/ads7846.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 9f5cc42a567a..1753288cedde 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -852,14 +852,8 @@ static void ads7846_report_state(struct ads7846 *ts) if (x == MAX_12BIT) x = 0; - if (ts->model == 7843) { + if (ts->model == 7843 || ts->model == 7845) { Rt = ts->pressure_max / 2; - } else if (ts->model == 7845) { - if (get_pendown_state(ts)) - Rt = ts->pressure_max / 2; - else - Rt = 0; - dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt); } else if (likely(x && z1)) { /* compute touch pressure resistance using equation #2 */ Rt = z2; From 241048adcb40246908a486258e98bd190e60d22c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 1 Feb 2023 19:23:04 +0200 Subject: [PATCH 0361/1017] clk: qcom: gpucc-sc7180: fix clk_dis_wait being programmed for CX GDSC [ Upstream commit 658c82caffa042b351f5a1b6325819297a951a04 ] The gdsc_init() function will rewrite the CLK_DIS_WAIT field while registering the GDSC (writing the value 0x2 by default). This will override the setting done in the driver's probe function. Set cx_gdsc.clk_dis_wait_val to 8 to follow the intention of the probe function. Fixes: 745ff069a49c ("clk: qcom: Add graphics clock controller driver for SC7180") Reviewed-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230201172305.993146-1-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/clk/qcom/gpucc-sc7180.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c index 88a739b6fec3..c51114e7e1e6 100644 --- a/drivers/clk/qcom/gpucc-sc7180.c +++ b/drivers/clk/qcom/gpucc-sc7180.c @@ -21,8 +21,6 @@ #define CX_GMU_CBCR_SLEEP_SHIFT 4 #define CX_GMU_CBCR_WAKE_MASK 0xF #define CX_GMU_CBCR_WAKE_SHIFT 8 -#define CLK_DIS_WAIT_SHIFT 12 -#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) enum { P_BI_TCXO, @@ -163,6 +161,7 @@ static struct clk_branch gpu_cc_cxo_clk = { static struct gdsc cx_gdsc = { .gdscr = 0x106c, .gds_hw_ctrl = 0x1540, + .clk_dis_wait_val = 8, .pd = { .name = "cx_gdsc", }, @@ -245,10 +244,6 @@ static int gpu_cc_sc7180_probe(struct platform_device *pdev) value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - /* Configure clk_dis_wait for gpu_cx_gdsc */ - regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, - 8 << CLK_DIS_WAIT_SHIFT); - return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap); } From 15fed9258b844b4cec78f1c38a07ff33af1410c2 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 1 Feb 2023 19:23:05 +0200 Subject: [PATCH 0362/1017] clk: qcom: gpucc-sdm845: fix clk_dis_wait being programmed for CX GDSC [ Upstream commit cb81719e3c1165ef1bc33137dc628f750eed8ea4 ] The gdsc_init() function will rewrite the CLK_DIS_WAIT field while registering the GDSC (writing the value 0x2 by default). This will override the setting done in the driver's probe function. Set cx_gdsc.clk_dis_wait_val to 8 to follow the intention of the probe function. Fixes: 453361cdd757 ("clk: qcom: Add graphics clock controller driver for SDM845") Reviewed-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230201172305.993146-2-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin --- drivers/clk/qcom/gpucc-sdm845.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c index 5663698b306b..658c6ac700e1 100644 --- a/drivers/clk/qcom/gpucc-sdm845.c +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -22,8 +22,6 @@ #define CX_GMU_CBCR_SLEEP_SHIFT 4 #define CX_GMU_CBCR_WAKE_MASK 0xf #define CX_GMU_CBCR_WAKE_SHIFT 8 -#define CLK_DIS_WAIT_SHIFT 12 -#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) enum { P_BI_TCXO, @@ -124,6 +122,7 @@ static struct clk_branch gpu_cc_cxo_clk = { static struct gdsc gpu_cx_gdsc = { .gdscr = 0x106c, .gds_hw_ctrl = 0x1540, + .clk_dis_wait_val = 0x8, .pd = { .name = "gpu_cx_gdsc", }, @@ -196,10 +195,6 @@ static int gpu_cc_sdm845_probe(struct platform_device *pdev) value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - /* Configure clk_dis_wait for gpu_cx_gdsc */ - regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, - 8 << CLK_DIS_WAIT_SHIFT); - return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); } From 4f060379aaf2a05b13bf27cccf93555e640e90a1 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Fri, 20 Jan 2023 10:32:15 +0100 Subject: [PATCH 0363/1017] powerpc/powernv/ioda: Skip unallocated resources when mapping to PE [ Upstream commit e64e71056f323a1e178dccf04d4c0f032d84436c ] pnv_ioda_setup_pe_res() calls opal to map a resource with a PE. However, the code assumes the resource is allocated and it uses the resource address to find out the segment(s) which need to be mapped to the PE. In the unlikely case where the resource hasn't been allocated, the computation for the segment number is garbage, which can lead to invalid memory access and potentially a kernel crash, such as: [ ] pci_bus 0002:02: Configuring PE for bus [ ] pci 0002:02 : [PE# fc] Secondary bus 0x0000000000000002..0x0000000000000002 associated with PE#fc [ ] BUG: Kernel NULL pointer dereference on write at 0x00000000 [ ] Faulting instruction address: 0xc00000000005eac4 [ ] Oops: Kernel access of bad area, sig: 7 [#1] [ ] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV [ ] Modules linked in: [ ] CPU: 12 PID: 1 Comm: swapper/20 Not tainted 5.10.50-openpower1 #2 [ ] NIP: c00000000005eac4 LR: c00000000005ea44 CTR: 0000000030061b9c [ ] REGS: c000200007383650 TRAP: 0300 Not tainted (5.10.50-openpower1) [ ] MSR: 9000000000009033 CR: 44000224 XER: 20040000 [ ] CFAR: c00000000005eaa0 DAR: 0000000000000000 DSISR: 02080000 IRQMASK: 0 [ ] GPR00: c00000000005dd98 c0002000073838e0 c00000000185de00 c000200fff018960 [ ] GPR04: 00000000000000fc 0000000000000003 0000000000000000 0000000000000000 [ ] GPR08: 0000000000000000 0000000000000000 0000000000000000 9000000000001033 [ ] GPR12: 0000000031cb0000 c000000ffffe6a80 c000000000010a58 0000000000000000 [ ] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ ] GPR20: 0000000000000000 0000000000000000 0000000000000000 c00000000711e200 [ ] GPR24: 0000000000000100 c000200009501120 c00020000cee2800 00000000000003ff [ ] GPR28: c000200fff018960 0000000000000000 c000200ffcb7fd00 0000000000000000 [ ] NIP [c00000000005eac4] pnv_ioda_setup_pe_res+0x94/0x1a0 [ ] LR [c00000000005ea44] pnv_ioda_setup_pe_res+0x14/0x1a0 [ ] Call Trace: [ ] [c0002000073838e0] [c00000000005eb98] pnv_ioda_setup_pe_res+0x168/0x1a0 (unreliable) [ ] [c000200007383970] [c00000000005dd98] pnv_pci_ioda_dma_dev_setup+0x43c/0x970 [ ] [c000200007383a60] [c000000000032cdc] pcibios_bus_add_device+0x78/0x18c [ ] [c000200007383aa0] [c00000000028f2bc] pci_bus_add_device+0x28/0xbc [ ] [c000200007383b10] [c00000000028f3a0] pci_bus_add_devices+0x50/0x7c [ ] [c000200007383b50] [c00000000028f3c4] pci_bus_add_devices+0x74/0x7c [ ] [c000200007383b90] [c00000000028f3c4] pci_bus_add_devices+0x74/0x7c [ ] [c000200007383bd0] [c00000000069ad0c] pcibios_init+0xf0/0x104 [ ] [c000200007383c50] [c0000000000106d8] do_one_initcall+0x84/0x1c4 [ ] [c000200007383d20] [c0000000006910b8] kernel_init_freeable+0x264/0x268 [ ] [c000200007383dc0] [c000000000010a68] kernel_init+0x18/0x138 [ ] [c000200007383e20] [c00000000000cbfc] ret_from_kernel_thread+0x5c/0x80 [ ] Instruction dump: [ ] 7f89e840 409d000c 7fbbf840 409c000c 38210090 4848f448 809c002c e95e0120 [ ] 7ba91764 38a00003 57a7043e 38c00000 <7c8a492e> 5484043e e87e0018 4bff23bd Hitting the problem is not that easy. It was seen with a (semi-bogus) PCI device with a class code of 0. The generic PCI framework doesn't allocate resources in such a case. The patch is simply skipping resources which are still flagged with IORESOURCE_UNSET. We don't have the problem with 64-bit mem resources, as the address of the resource is checked to be within the range of the 64-bit mmio window. See pnv_ioda_reserve_dev_m64_pe() and pnv_pci_is_m64(). Reported-by: Andrew Jeffery Fixes: 23e79425fe7c ("powerpc/powernv: Simplify pnv_ioda_setup_pe_seg()") Signed-off-by: Frederic Barrat Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230120093215.19496-1-fbarrat@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/pci-ioda.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 2b4ceb5e6ce4..a1e6dd47743f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2260,7 +2260,8 @@ static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe, int index; int64_t rc; - if (!res || !res->flags || res->start > res->end) + if (!res || !res->flags || res->start > res->end || + res->flags & IORESOURCE_UNSET) return; if (res->flags & IORESOURCE_IO) { From 831a2d8de1d605be23f3afb0caa4690a5bfc3bfb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 3 Jan 2023 17:23:30 +0800 Subject: [PATCH 0364/1017] clk: Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled() [ Upstream commit 79200d5851c8e7179f68a4a6f162d8f1bde4986f ] In the previous commits that added CLK_OPS_PARENT_ENABLE, support for this flag was only added to rate change operations (rate setting and reparent) and disabling unused subtree. It was not added to the clock gate related operations. Any hardware driver that needs it for these operations will either see bogus results, or worse, hang. This has been seen on MT8192 and MT8195, where the imp_ii2_* clk drivers set this, but dumping debugfs clk_summary would cause it to hang. Prepare parent on prepare and enable parent on enable dependencies are already handled automatically by the core as part of its sequencing. Whether the case for "enable parent on prepare" should be supported by this flag or not is not clear, and thus ignored for now. This change solely fixes the handling of clk_core_is_enabled, i.e. enabling the parent clock when reading the hardware state. Unfortunately clk_core_is_enabled is called in a variety of places, sometimes with the enable clock already held. To avoid deadlocking, the core will ignore readouts and just return false if CLK_OPS_PARENT_ENABLE is set but the parent isn't currently enabled. Fixes: fc8726a2c021 ("clk: core: support clocks which requires parents enable (part 2)") Fixes: a4b3518d146f ("clk: core: support clocks which requires parents enable (part 1)") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20230103092330.494102-1-wenst@chromium.org Tested-by: AngeloGioacchino Del Regno Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/clk.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b355d3d40f63..3575afe16a57 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -251,6 +251,17 @@ static bool clk_core_is_enabled(struct clk_core *core) } } + /* + * This could be called with the enable lock held, or from atomic + * context. If the parent isn't enabled already, we can't do + * anything here. We can also assume this clock isn't enabled. + */ + if ((core->flags & CLK_OPS_PARENT_ENABLE) && core->parent) + if (!clk_core_is_enabled(core->parent)) { + ret = false; + goto done; + } + ret = core->ops->is_enabled(core->hw); done: if (core->rpm_enabled) From 9626f83a6ec72caceeaa22ffe400d746cf2ccfff Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 10 Feb 2023 12:41:50 -0600 Subject: [PATCH 0365/1017] powerpc/perf/hv-24x7: add missing RTAS retry status handling [ Upstream commit cc4b26eab1859fa1a70711872caaf6414809973f ] The ibm,get-system-parameter RTAS function may return -2 or 990x, which indicate that the caller should try again. read_24x7_sys_info() ignores this, allowing transient failures in reporting processor module information. Move the RTAS call into a coventional rtas_busy_delay()-based loop, along with the parsing of results on success. Signed-off-by: Nathan Lynch Fixes: 8ba214267382 ("powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get processor details") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-2-26929c8cce78@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/perf/hv-24x7.c | 42 ++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 6e7e820508df..1cd2351d241e 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -79,9 +79,8 @@ static u32 phys_coresperchip; /* Physical cores per chip */ */ void read_24x7_sys_info(void) { - int call_status, len, ntypes; - - spin_lock(&rtas_data_buf_lock); + const s32 token = rtas_token("ibm,get-system-parameter"); + int call_status; /* * Making system parameter: chips and sockets and cores per chip @@ -91,32 +90,27 @@ void read_24x7_sys_info(void) phys_chipspersocket = 1; phys_coresperchip = 1; - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, - NULL, - PROCESSOR_MODULE_INFO, - __pa(rtas_data_buf), - RTAS_DATA_BUF_SIZE); + do { + spin_lock(&rtas_data_buf_lock); + call_status = rtas_call(token, 3, 1, NULL, PROCESSOR_MODULE_INFO, + __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE); + if (call_status == 0) { + int ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]); + int len = be16_to_cpup((__be16 *)&rtas_data_buf[0]); + + if (len >= 8 && ntypes != 0) { + phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]); + phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]); + phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]); + } + } + spin_unlock(&rtas_data_buf_lock); + } while (rtas_busy_delay(call_status)); if (call_status != 0) { pr_err("Error calling get-system-parameter %d\n", call_status); - } else { - len = be16_to_cpup((__be16 *)&rtas_data_buf[0]); - if (len < 8) - goto out; - - ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]); - - if (!ntypes) - goto out; - - phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]); - phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]); - phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]); } - -out: - spin_unlock(&rtas_data_buf_lock); } /* Domains for which more than one result element are returned for each event. */ From df995aef6400fc5f854ea892bb57760f85f360ee Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 10 Feb 2023 12:41:51 -0600 Subject: [PATCH 0366/1017] powerpc/pseries/lpar: add missing RTAS retry status handling [ Upstream commit daa8ab59044610aa8ef2ee45a6c157b5e11635e9 ] The ibm,get-system-parameter RTAS function may return -2 or 990x, which indicate that the caller should try again. pseries_lpar_read_hblkrm_characteristics() ignores this, making it possible to incorrectly detect TLB block invalidation characteristics at boot. Move the RTAS call into a coventional rtas_busy_delay()-based loop. Signed-off-by: Nathan Lynch Fixes: 1211ee61b4a8 ("powerpc/pseries: Read TLB Block Invalidate Characteristics") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-3-26929c8cce78@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/pseries/lpar.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 1c3ac0f66336..115d196560b8 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -1433,22 +1433,22 @@ static inline void __init check_lp_set_hblkrm(unsigned int lp, void __init pseries_lpar_read_hblkrm_characteristics(void) { + const s32 token = rtas_token("ibm,get-system-parameter"); unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH]; int call_status, len, idx, bpsize; if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) return; - spin_lock(&rtas_data_buf_lock); - memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, - NULL, - SPLPAR_TLB_BIC_TOKEN, - __pa(rtas_data_buf), - RTAS_DATA_BUF_SIZE); - memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH); - local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0'; - spin_unlock(&rtas_data_buf_lock); + do { + spin_lock(&rtas_data_buf_lock); + memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); + call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN, + __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE); + memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH); + local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0'; + spin_unlock(&rtas_data_buf_lock); + } while (rtas_busy_delay(call_status)); if (call_status != 0) { pr_warn("%s %s Error calling get-system-parameter (0x%x)\n", From 7afd768784bd7ae499f151ecd3f27c38ddcf5dc7 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 10 Feb 2023 12:41:52 -0600 Subject: [PATCH 0367/1017] powerpc/pseries/lparcfg: add missing RTAS retry status handling [ Upstream commit 5d08633e5f6564b60f1cbe09af3af40a74d66431 ] The ibm,get-system-parameter RTAS function may return -2 or 990x, which indicate that the caller should try again. lparcfg's parse_system_parameter_string() ignores this, making it possible to intermittently report incorrect SPLPAR characteristics. Move the RTAS call into a coventional rtas_busy_delay()-based loop. Signed-off-by: Nathan Lynch Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-4-26929c8cce78@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/pseries/lparcfg.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index e278390ab28d..d3517e498512 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -322,6 +322,7 @@ static void parse_mpp_x_data(struct seq_file *m) */ static void parse_system_parameter_string(struct seq_file *m) { + const s32 token = rtas_token("ibm,get-system-parameter"); int call_status; unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); @@ -331,16 +332,15 @@ static void parse_system_parameter_string(struct seq_file *m) return; } - spin_lock(&rtas_data_buf_lock); - memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH); - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, - NULL, - SPLPAR_CHARACTERISTICS_TOKEN, - __pa(rtas_data_buf), - RTAS_DATA_BUF_SIZE); - memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); - local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; - spin_unlock(&rtas_data_buf_lock); + do { + spin_lock(&rtas_data_buf_lock); + memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH); + call_status = rtas_call(token, 3, 1, NULL, SPLPAR_CHARACTERISTICS_TOKEN, + __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE); + memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); + local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; + spin_unlock(&rtas_data_buf_lock); + } while (rtas_busy_delay(call_status)); if (call_status != 0) { printk(KERN_INFO From c9a299f2f465697b95a2431c036b43acaed265f9 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 24 Jan 2023 08:04:46 -0600 Subject: [PATCH 0368/1017] powerpc/rtas: make all exports GPL [ Upstream commit 9bce6243848dfd0ff7c2be6e8d82ab9b1e6c7858 ] The first symbol exports of RTAS functions and data came with the (now removed) scanlog driver in 2003: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=f92e361842d5251e50562b09664082dcbd0548bb At the time this was applied, EXPORT_SYMBOL_GPL() was very new, and the exports of rtas_call() etc have remained non-GPL. As new APIs have been added to the RTAS subsystem, their symbol exports have followed the convention set by existing code. However, the historical evidence is that RTAS function exports have been added over time only to satisfy the needs of in-kernel users, and these clients must have fairly intimate knowledge of how the APIs work to use them safely. No out of tree users are known, and future ones seem unlikely. Arguably the default for RTAS symbols should have become EXPORT_SYMBOL_GPL once it was available. Let's make it so now, and exceptions can be evaluated as needed. Signed-off-by: Nathan Lynch Reviewed-by: Laurent Dufour Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230124140448.45938-3-nathanl@linux.ibm.com Stable-dep-of: 836b5b9fcc8e ("powerpc/rtas: ensure 4KB alignment for rtas_data_buf") Signed-off-by: Sasha Levin --- arch/powerpc/kernel/rtas.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 014229c40435..7d0bcc515a05 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -52,10 +52,10 @@ struct rtas_t rtas = { EXPORT_SYMBOL(rtas); DEFINE_SPINLOCK(rtas_data_buf_lock); -EXPORT_SYMBOL(rtas_data_buf_lock); +EXPORT_SYMBOL_GPL(rtas_data_buf_lock); char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; -EXPORT_SYMBOL(rtas_data_buf); +EXPORT_SYMBOL_GPL(rtas_data_buf); unsigned long rtas_rmo_buf; @@ -64,7 +64,7 @@ unsigned long rtas_rmo_buf; * This is done like this so rtas_flash can be a module. */ void (*rtas_flash_term_hook)(int); -EXPORT_SYMBOL(rtas_flash_term_hook); +EXPORT_SYMBOL_GPL(rtas_flash_term_hook); /* RTAS use home made raw locking instead of spin_lock_irqsave * because those can be called from within really nasty contexts @@ -312,7 +312,7 @@ void rtas_progress(char *s, unsigned short hex) spin_unlock(&progress_lock); } -EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */ +EXPORT_SYMBOL_GPL(rtas_progress); /* needed by rtas_flash module */ int rtas_token(const char *service) { @@ -322,7 +322,7 @@ int rtas_token(const char *service) tokp = of_get_property(rtas.dev, service, NULL); return tokp ? be32_to_cpu(*tokp) : RTAS_UNKNOWN_SERVICE; } -EXPORT_SYMBOL(rtas_token); +EXPORT_SYMBOL_GPL(rtas_token); int rtas_service_present(const char *service) { @@ -482,7 +482,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) } return ret; } -EXPORT_SYMBOL(rtas_call); +EXPORT_SYMBOL_GPL(rtas_call); /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. @@ -517,7 +517,7 @@ unsigned int rtas_busy_delay(int status) return ms; } -EXPORT_SYMBOL(rtas_busy_delay); +EXPORT_SYMBOL_GPL(rtas_busy_delay); static int rtas_error_rc(int rtas_rc) { @@ -563,7 +563,7 @@ int rtas_get_power_level(int powerdomain, int *level) return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_get_power_level); +EXPORT_SYMBOL_GPL(rtas_get_power_level); int rtas_set_power_level(int powerdomain, int level, int *setlevel) { @@ -581,7 +581,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_set_power_level); +EXPORT_SYMBOL_GPL(rtas_set_power_level); int rtas_get_sensor(int sensor, int index, int *state) { @@ -599,7 +599,7 @@ int rtas_get_sensor(int sensor, int index, int *state) return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_get_sensor); +EXPORT_SYMBOL_GPL(rtas_get_sensor); int rtas_get_sensor_fast(int sensor, int index, int *state) { @@ -660,7 +660,7 @@ int rtas_set_indicator(int indicator, int index, int new_value) return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_set_indicator); +EXPORT_SYMBOL_GPL(rtas_set_indicator); /* * Ignoring RTAS extended delay From 386cc2af90e94f6b55e5ff19ebdb98cac56fe1ff Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 10 Feb 2023 12:41:54 -0600 Subject: [PATCH 0369/1017] powerpc/rtas: ensure 4KB alignment for rtas_data_buf [ Upstream commit 836b5b9fcc8e09cea7e8a59a070349a00e818308 ] Some RTAS functions that have work area parameters impose alignment requirements on the work area passed to them by the OS. Examples include: - ibm,configure-connector - ibm,update-nodes - ibm,update-properties 4KB is the greatest alignment required by PAPR for such buffers. rtas_data_buf used to have a __page_aligned attribute in the arch/ppc64 days, but that was changed to __cacheline_aligned for unknown reasons by commit 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel"). That works out to 128-byte alignment on ppc64, which isn't right. This was found by inspection and I'm not aware of any real problems caused by this. Either current RTAS implementations don't enforce the alignment constraints, or rtas_data_buf is always being placed at a 4KB boundary by accident (or both, perhaps). Use __aligned(SZ_4K) to ensure the rtas_data_buf has alignment appropriate for all users. Signed-off-by: Nathan Lynch Fixes: 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-6-26929c8cce78@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/rtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 7d0bcc515a05..c2e407a112a2 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -54,7 +54,7 @@ EXPORT_SYMBOL(rtas); DEFINE_SPINLOCK(rtas_data_buf_lock); EXPORT_SYMBOL_GPL(rtas_data_buf_lock); -char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; +char rtas_data_buf[RTAS_DATA_BUF_SIZE] __aligned(SZ_4K); EXPORT_SYMBOL_GPL(rtas_data_buf); unsigned long rtas_rmo_buf; From dfc41e3859152593f8fe843dfbdab303e9b152cc Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Fri, 15 Oct 2021 18:06:27 +1100 Subject: [PATCH 0370/1017] powerpc/eeh: Small refactor of eeh_handle_normal_event() [ Upstream commit 10b34ece132ee46dc4e6459c765d180c422a09fa ] The control flow of eeh_handle_normal_event() is a bit tricky. Break out one of the error handling paths - rather than be in an else block, we'll make it part of the regular body of the function and put a 'goto out;' in the true limb of the if. Signed-off-by: Daniel Axtens Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20211015070628.1331635-1-dja@axtens.net Stable-dep-of: 9efcdaac36e1 ("powerpc/eeh: Set channel state after notifying the drivers") Signed-off-by: Sasha Levin --- arch/powerpc/kernel/eeh_driver.c | 69 ++++++++++++++++---------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 3eff6a4888e7..cb3ac555c944 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -1054,45 +1054,46 @@ void eeh_handle_normal_event(struct eeh_pe *pe) } pr_info("EEH: Recovery successful.\n"); - } else { - /* - * About 90% of all real-life EEH failures in the field - * are due to poorly seated PCI cards. Only 10% or so are - * due to actual, failed cards. - */ - pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n" - "Please try reseating or replacing it\n", - pe->phb->global_number, pe->addr); + goto out; + } - eeh_slot_error_detail(pe, EEH_LOG_PERM); + /* + * About 90% of all real-life EEH failures in the field + * are due to poorly seated PCI cards. Only 10% or so are + * due to actual, failed cards. + */ + pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n" + "Please try reseating or replacing it\n", + pe->phb->global_number, pe->addr); - /* Notify all devices that they're about to go down. */ - eeh_set_channel_state(pe, pci_channel_io_perm_failure); - eeh_set_irq_state(pe, false); - eeh_pe_report("error_detected(permanent failure)", pe, - eeh_report_failure, NULL); + eeh_slot_error_detail(pe, EEH_LOG_PERM); - /* Mark the PE to be removed permanently */ - eeh_pe_state_mark(pe, EEH_PE_REMOVED); + /* Notify all devices that they're about to go down. */ + eeh_set_channel_state(pe, pci_channel_io_perm_failure); + eeh_set_irq_state(pe, false); + eeh_pe_report("error_detected(permanent failure)", pe, + eeh_report_failure, NULL); - /* - * Shut down the device drivers for good. We mark - * all removed devices correctly to avoid access - * the their PCI config any more. - */ - if (pe->type & EEH_PE_VF) { - eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); - eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); - } else { - eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); - eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + /* Mark the PE to be removed permanently */ + eeh_pe_state_mark(pe, EEH_PE_REMOVED); - pci_lock_rescan_remove(); - pci_hp_remove_devices(bus); - pci_unlock_rescan_remove(); - /* The passed PE should no longer be used */ - return; - } + /* + * Shut down the device drivers for good. We mark + * all removed devices correctly to avoid access + * the their PCI config any more. + */ + if (pe->type & EEH_PE_VF) { + eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); + eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + } else { + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); + eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + + pci_lock_rescan_remove(); + pci_hp_remove_devices(bus); + pci_unlock_rescan_remove(); + /* The passed PE should no longer be used */ + return; } out: From 6fc6d29be811b677409c22db1eb27e5d7a42a241 Mon Sep 17 00:00:00 2001 From: Ganesh Goudar Date: Thu, 9 Feb 2023 16:26:49 +0530 Subject: [PATCH 0371/1017] powerpc/eeh: Set channel state after notifying the drivers [ Upstream commit 9efcdaac36e1643a1b7f5337e6143ce142d381b1 ] When a PCI error is encountered 6th time in an hour we set the channel state to perm_failure and notify the driver about the permanent failure. However, after upstream commit 38ddc011478e ("powerpc/eeh: Make permanently failed devices non-actionable"), EEH handler stops calling any routine once the device is marked as permanent failure. This issue can lead to fatal consequences like kernel hang with certain PCI devices. Following log is observed with lpfc driver, with and without this change, Without this change kernel hangs, If PCI error is encountered 6 times for a device in an hour. Without the change EEH: Beginning: 'error_detected(permanent failure)' PCI 0132:60:00.0#600000: EEH: not actionable (1,1,1) PCI 0132:60:00.1#600000: EEH: not actionable (1,1,1) EEH: Finished:'error_detected(permanent failure)' With the change EEH: Beginning: 'error_detected(permanent failure)' EEH: Invoking lpfc->error_detected(permanent failure) EEH: lpfc driver reports: 'disconnect' EEH: Invoking lpfc->error_detected(permanent failure) EEH: lpfc driver reports: 'disconnect' EEH: Finished:'error_detected(permanent failure)' To fix the issue, set channel state to permanent failure after notifying the drivers. Fixes: 38ddc011478e ("powerpc/eeh: Make permanently failed devices non-actionable") Suggested-by: Mahesh Salgaonkar Signed-off-by: Ganesh Goudar Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230209105649.127707-1-ganeshgr@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/eeh_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index cb3ac555c944..665d847ef9b5 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -1069,10 +1069,10 @@ void eeh_handle_normal_event(struct eeh_pe *pe) eeh_slot_error_detail(pe, EEH_LOG_PERM); /* Notify all devices that they're about to go down. */ - eeh_set_channel_state(pe, pci_channel_io_perm_failure); eeh_set_irq_state(pe, false); eeh_pe_report("error_detected(permanent failure)", pe, eeh_report_failure, NULL); + eeh_set_channel_state(pe, pci_channel_io_perm_failure); /* Mark the PE to be removed permanently */ eeh_pe_state_mark(pe, EEH_PE_REMOVED); @@ -1189,10 +1189,10 @@ void eeh_handle_special_event(void) /* Notify all devices to be down */ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); - eeh_set_channel_state(pe, pci_channel_io_perm_failure); eeh_pe_report( "error_detected(permanent failure)", pe, eeh_report_failure, NULL); + eeh_set_channel_state(pe, pci_channel_io_perm_failure); pci_lock_rescan_remove(); list_for_each_entry(hose, &hose_list, list_node) { From 132203ce40d050dd6f09668cab54b4ea70a2ba4a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 17 Feb 2023 12:07:49 -0800 Subject: [PATCH 0372/1017] MIPS: SMP-CPS: fix build error when HOTPLUG_CPU not set [ Upstream commit 6f02e39fa40f16c24e7a5c599a854c0d1682788d ] When MIPS_CPS=y, MIPS_CPS_PM is not set, HOTPLUG_CPU is not set, and KEXEC=y, cps_shutdown_this_cpu() attempts to call cps_pm_enter_state(), which is not built when MIPS_CPS_PM is not set. Conditionally execute the else branch based on CONFIG_HOTPLUG_CPU to remove the build error. This build failure is from a randconfig file. mips-linux-ld: arch/mips/kernel/smp-cps.o: in function `$L162': smp-cps.c:(.text.cps_kexec_nonboot_cpu+0x31c): undefined reference to `cps_pm_enter_state' Fixes: 1447864bee4c ("MIPS: kexec: CPS systems to halt nonboot CPUs") Signed-off-by: Randy Dunlap Cc: Dengcheng Zhu Cc: Paul Burton Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Cc: Sergei Shtylyov Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/kernel/smp-cps.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index dbb3f1fc71ab..f659adb681bc 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -423,9 +423,11 @@ static void cps_shutdown_this_cpu(enum cpu_death death) wmb(); } } else { - pr_debug("Gating power to core %d\n", core); - /* Power down the core */ - cps_pm_enter_state(CPS_PM_POWER_GATED); + if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) { + pr_debug("Gating power to core %d\n", core); + /* Power down the core */ + cps_pm_enter_state(CPS_PM_POWER_GATED); + } } } From bccccd43a06dfea5f5a8295a0cb384d74b90a9b3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 19 Feb 2023 15:15:25 -0800 Subject: [PATCH 0373/1017] MIPS: vpe-mt: drop physical_memsize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 91dc288f4edf0d768e46c2c6d33e0ab703403459 ] When neither LANTIQ nor MIPS_MALTA is set, 'physical_memsize' is not declared. This causes the build to fail with: mips-linux-ld: arch/mips/kernel/vpe-mt.o: in function `vpe_run': arch/mips/kernel/vpe-mt.c:(.text.vpe_run+0x280): undefined reference to `physical_memsize' LANTIQ is not using 'physical_memsize' and MIPS_MALTA's use of it is self-contained in mti-malta/malta-dtshim.c. Use of physical_memsize in vpe-mt.c appears to be unused, so eliminate this loader mode completely and require VPE programs to be compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined. Fixes: 9050d50e2244 ("MIPS: lantiq: Set physical_memsize") Fixes: 1a2a6d7e8816 ("MIPS: APRP: Split VPE loader into separate files.") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Link: https://lore.kernel.org/all/202302030625.2g3E98sY-lkp@intel.com/ Cc: Dengcheng Zhu Cc: John Crispin Cc: Thomas Bogendoerfer Cc: Philippe Mathieu-Daudé Cc: "Steven J. Hill" Cc: Qais Yousef Cc: Yang Yingliang Cc: Hauke Mehrtens Cc: James Hogan Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/include/asm/vpe.h | 1 - arch/mips/kernel/vpe-mt.c | 7 +++---- arch/mips/lantiq/prom.c | 6 ------ 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/mips/include/asm/vpe.h b/arch/mips/include/asm/vpe.h index 80e70dbd1f64..012731546cf6 100644 --- a/arch/mips/include/asm/vpe.h +++ b/arch/mips/include/asm/vpe.h @@ -104,7 +104,6 @@ struct vpe_control { struct list_head tc_list; /* Thread contexts */ }; -extern unsigned long physical_memsize; extern struct vpe_control vpecontrol; extern const struct file_operations vpe_fops; diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c index 9fd7cd48ea1d..496ed8f362f6 100644 --- a/arch/mips/kernel/vpe-mt.c +++ b/arch/mips/kernel/vpe-mt.c @@ -92,12 +92,11 @@ int vpe_run(struct vpe *v) write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); /* - * The sde-kit passes 'memsize' to __start in $a3, so set something - * here... Or set $a3 to zero and define DFLT_STACK_SIZE and - * DFLT_HEAP_SIZE when you compile your program + * We don't pass the memsize here, so VPE programs need to be + * compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined. */ + mttgpr(7, 0); mttgpr(6, v->ntcs); - mttgpr(7, physical_memsize); /* set up VPE1 */ /* diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 3f568f5aae2d..2729a4b63e18 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -22,12 +22,6 @@ DEFINE_SPINLOCK(ebu_lock); EXPORT_SYMBOL_GPL(ebu_lock); -/* - * This is needed by the VPE loader code, just set it to 0 and assume - * that the firmware hardcodes this value to something useful. - */ -unsigned long physical_memsize = 0L; - /* * this struct is filled by the soc specific detection code and holds * information about the specific soc type, revision and name From 4cab7debf3e05a6a2411c1b0192d849190be79a6 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 6 Feb 2023 14:19:56 +0200 Subject: [PATCH 0374/1017] vdpa/mlx5: Don't clear mr struct on destroy MR [ Upstream commit aef24311bd2d8a6d39a80c34f278b0fd1692aed3 ] Clearing the mr struct erases the lock owner and causes warnings to be emitted. It is not required to clear the mr so remove the memset call. Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code") Signed-off-by: Eli Cohen Message-Id: <20230206121956.1149356-1-elic@nvidia.com> Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin --- drivers/vdpa/mlx5/core/mr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c index 32c9925de473..1f94ea46c01a 100644 --- a/drivers/vdpa/mlx5/core/mr.c +++ b/drivers/vdpa/mlx5/core/mr.c @@ -448,7 +448,6 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev) unmap_direct_mr(mvdev, dmr); kfree(dmr); } - memset(mr, 0, sizeof(*mr)); mr->initialized = false; out: mutex_unlock(&mr->mkey_mtx); From b0b84fd32cb48dcb7d617f1abe476533447ef67f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 9 Jan 2023 00:14:02 -0500 Subject: [PATCH 0375/1017] alpha/boot/tools/objstrip: fix the check for ELF header [ Upstream commit 1878787797cbb019eeefe6f905514dcd557302b6 ] Just memcmp() with ELFMAG - that's the normal way to do it in userland code, which that thing is. Besides, that has the benefit of actually building - str_has_prefix() is *NOT* present in . Fixes: 5f14596e55de "alpha: Replace strncmp with str_has_prefix" Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- arch/alpha/boot/tools/objstrip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c index 08b430d25a31..7cf92d172dce 100644 --- a/arch/alpha/boot/tools/objstrip.c +++ b/arch/alpha/boot/tools/objstrip.c @@ -148,7 +148,7 @@ main (int argc, char *argv[]) #ifdef __ELF__ elf = (struct elfhdr *) buf; - if (elf->e_ident[0] == 0x7f && str_has_prefix((char *)elf->e_ident + 1, "ELF")) { + if (memcmp(&elf->e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0) { if (elf->e_type != ET_EXEC) { fprintf(stderr, "%s: %s is not an ELF executable\n", prog_name, inname); From 65e39fdce1fc3f2144844051508a11d913e41fdd Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Tue, 3 Jan 2023 11:59:21 -0600 Subject: [PATCH 0376/1017] Input: iqs269a - do not poll during suspend or resume [ Upstream commit 18ab69c8ca5678324efbeed874b707ce7b2feae1 ] Polling the device while it transitions from automatic to manual power mode switching may keep the device from actually finishing the transition. The process appears to time out depending on the polling rate and the device's core clock frequency. This is ultimately unnecessary in the first place; instead it is sufficient to write the desired mode during initialization, then disable automatic switching at suspend. This eliminates the need to ensure the device is prepared for a manual change and removes the 'suspend_mode' variable. Similarly, polling the device while it transitions from one mode to another under manual control may time out as well. This added step does not appear to be necessary either, so drop it. Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/Y7Rs+eEXlRw4Vq57@nixie71 Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/misc/iqs269a.c | 118 +++++++++-------------------------- 1 file changed, 31 insertions(+), 87 deletions(-) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index 1530efd301c2..814d1a898e7f 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -148,9 +148,6 @@ #define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000) #define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150) -#define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US -#define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US - #define iqs269_irq_wait() usleep_range(200, 250) enum iqs269_local_cap_size { @@ -295,7 +292,6 @@ struct iqs269_private { struct input_dev *keypad; struct input_dev *slider[IQS269_NUM_SL]; unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH]; - unsigned int suspend_mode; unsigned int delay_mult; unsigned int ch_num; bool hall_enable; @@ -767,17 +763,6 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269) iqs269->hall_enable = device_property_present(&client->dev, "azoteq,hall-enable"); - if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode", - &val)) { - if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) { - dev_err(&client->dev, "Invalid suspend mode: %u\n", - val); - return -EINVAL; - } - - iqs269->suspend_mode = val; - } - error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg, sizeof(*sys_reg)); if (error) @@ -1005,6 +990,17 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269) general &= ~IQS269_SYS_SETTINGS_DIS_AUTO; general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK; + if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode", + &val)) { + if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) { + dev_err(&client->dev, "Invalid suspend mode: %u\n", + val); + return -EINVAL; + } + + general |= (val << IQS269_SYS_SETTINGS_PWR_MODE_SHIFT); + } + if (!device_property_read_u32(&client->dev, "azoteq,ulp-update", &val)) { if (val > IQS269_SYS_SETTINGS_ULP_UPDATE_MAX) { @@ -1687,59 +1683,30 @@ static int iqs269_probe(struct i2c_client *client) return error; } +static u16 iqs269_general_get(struct iqs269_private *iqs269) +{ + u16 general = be16_to_cpu(iqs269->sys_reg.general); + + general &= ~IQS269_SYS_SETTINGS_REDO_ATI; + general &= ~IQS269_SYS_SETTINGS_ACK_RESET; + + return general | IQS269_SYS_SETTINGS_DIS_AUTO; +} + static int __maybe_unused iqs269_suspend(struct device *dev) { struct iqs269_private *iqs269 = dev_get_drvdata(dev); struct i2c_client *client = iqs269->client; - unsigned int val; int error; + u16 general = iqs269_general_get(iqs269); - if (!iqs269->suspend_mode) + if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK)) return 0; disable_irq(client->irq); - /* - * Automatic power mode switching must be disabled before the device is - * forced into any particular power mode. In this case, the device will - * transition into normal-power mode. - */ - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, - IQS269_SYS_SETTINGS_DIS_AUTO, ~0); - if (error) - goto err_irq; + error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, general); - /* - * The following check ensures the device has completed its transition - * into normal-power mode before a manual mode switch is performed. - */ - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, - !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK), - IQS269_PWR_MODE_POLL_SLEEP_US, - IQS269_PWR_MODE_POLL_TIMEOUT_US); - if (error) - goto err_irq; - - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, - IQS269_SYS_SETTINGS_PWR_MODE_MASK, - iqs269->suspend_mode << - IQS269_SYS_SETTINGS_PWR_MODE_SHIFT); - if (error) - goto err_irq; - - /* - * This last check ensures the device has completed its transition into - * the desired power mode to prevent any spurious interrupts from being - * triggered after iqs269_suspend has already returned. - */ - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, - (val & IQS269_SYS_FLAGS_PWR_MODE_MASK) - == (iqs269->suspend_mode << - IQS269_SYS_FLAGS_PWR_MODE_SHIFT), - IQS269_PWR_MODE_POLL_SLEEP_US, - IQS269_PWR_MODE_POLL_TIMEOUT_US); - -err_irq: iqs269_irq_wait(); enable_irq(client->irq); @@ -1750,43 +1717,20 @@ static int __maybe_unused iqs269_resume(struct device *dev) { struct iqs269_private *iqs269 = dev_get_drvdata(dev); struct i2c_client *client = iqs269->client; - unsigned int val; int error; + u16 general = iqs269_general_get(iqs269); - if (!iqs269->suspend_mode) + if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK)) return 0; disable_irq(client->irq); - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, - IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0); - if (error) - goto err_irq; + error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, + general & ~IQS269_SYS_SETTINGS_PWR_MODE_MASK); + if (!error) + error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, + general & ~IQS269_SYS_SETTINGS_DIS_AUTO); - /* - * This check ensures the device has returned to normal-power mode - * before automatic power mode switching is re-enabled. - */ - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, - !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK), - IQS269_PWR_MODE_POLL_SLEEP_US, - IQS269_PWR_MODE_POLL_TIMEOUT_US); - if (error) - goto err_irq; - - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, - IQS269_SYS_SETTINGS_DIS_AUTO, 0); - if (error) - goto err_irq; - - /* - * This step reports any events that may have been "swallowed" as a - * result of polling PWR_MODE (which automatically acknowledges any - * pending interrupts). - */ - error = iqs269_report(iqs269); - -err_irq: iqs269_irq_wait(); enable_irq(client->irq); From 7e5bc675eb7b3e1e1442dc721e074e3cc02f44d0 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Tue, 3 Jan 2023 11:59:35 -0600 Subject: [PATCH 0377/1017] Input: iqs269a - do not poll during ATI [ Upstream commit b08134eb254db56e9ce8170d9b82f0d7a616b6f8 ] After initial start-up, the driver triggers ATI (calibration) with the newly loaded register configuration in place. Next, the driver polls a register field to ensure ATI completed in a timely fashion and that the device is ready to sense. However, communicating with the device over I2C while ATI is under- way may induce noise in the device and cause ATI to fail. As such, the vendor recommends not to poll the device during ATI. To solve this problem, let the device naturally signal to the host that ATI is complete by way of an interrupt. A completion prevents the device from successfully probing until this happens. As an added benefit, initial switch states are now reported in the interrupt handler at the same time ATI status is checked. As such, duplicate code that reports initial switch states has been removed from iqs269_input_init(). The former logic that scaled ATI timeout and filter settling delay is not carried forward with the new implementation, as it produces overly conservative delays at the lower clock rate. Rather, a single timeout that covers both clock rates is used. The filter settling delay does not happen to be necessary and has been removed as well. Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/Y7RtB2T7AF9rYMjK@nixie71 Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/misc/iqs269a.c | 97 +++++++++++++++++------------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index 814d1a898e7f..8b30c911f789 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -9,6 +9,7 @@ * axial sliders presented by the device. */ +#include #include #include #include @@ -144,10 +145,6 @@ #define IQS269_NUM_CH 8 #define IQS269_NUM_SL 2 -#define IQS269_ATI_POLL_SLEEP_US (iqs269->delay_mult * 10000) -#define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000) -#define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150) - #define iqs269_irq_wait() usleep_range(200, 250) enum iqs269_local_cap_size { @@ -289,10 +286,10 @@ struct iqs269_private { struct mutex lock; struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)]; struct iqs269_sys_reg sys_reg; + struct completion ati_done; struct input_dev *keypad; struct input_dev *slider[IQS269_NUM_SL]; unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH]; - unsigned int delay_mult; unsigned int ch_num; bool hall_enable; bool ati_current; @@ -973,13 +970,8 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269) general = be16_to_cpu(sys_reg->general); - if (device_property_present(&client->dev, "azoteq,clk-div")) { + if (device_property_present(&client->dev, "azoteq,clk-div")) general |= IQS269_SYS_SETTINGS_CLK_DIV; - iqs269->delay_mult = 4; - } else { - general &= ~IQS269_SYS_SETTINGS_CLK_DIV; - iqs269->delay_mult = 1; - } /* * Configure the device to automatically switch between normal and low- @@ -1036,7 +1028,6 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269) static int iqs269_dev_init(struct iqs269_private *iqs269) { - unsigned int val; int error; mutex_lock(&iqs269->lock); @@ -1052,14 +1043,12 @@ static int iqs269_dev_init(struct iqs269_private *iqs269) if (error) goto err_mutex; - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, - !(val & IQS269_SYS_FLAGS_IN_ATI), - IQS269_ATI_POLL_SLEEP_US, - IQS269_ATI_POLL_TIMEOUT_US); - if (error) - goto err_mutex; + /* + * The following delay gives the device time to deassert its RDY output + * so as to prevent an interrupt from being serviced prematurely. + */ + usleep_range(2000, 2100); - msleep(IQS269_ATI_STABLE_DELAY_MS); iqs269->ati_current = true; err_mutex: @@ -1071,10 +1060,8 @@ err_mutex: static int iqs269_input_init(struct iqs269_private *iqs269) { struct i2c_client *client = iqs269->client; - struct iqs269_flags flags; unsigned int sw_code, keycode; int error, i, j; - u8 dir_mask, state; iqs269->keypad = devm_input_allocate_device(&client->dev); if (!iqs269->keypad) @@ -1087,23 +1074,7 @@ static int iqs269_input_init(struct iqs269_private *iqs269) iqs269->keypad->name = "iqs269a_keypad"; iqs269->keypad->id.bustype = BUS_I2C; - if (iqs269->hall_enable) { - error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS, - &flags, sizeof(flags)); - if (error) { - dev_err(&client->dev, - "Failed to read initial status: %d\n", error); - return error; - } - } - for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) { - dir_mask = flags.states[IQS269_ST_OFFS_DIR]; - if (!iqs269_events[i].dir_up) - dir_mask = ~dir_mask; - - state = flags.states[iqs269_events[i].st_offs] & dir_mask; - sw_code = iqs269->switches[i].code; for (j = 0; j < IQS269_NUM_CH; j++) { @@ -1116,13 +1087,9 @@ static int iqs269_input_init(struct iqs269_private *iqs269) switch (j) { case IQS269_CHx_HALL_ACTIVE: if (iqs269->hall_enable && - iqs269->switches[i].enabled) { + iqs269->switches[i].enabled) input_set_capability(iqs269->keypad, EV_SW, sw_code); - input_report_switch(iqs269->keypad, - sw_code, - state & BIT(j)); - } fallthrough; case IQS269_CHx_HALL_INACTIVE: @@ -1138,14 +1105,6 @@ static int iqs269_input_init(struct iqs269_private *iqs269) } } - input_sync(iqs269->keypad); - - error = input_register_device(iqs269->keypad); - if (error) { - dev_err(&client->dev, "Failed to register keypad: %d\n", error); - return error; - } - for (i = 0; i < IQS269_NUM_SL; i++) { if (!iqs269->sys_reg.slider_select[i]) continue; @@ -1205,6 +1164,9 @@ static int iqs269_report(struct iqs269_private *iqs269) return error; } + if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_IN_ATI) + return 0; + error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x, sizeof(slider_x)); if (error) { @@ -1267,6 +1229,12 @@ static int iqs269_report(struct iqs269_private *iqs269) input_sync(iqs269->keypad); + /* + * The following completion signals that ATI has finished, any initial + * switch states have been reported and the keypad can be registered. + */ + complete_all(&iqs269->ati_done); + return 0; } @@ -1298,6 +1266,9 @@ static ssize_t counts_show(struct device *dev, if (!iqs269->ati_current || iqs269->hall_enable) return -EPERM; + if (!completion_done(&iqs269->ati_done)) + return -EBUSY; + /* * Unsolicited I2C communication prompts the device to assert its RDY * pin, so disable the interrupt line until the operation is finished @@ -1554,7 +1525,9 @@ static ssize_t ati_trigger_show(struct device *dev, { struct iqs269_private *iqs269 = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ati_current); + return scnprintf(buf, PAGE_SIZE, "%u\n", + iqs269->ati_current && + completion_done(&iqs269->ati_done)); } static ssize_t ati_trigger_store(struct device *dev, @@ -1574,6 +1547,7 @@ static ssize_t ati_trigger_store(struct device *dev, return count; disable_irq(client->irq); + reinit_completion(&iqs269->ati_done); error = iqs269_dev_init(iqs269); @@ -1583,6 +1557,10 @@ static ssize_t ati_trigger_store(struct device *dev, if (error) return error; + if (!wait_for_completion_timeout(&iqs269->ati_done, + msecs_to_jiffies(2000))) + return -ETIMEDOUT; + return count; } @@ -1641,6 +1619,7 @@ static int iqs269_probe(struct i2c_client *client) } mutex_init(&iqs269->lock); + init_completion(&iqs269->ati_done); error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info, sizeof(ver_info)); @@ -1676,6 +1655,22 @@ static int iqs269_probe(struct i2c_client *client) return error; } + if (!wait_for_completion_timeout(&iqs269->ati_done, + msecs_to_jiffies(2000))) { + dev_err(&client->dev, "Failed to complete ATI\n"); + return -ETIMEDOUT; + } + + /* + * The keypad may include one or more switches and is not registered + * until ATI is complete and the initial switch states are read. + */ + error = input_register_device(iqs269->keypad); + if (error) { + dev_err(&client->dev, "Failed to register keypad: %d\n", error); + return error; + } + error = devm_device_add_group(&client->dev, &iqs269_attr_group); if (error) dev_err(&client->dev, "Failed to add attributes: %d\n", error); From 0a2e2674f720836e294523cf165deac9ba3b1425 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Tue, 17 Jan 2023 14:28:35 +0530 Subject: [PATCH 0378/1017] remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers [ Upstream commit 57f72170a2b2a362c35bb9407fc844eac5afdec1 ] Any access to the dynamically allocated metadata region by the application processor after assigning it to the remote Q6 will result in a XPU violation. Fix this by replacing the dynamically allocated memory region with a no-map carveout and unmap the modem metadata memory region before passing control to the remote Q6. Reported-and-tested-by: Amit Pundir Fixes: 6c5a9dc2481b ("remoteproc: qcom: Make secure world call for mem ownership switch") Signed-off-by: Sibi Sankar Reviewed-by: Manivannan Sadhasivam Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230117085840.32356-7-quic_sibis@quicinc.com Signed-off-by: Sasha Levin --- drivers/remoteproc/qcom_q6v5_mss.c | 59 +++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 1b3aa84e36e7..3d975ecd9336 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -190,6 +191,9 @@ struct q6v5 { size_t mba_size; size_t dp_size; + phys_addr_t mdata_phys; + size_t mdata_size; + phys_addr_t mpss_phys; phys_addr_t mpss_reloc; size_t mpss_size; @@ -816,15 +820,35 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) if (IS_ERR(metadata)) return PTR_ERR(metadata); - ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); - if (!ptr) { - kfree(metadata); - dev_err(qproc->dev, "failed to allocate mdt buffer\n"); - return -ENOMEM; + if (qproc->mdata_phys) { + if (size > qproc->mdata_size) { + ret = -EINVAL; + dev_err(qproc->dev, "metadata size outside memory range\n"); + goto free_metadata; + } + + phys = qproc->mdata_phys; + ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC); + if (!ptr) { + ret = -EBUSY; + dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", + &qproc->mdata_phys, size); + goto free_metadata; + } + } else { + ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); + if (!ptr) { + ret = -ENOMEM; + dev_err(qproc->dev, "failed to allocate mdt buffer\n"); + goto free_metadata; + } } memcpy(ptr, metadata, size); + if (qproc->mdata_phys) + memunmap(ptr); + /* Hypervisor mapping to access metadata by modem */ mdata_perm = BIT(QCOM_SCM_VMID_HLOS); ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true, @@ -853,7 +877,9 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) "mdt buffer not reclaimed system may become unstable\n"); free_dma_attrs: - dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); + if (!qproc->mdata_phys) + dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); +free_metadata: kfree(metadata); return ret < 0 ? ret : 0; @@ -1585,6 +1611,7 @@ static int q6v5_init_reset(struct q6v5 *qproc) static int q6v5_alloc_memory_region(struct q6v5 *qproc) { struct device_node *child; + struct reserved_mem *rmem; struct device_node *node; struct resource r; int ret; @@ -1637,6 +1664,26 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) qproc->mpss_phys = qproc->mpss_reloc = r.start; qproc->mpss_size = resource_size(&r); + if (!child) { + node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2); + } else { + child = of_get_child_by_name(qproc->dev->of_node, "metadata"); + node = of_parse_phandle(child, "memory-region", 0); + of_node_put(child); + } + + if (!node) + return 0; + + rmem = of_reserved_mem_lookup(node); + if (!rmem) { + dev_err(qproc->dev, "unable to resolve metadata region\n"); + return -EINVAL; + } + + qproc->mdata_phys = rmem->base; + qproc->mdata_size = rmem->size; + return 0; } From c7a218cbf67fffcd99b76ae3b5e9c2e8bef17c8c Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Tue, 29 Nov 2022 12:01:59 +0100 Subject: [PATCH 0379/1017] media: ti: cal: fix possible memory leak in cal_ctx_create() [ Upstream commit 7acd650a0484d92985a0d6d867d980c6dd019885 ] The memory of ctx is allocated in cal_ctx_create(), but it will not be freed when cal_ctx_v4l2_init() fails, so add kfree() when cal_ctx_v4l2_init() fails to fix it. Fixes: d68a94e98a89 ("media: ti-vpe: cal: Split video device initialization and registration") Signed-off-by: Gaosheng Cui Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/ti-vpe/cal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 2eef245c31a1..93121c90d76a 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -624,8 +624,10 @@ static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst) ctx->cport = inst; ret = cal_ctx_v4l2_init(ctx); - if (ret) + if (ret) { + kfree(ctx); return NULL; + } return ctx; } From b74aaa314f6a9e6b4e0deac993abcaf9a0029e8c Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Wed, 4 Jan 2023 09:55:37 +0100 Subject: [PATCH 0380/1017] media: platform: ti: Add missing check for devm_regulator_get [ Upstream commit da8e05f84a11c3cc3b0ba0a3c62d20e358002d99 ] Add check for the return value of devm_regulator_get since it may return error pointer. Fixes: 448de7e7850b ("[media] omap3isp: OMAP3 ISP core") Signed-off-by: Jiasheng Jiang Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/omap3isp/isp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 1311b4996ece..21c16698cc2d 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2297,7 +2297,16 @@ static int isp_probe(struct platform_device *pdev) /* Regulators */ isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1"); + if (IS_ERR(isp->isp_csiphy1.vdd)) { + ret = PTR_ERR(isp->isp_csiphy1.vdd); + goto error; + } + isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2"); + if (IS_ERR(isp->isp_csiphy2.vdd)) { + ret = PTR_ERR(isp->isp_csiphy2.vdd); + goto error; + } /* Clocks * From 55f3bca25d3fd555935f84734d5203e25c41793b Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 11 Jan 2023 20:05:02 -0700 Subject: [PATCH 0381/1017] powerpc: Remove linker flag from KBUILD_AFLAGS [ Upstream commit 31f48f16264bc70962fb3e7ec62da64d0a2ba04a ] When clang's -Qunused-arguments is dropped from KBUILD_CPPFLAGS, it points out that KBUILD_AFLAGS contains a linker flag, which will be unused: clang: error: -Wl,-a32: 'linker' input unused [-Werror,-Wunused-command-line-argument] This was likely supposed to be '-Wa,-a$(BITS)'. However, this change is unnecessary, as all supported versions of clang and gcc will pass '-a64' or '-a32' to GNU as based on the value of '-m'; the behavior of the latest stable release of the oldest supported major version of each compiler is shown below and each compiler's latest release exhibits the same behavior (GCC 12.2.0 and Clang 15.0.6). $ powerpc64-linux-gcc --version | head -1 powerpc64-linux-gcc (GCC) 5.5.0 $ powerpc64-linux-gcc -m64 -### -x assembler-with-cpp -c -o /dev/null /dev/null &| grep 'as ' .../as -a64 -mppc64 -many -mbig -o /dev/null /tmp/cctwuBzZ.s $ powerpc64-linux-gcc -m32 -### -x assembler-with-cpp -c -o /dev/null /dev/null &| grep 'as ' .../as -a32 -mppc -many -mbig -o /dev/null /tmp/ccaZP4mF.sg $ clang --version | head -1 Ubuntu clang version 11.1.0-++20211011094159+1fdec59bffc1-1~exp1~20211011214622.5 $ clang --target=powerpc64-linux-gnu -fno-integrated-as -m64 -### \ -x assembler-with-cpp -c -o /dev/null /dev/null &| grep gnu-as "/usr/bin/powerpc64-linux-gnu-as" "-a64" "-mppc64" "-many" "-o" "/dev/null" "/tmp/null-80267c.s" $ clang --target=powerpc64-linux-gnu -fno-integrated-as -m64 -### \ -x assembler-with-cpp -c -o /dev/null /dev/null &| grep gnu-as "/usr/bin/powerpc64-linux-gnu-as" "-a32" "-mppc" "-many" "-o" "/dev/null" "/tmp/null-ab8f8d.s" Remove this flag altogether to avoid future issues. Fixes: 1421dc6d4829 ("powerpc/kbuild: Use flags variables rather than overriding LD/CC/AS") Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Tested-by: Linux Kernel Functional Testing Tested-by: Anders Roxell Acked-by: Michael Ellerman Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin --- arch/powerpc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 612254141296..a3f66ade09b3 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -92,7 +92,7 @@ aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mlittle-endian ifeq ($(HAS_BIARCH),y) KBUILD_CFLAGS += -m$(BITS) -KBUILD_AFLAGS += -m$(BITS) -Wl,-a$(BITS) +KBUILD_AFLAGS += -m$(BITS) KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION) endif From f3e10a3437dcbee7900b437c5bceaa4f105d75e6 Mon Sep 17 00:00:00 2001 From: Bastian Germann Date: Wed, 26 May 2021 01:01:37 +0200 Subject: [PATCH 0382/1017] builddeb: clean generated package content [ Upstream commit c9f9cf2560e40b62015c6c4a04be60f55ce5240e ] For each binary Debian package, a directory with the package name is created in the debian directory. Correct the generated file matches in the package's clean target, which were renamed without adjusting the target. Fixes: 1694e94e4f46 ("builddeb: match temporary directory name to the package name") Signed-off-by: Bastian Germann Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin --- scripts/package/mkdebian | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 60a2a63a5e90..32d528a36786 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -236,7 +236,7 @@ binary-arch: build-arch KBUILD_BUILD_VERSION=${revision} -f \$(srctree)/Makefile intdeb-pkg clean: - rm -rf debian/*tmp debian/files + rm -rf debian/files debian/linux-* \$(MAKE) clean binary: binary-arch From 505ff3a0c5951684c3a43094ca4c1a74683d5681 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Tue, 6 Dec 2022 14:05:55 +0100 Subject: [PATCH 0383/1017] media: max9286: Fix memleak in max9286_v4l2_register() [ Upstream commit 8636c5fc7658c7c6299fb8b352d24ea4b9ba99e2 ] There is a kmemleak when testing the media/i2c/max9286.c with bpf mock device: kmemleak: 5 new suspected memory leaks (see /sys/kernel/debug/kmemleak) unreferenced object 0xffff88810defc400 (size 256): comm "python3", pid 278, jiffies 4294737563 (age 31.978s) hex dump (first 32 bytes): 28 06 a7 0a 81 88 ff ff 00 fe 22 12 81 88 ff ff (........."..... 10 c4 ef 0d 81 88 ff ff 10 c4 ef 0d 81 88 ff ff ................ backtrace: [<00000000191de6a7>] __kmalloc_node+0x44/0x1b0 [<000000002f4912b7>] kvmalloc_node+0x34/0x180 [<0000000057dc4cae>] v4l2_ctrl_new+0x325/0x10f0 [videodev] [<0000000026030272>] v4l2_ctrl_new_std+0x16f/0x210 [videodev] [<00000000f0d9ea2f>] max9286_probe+0x76e/0xbff [max9286] [<00000000ea8f6455>] i2c_device_probe+0x28d/0x680 [<0000000087529af3>] really_probe+0x17c/0x3f0 [<00000000b08be526>] __driver_probe_device+0xe3/0x170 [<000000004382edea>] driver_probe_device+0x49/0x120 [<000000007bde528a>] __device_attach_driver+0xf7/0x150 [<000000009f9c6ab4>] bus_for_each_drv+0x114/0x180 [<00000000c8aaf588>] __device_attach+0x1e5/0x2d0 [<0000000041cc06b9>] bus_probe_device+0x126/0x140 [<000000002309860d>] device_add+0x810/0x1130 [<000000002827bf98>] i2c_new_client_device+0x359/0x4f0 [<00000000593bdc85>] of_i2c_register_device+0xf1/0x110 max9286_v4l2_register() calls v4l2_ctrl_new_std(), but won't free the created v412_ctrl when fwnode_graph_get_endpoint_by_id() failed, which causes the memleak. Call v4l2_ctrl_handler_free() to free the v412_ctrl. Fixes: 66d8c9d2422d ("media: i2c: Add MAX9286 driver") Signed-off-by: Shang XiaoJing Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/max9286.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index b1e2476d3c9e..79a11c0184c6 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -890,6 +890,7 @@ static int max9286_v4l2_register(struct max9286_priv *priv) err_put_node: fwnode_handle_put(ep); err_async: + v4l2_ctrl_handler_free(&priv->ctrls); max9286_v4l2_notifier_unregister(priv); return ret; From a163ee11345d8322321c28bd61631de32455b987 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Thu, 8 Dec 2022 08:59:37 +0100 Subject: [PATCH 0384/1017] media: ov2740: Fix memleak in ov2740_init_controls() [ Upstream commit 2d899592ed7829d0d5140853bac4d58742a6b8af ] There is a kmemleak when testing the media/i2c/ov2740.c with bpf mock device: unreferenced object 0xffff8881090e19e0 (size 16): comm "51-i2c-ov2740", pid 278, jiffies 4294781584 (age 23.613s) hex dump (first 16 bytes): 00 f3 7c 0b 81 88 ff ff 80 75 6a 09 81 88 ff ff ..|......uj..... backtrace: [<000000004e9fad8f>] __kmalloc_node+0x44/0x1b0 [<0000000039c802f4>] kvmalloc_node+0x34/0x180 [<000000009b8b5c63>] v4l2_ctrl_handler_init_class+0x11d/0x180 [videodev] [<0000000038644056>] ov2740_probe+0x37d/0x84f [ov2740] [<0000000092489f59>] i2c_device_probe+0x28d/0x680 [<000000001038babe>] really_probe+0x17c/0x3f0 [<0000000098c7af1c>] __driver_probe_device+0xe3/0x170 [<00000000e1b3dc24>] device_driver_attach+0x34/0x80 [<000000005a04a34d>] bind_store+0x10b/0x1a0 [<00000000ce25d4f2>] drv_attr_store+0x49/0x70 [<000000007d9f4e9a>] sysfs_kf_write+0x8c/0xb0 [<00000000be6cff0f>] kernfs_fop_write_iter+0x216/0x2e0 [<0000000031ddb40a>] vfs_write+0x658/0x810 [<0000000041beecdd>] ksys_write+0xd6/0x1b0 [<0000000023755840>] do_syscall_64+0x38/0x90 [<00000000b2cc2da2>] entry_SYSCALL_64_after_hwframe+0x63/0xcd ov2740_init_controls() won't clean all the allocated resources in fail path, which may causes the memleaks. Add v4l2_ctrl_handler_free() to prevent memleak. Fixes: 866edc895171 ("media: i2c: Add ov2740 image sensor driver") Signed-off-by: Shang XiaoJing Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/ov2740.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index bd0d45b0d43f..34d74e575a43 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -577,8 +577,10 @@ static int ov2740_init_controls(struct ov2740 *ov2740) V4L2_CID_TEST_PATTERN, ARRAY_SIZE(ov2740_test_pattern_menu) - 1, 0, 0, ov2740_test_pattern_menu); - if (ctrl_hdlr->error) + if (ctrl_hdlr->error) { + v4l2_ctrl_handler_free(ctrl_hdlr); return ctrl_hdlr->error; + } ov2740->sd.ctrl_handler = ctrl_hdlr; From bcae9115a163198dce9126aa8bedc1c007ec30ed Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Thu, 8 Dec 2022 08:59:38 +0100 Subject: [PATCH 0385/1017] media: ov5675: Fix memleak in ov5675_init_controls() [ Upstream commit dd74ed6c213003533e3abf4c204374ef01d86978 ] There is a kmemleak when testing the media/i2c/ov5675.c with bpf mock device: AssertionError: unreferenced object 0xffff888107362160 (size 16): comm "python3", pid 277, jiffies 4294832798 (age 20.722s) hex dump (first 16 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000abe7d67c>] __kmalloc_node+0x44/0x1b0 [<000000008a725aac>] kvmalloc_node+0x34/0x180 [<000000009a53cd11>] v4l2_ctrl_handler_init_class+0x11d/0x180 [videodev] [<0000000055b46db0>] ov5675_probe+0x38b/0x897 [ov5675] [<00000000153d886c>] i2c_device_probe+0x28d/0x680 [<000000004afb7e8f>] really_probe+0x17c/0x3f0 [<00000000ff2f18e4>] __driver_probe_device+0xe3/0x170 [<000000000a001029>] driver_probe_device+0x49/0x120 [<00000000e39743c7>] __device_attach_driver+0xf7/0x150 [<00000000d32fd070>] bus_for_each_drv+0x114/0x180 [<000000009083ac41>] __device_attach+0x1e5/0x2d0 [<0000000015b4a830>] bus_probe_device+0x126/0x140 [<000000007813deaf>] device_add+0x810/0x1130 [<000000007becb867>] i2c_new_client_device+0x386/0x540 [<000000007f9cf4b4>] of_i2c_register_device+0xf1/0x110 [<00000000ebfdd032>] of_i2c_notify+0xfc/0x1f0 ov5675_init_controls() won't clean all the allocated resources in fail path, which may causes the memleaks. Add v4l2_ctrl_handler_free() to prevent memleak. Fixes: bf27502b1f3b ("media: ov5675: Add support for OV5675 sensor") Signed-off-by: Shang XiaoJing Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/ov5675.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index 9540ce8918f0..aa35a9546177 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -791,8 +791,10 @@ static int ov5675_init_controls(struct ov5675 *ov5675) v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - if (ctrl_hdlr->error) + if (ctrl_hdlr->error) { + v4l2_ctrl_handler_free(ctrl_hdlr); return ctrl_hdlr->error; + } ov5675->sd.ctrl_handler = ctrl_hdlr; From dfaafeb8e9537969e8dba75491f732478c7fa9d6 Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Thu, 8 Dec 2022 09:06:25 +0100 Subject: [PATCH 0386/1017] media: i2c: ov772x: Fix memleak in ov772x_probe() [ Upstream commit 7485edb2b6ca5960205c0a49bedfd09bba30e521 ] A memory leak was reported when testing ov772x with bpf mock device: AssertionError: unreferenced object 0xffff888109afa7a8 (size 8): comm "python3", pid 279, jiffies 4294805921 (age 20.681s) hex dump (first 8 bytes): 80 22 88 15 81 88 ff ff ."...... backtrace: [<000000009990b438>] __kmalloc_node+0x44/0x1b0 [<000000009e32f7d7>] kvmalloc_node+0x34/0x180 [<00000000faf48134>] v4l2_ctrl_handler_init_class+0x11d/0x180 [videodev] [<00000000da376937>] ov772x_probe+0x1c3/0x68c [ov772x] [<000000003f0d225e>] i2c_device_probe+0x28d/0x680 [<00000000e0b6db89>] really_probe+0x17c/0x3f0 [<000000001b19fcee>] __driver_probe_device+0xe3/0x170 [<0000000048370519>] driver_probe_device+0x49/0x120 [<000000005ead07a0>] __device_attach_driver+0xf7/0x150 [<0000000043f452b8>] bus_for_each_drv+0x114/0x180 [<00000000358e5596>] __device_attach+0x1e5/0x2d0 [<0000000043f83c5d>] bus_probe_device+0x126/0x140 [<00000000ee0f3046>] device_add+0x810/0x1130 [<00000000e0278184>] i2c_new_client_device+0x359/0x4f0 [<0000000070baf34f>] of_i2c_register_device+0xf1/0x110 [<00000000a9f2159d>] of_i2c_notify+0x100/0x160 unreferenced object 0xffff888119825c00 (size 256): comm "python3", pid 279, jiffies 4294805921 (age 20.681s) hex dump (first 32 bytes): 00 b4 a5 17 81 88 ff ff 00 5e 82 19 81 88 ff ff .........^...... 10 5c 82 19 81 88 ff ff 10 5c 82 19 81 88 ff ff .\.......\...... backtrace: [<000000009990b438>] __kmalloc_node+0x44/0x1b0 [<000000009e32f7d7>] kvmalloc_node+0x34/0x180 [<0000000073d88e0b>] v4l2_ctrl_new.cold+0x19b/0x86f [videodev] [<00000000b1f576fb>] v4l2_ctrl_new_std+0x16f/0x210 [videodev] [<00000000caf7ac99>] ov772x_probe+0x1fa/0x68c [ov772x] [<000000003f0d225e>] i2c_device_probe+0x28d/0x680 [<00000000e0b6db89>] really_probe+0x17c/0x3f0 [<000000001b19fcee>] __driver_probe_device+0xe3/0x170 [<0000000048370519>] driver_probe_device+0x49/0x120 [<000000005ead07a0>] __device_attach_driver+0xf7/0x150 [<0000000043f452b8>] bus_for_each_drv+0x114/0x180 [<00000000358e5596>] __device_attach+0x1e5/0x2d0 [<0000000043f83c5d>] bus_probe_device+0x126/0x140 [<00000000ee0f3046>] device_add+0x810/0x1130 [<00000000e0278184>] i2c_new_client_device+0x359/0x4f0 [<0000000070baf34f>] of_i2c_register_device+0xf1/0x110 The reason is that if priv->hdl.error is set, ov772x_probe() jumps to the error_mutex_destroy without doing v4l2_ctrl_handler_free(), and all resources allocated in v4l2_ctrl_handler_init() and v4l2_ctrl_new_std() are leaked. Fixes: 1112babde214 ("media: i2c: Copy ov772x soc_camera sensor driver") Signed-off-by: Yuan Can Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/ov772x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c index 2cc6a678069a..5033950a48ab 100644 --- a/drivers/media/i2c/ov772x.c +++ b/drivers/media/i2c/ov772x.c @@ -1397,7 +1397,7 @@ static int ov772x_probe(struct i2c_client *client) priv->subdev.ctrl_handler = &priv->hdl; if (priv->hdl.error) { ret = priv->hdl.error; - goto error_mutex_destroy; + goto error_ctrl_free; } priv->clk = clk_get(&client->dev, NULL); @@ -1446,7 +1446,6 @@ error_clk_put: clk_put(priv->clk); error_ctrl_free: v4l2_ctrl_handler_free(&priv->hdl); -error_mutex_destroy: mutex_destroy(&priv->lock); return ret; From 09a0410886aa80269d5fee39a5d61dde98694f90 Mon Sep 17 00:00:00 2001 From: Sameer Puri Date: Mon, 13 Apr 2020 17:51:47 +0200 Subject: [PATCH 0387/1017] media: i2c: imx219: remove redundant writes [ Upstream commit fbef89886da6d7735d20fdde16a1ee6ed6c6ab56 ] These writes to 0x162, 0x163 already appear earlier in the struct for the 1920x1080 mode and do not need to be repeated. Signed-off-by: Sameer Puri Reviewed-by: Dave Stevenson Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: ef86447e775f ("media: i2c: imx219: Fix binning for RAW8 capture") Signed-off-by: Sasha Levin --- drivers/media/i2c/imx219.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 4771d0ef2c46..cad0a8df203e 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -262,8 +262,6 @@ static const struct imx219_reg mode_1920_1080_regs[] = { {0x4793, 0x10}, {0x4797, 0x0e}, {0x479b, 0x0e}, - {0x0162, 0x0d}, - {0x0163, 0x78}, }; static const struct imx219_reg mode_1640_1232_regs[] = { From a34288e3a1169abc6509c943fc76ddc43843ec9c Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 20 Dec 2022 13:07:53 +0100 Subject: [PATCH 0388/1017] media: i2c: imx219: Split common registers from mode tables [ Upstream commit 8508455961d5a9e8907bcfd8dcd58f19d9b6ce47 ] There are four modes, and each mode has a table of registers. Some of the registers are common to all modes, so create new tables for these common registers to reduce duplicate code. Signed-off-by: Adam Ford Reviewed-by: Dave Stevenson Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: ef86447e775f ("media: i2c: imx219: Fix binning for RAW8 capture") Signed-off-by: Sasha Levin --- drivers/media/i2c/imx219.c | 206 +++++++++++-------------------------- 1 file changed, 59 insertions(+), 147 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index cad0a8df203e..a28926069b82 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -145,23 +145,61 @@ struct imx219_mode { struct imx219_reg_list reg_list; }; -/* - * Register sets lifted off the i2C interface from the Raspberry Pi firmware - * driver. - * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. - */ -static const struct imx219_reg mode_3280x2464_regs[] = { - {0x0100, 0x00}, +static const struct imx219_reg imx219_common_regs[] = { + {0x0100, 0x00}, /* Mode Select */ + + /* To Access Addresses 3000-5fff, send the following commands */ {0x30eb, 0x0c}, {0x30eb, 0x05}, {0x300a, 0xff}, {0x300b, 0xff}, {0x30eb, 0x05}, {0x30eb, 0x09}, - {0x0114, 0x01}, - {0x0128, 0x00}, - {0x012a, 0x18}, + + /* PLL Clock Table */ + {0x0301, 0x05}, /* VTPXCK_DIV */ + {0x0303, 0x01}, /* VTSYSCK_DIV */ + {0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ + {0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ + {0x0306, 0x00}, /* PLL_VT_MPY */ + {0x0307, 0x39}, + {0x030b, 0x01}, /* OP_SYS_CLK_DIV */ + {0x030c, 0x00}, /* PLL_OP_MPY */ + {0x030d, 0x72}, + + /* Undocumented registers */ + {0x455e, 0x00}, + {0x471e, 0x4b}, + {0x4767, 0x0f}, + {0x4750, 0x14}, + {0x4540, 0x00}, + {0x47b4, 0x14}, + {0x4713, 0x30}, + {0x478b, 0x10}, + {0x478f, 0x10}, + {0x4793, 0x10}, + {0x4797, 0x0e}, + {0x479b, 0x0e}, + + /* Frame Bank Register Group "A" */ + {0x0162, 0x0d}, /* Line_Length_A */ + {0x0163, 0x78}, + {0x0170, 0x01}, /* X_ODD_INC_A */ + {0x0171, 0x01}, /* Y_ODD_INC_A */ + + /* Output setup registers */ + {0x0114, 0x01}, /* CSI 2-Lane Mode */ + {0x0128, 0x00}, /* DPHY Auto Mode */ + {0x012a, 0x18}, /* EXCK_Freq */ {0x012b, 0x00}, +}; + +/* + * Register sets lifted off the i2C interface from the Raspberry Pi firmware + * driver. + * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. + */ +static const struct imx219_reg mode_3280x2464_regs[] = { {0x0164, 0x00}, {0x0165, 0x00}, {0x0166, 0x0c}, @@ -174,53 +212,15 @@ static const struct imx219_reg mode_3280x2464_regs[] = { {0x016d, 0xd0}, {0x016e, 0x09}, {0x016f, 0xa0}, - {0x0170, 0x01}, - {0x0171, 0x01}, - {0x0174, 0x00}, + {0x0174, 0x00}, /* No-Binning */ {0x0175, 0x00}, - {0x0301, 0x05}, - {0x0303, 0x01}, - {0x0304, 0x03}, - {0x0305, 0x03}, - {0x0306, 0x00}, - {0x0307, 0x39}, - {0x030b, 0x01}, - {0x030c, 0x00}, - {0x030d, 0x72}, {0x0624, 0x0c}, {0x0625, 0xd0}, {0x0626, 0x09}, {0x0627, 0xa0}, - {0x455e, 0x00}, - {0x471e, 0x4b}, - {0x4767, 0x0f}, - {0x4750, 0x14}, - {0x4540, 0x00}, - {0x47b4, 0x14}, - {0x4713, 0x30}, - {0x478b, 0x10}, - {0x478f, 0x10}, - {0x4793, 0x10}, - {0x4797, 0x0e}, - {0x479b, 0x0e}, - {0x0162, 0x0d}, - {0x0163, 0x78}, }; static const struct imx219_reg mode_1920_1080_regs[] = { - {0x0100, 0x00}, - {0x30eb, 0x05}, - {0x30eb, 0x0c}, - {0x300a, 0xff}, - {0x300b, 0xff}, - {0x30eb, 0x05}, - {0x30eb, 0x09}, - {0x0114, 0x01}, - {0x0128, 0x00}, - {0x012a, 0x18}, - {0x012b, 0x00}, - {0x0162, 0x0d}, - {0x0163, 0x78}, {0x0164, 0x02}, {0x0165, 0xa8}, {0x0166, 0x0a}, @@ -233,49 +233,15 @@ static const struct imx219_reg mode_1920_1080_regs[] = { {0x016d, 0x80}, {0x016e, 0x04}, {0x016f, 0x38}, - {0x0170, 0x01}, - {0x0171, 0x01}, - {0x0174, 0x00}, + {0x0174, 0x00}, /* No-Binning */ {0x0175, 0x00}, - {0x0301, 0x05}, - {0x0303, 0x01}, - {0x0304, 0x03}, - {0x0305, 0x03}, - {0x0306, 0x00}, - {0x0307, 0x39}, - {0x030b, 0x01}, - {0x030c, 0x00}, - {0x030d, 0x72}, {0x0624, 0x07}, {0x0625, 0x80}, {0x0626, 0x04}, {0x0627, 0x38}, - {0x455e, 0x00}, - {0x471e, 0x4b}, - {0x4767, 0x0f}, - {0x4750, 0x14}, - {0x4540, 0x00}, - {0x47b4, 0x14}, - {0x4713, 0x30}, - {0x478b, 0x10}, - {0x478f, 0x10}, - {0x4793, 0x10}, - {0x4797, 0x0e}, - {0x479b, 0x0e}, }; static const struct imx219_reg mode_1640_1232_regs[] = { - {0x0100, 0x00}, - {0x30eb, 0x0c}, - {0x30eb, 0x05}, - {0x300a, 0xff}, - {0x300b, 0xff}, - {0x30eb, 0x05}, - {0x30eb, 0x09}, - {0x0114, 0x01}, - {0x0128, 0x00}, - {0x012a, 0x18}, - {0x012b, 0x00}, {0x0164, 0x00}, {0x0165, 0x00}, {0x0166, 0x0c}, @@ -288,53 +254,15 @@ static const struct imx219_reg mode_1640_1232_regs[] = { {0x016d, 0x68}, {0x016e, 0x04}, {0x016f, 0xd0}, - {0x0170, 0x01}, - {0x0171, 0x01}, - {0x0174, 0x01}, + {0x0174, 0x01}, /* x2-Binning */ {0x0175, 0x01}, - {0x0301, 0x05}, - {0x0303, 0x01}, - {0x0304, 0x03}, - {0x0305, 0x03}, - {0x0306, 0x00}, - {0x0307, 0x39}, - {0x030b, 0x01}, - {0x030c, 0x00}, - {0x030d, 0x72}, {0x0624, 0x06}, {0x0625, 0x68}, {0x0626, 0x04}, {0x0627, 0xd0}, - {0x455e, 0x00}, - {0x471e, 0x4b}, - {0x4767, 0x0f}, - {0x4750, 0x14}, - {0x4540, 0x00}, - {0x47b4, 0x14}, - {0x4713, 0x30}, - {0x478b, 0x10}, - {0x478f, 0x10}, - {0x4793, 0x10}, - {0x4797, 0x0e}, - {0x479b, 0x0e}, - {0x0162, 0x0d}, - {0x0163, 0x78}, }; static const struct imx219_reg mode_640_480_regs[] = { - {0x0100, 0x00}, - {0x30eb, 0x05}, - {0x30eb, 0x0c}, - {0x300a, 0xff}, - {0x300b, 0xff}, - {0x30eb, 0x05}, - {0x30eb, 0x09}, - {0x0114, 0x01}, - {0x0128, 0x00}, - {0x012a, 0x18}, - {0x012b, 0x00}, - {0x0162, 0x0d}, - {0x0163, 0x78}, {0x0164, 0x03}, {0x0165, 0xe8}, {0x0166, 0x08}, @@ -347,35 +275,12 @@ static const struct imx219_reg mode_640_480_regs[] = { {0x016d, 0x80}, {0x016e, 0x01}, {0x016f, 0xe0}, - {0x0170, 0x01}, - {0x0171, 0x01}, - {0x0174, 0x03}, + {0x0174, 0x03}, /* x2-analog binning */ {0x0175, 0x03}, - {0x0301, 0x05}, - {0x0303, 0x01}, - {0x0304, 0x03}, - {0x0305, 0x03}, - {0x0306, 0x00}, - {0x0307, 0x39}, - {0x030b, 0x01}, - {0x030c, 0x00}, - {0x030d, 0x72}, {0x0624, 0x06}, {0x0625, 0x68}, {0x0626, 0x04}, {0x0627, 0xd0}, - {0x455e, 0x00}, - {0x471e, 0x4b}, - {0x4767, 0x0f}, - {0x4750, 0x14}, - {0x4540, 0x00}, - {0x47b4, 0x14}, - {0x4713, 0x30}, - {0x478b, 0x10}, - {0x478f, 0x10}, - {0x4793, 0x10}, - {0x4797, 0x0e}, - {0x479b, 0x0e}, }; static const struct imx219_reg raw8_framefmt_regs[] = { @@ -1030,6 +935,13 @@ static int imx219_start_streaming(struct imx219 *imx219) return ret; } + /* Send all registers that are common to all modes */ + ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs)); + if (ret) { + dev_err(&client->dev, "%s failed to send mfg header\n", __func__); + goto err_rpm_put; + } + /* Apply default values of current mode */ reg_list = &imx219->mode->reg_list; ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); From c6c3b4ae31664e2b52e31a80b231c6f37f370c97 Mon Sep 17 00:00:00 2001 From: Jai Luthra Date: Tue, 17 Jan 2023 09:16:23 +0100 Subject: [PATCH 0389/1017] media: i2c: imx219: Fix binning for RAW8 capture [ Upstream commit ef86447e775fb1f2ced00d4c7fff2c0a1c63f165 ] 2x2 binning works fine for RAW10 capture, but for RAW8 1232p mode it leads to corrupted frames [1][2]. Using the special 2x2 analog binning mode fixes the issue, but causes artefacts for RAW10 1232p capture. So here we choose the binning mode depending upon the frame format selected. As both binning modes work fine for 480p RAW8 and RAW10 capture, it can share the same code path as 1232p for selecting binning mode. [1] https://forums.raspberrypi.com/viewtopic.php?t=332103 [2] https://github.com/raspberrypi/libcamera-apps/issues/281 Fixes: 22da1d56e982 ("media: i2c: imx219: Add support for RAW8 bit bayer format") Signed-off-by: Jai Luthra Reviewed-by: Dave Stevenson Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/imx219.c | 57 ++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index a28926069b82..b975636d9440 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -89,6 +89,12 @@ #define IMX219_REG_ORIENTATION 0x0172 +/* Binning Mode */ +#define IMX219_REG_BINNING_MODE 0x0174 +#define IMX219_BINNING_NONE 0x0000 +#define IMX219_BINNING_2X2 0x0101 +#define IMX219_BINNING_2X2_ANALOG 0x0303 + /* Test Pattern Control */ #define IMX219_REG_TEST_PATTERN 0x0600 #define IMX219_TEST_PATTERN_DISABLE 0 @@ -143,6 +149,9 @@ struct imx219_mode { /* Default register values */ struct imx219_reg_list reg_list; + + /* 2x2 binning is used */ + bool binning; }; static const struct imx219_reg imx219_common_regs[] = { @@ -212,8 +221,6 @@ static const struct imx219_reg mode_3280x2464_regs[] = { {0x016d, 0xd0}, {0x016e, 0x09}, {0x016f, 0xa0}, - {0x0174, 0x00}, /* No-Binning */ - {0x0175, 0x00}, {0x0624, 0x0c}, {0x0625, 0xd0}, {0x0626, 0x09}, @@ -233,8 +240,6 @@ static const struct imx219_reg mode_1920_1080_regs[] = { {0x016d, 0x80}, {0x016e, 0x04}, {0x016f, 0x38}, - {0x0174, 0x00}, /* No-Binning */ - {0x0175, 0x00}, {0x0624, 0x07}, {0x0625, 0x80}, {0x0626, 0x04}, @@ -254,8 +259,6 @@ static const struct imx219_reg mode_1640_1232_regs[] = { {0x016d, 0x68}, {0x016e, 0x04}, {0x016f, 0xd0}, - {0x0174, 0x01}, /* x2-Binning */ - {0x0175, 0x01}, {0x0624, 0x06}, {0x0625, 0x68}, {0x0626, 0x04}, @@ -275,8 +278,6 @@ static const struct imx219_reg mode_640_480_regs[] = { {0x016d, 0x80}, {0x016e, 0x01}, {0x016f, 0xe0}, - {0x0174, 0x03}, /* x2-analog binning */ - {0x0175, 0x03}, {0x0624, 0x06}, {0x0625, 0x68}, {0x0626, 0x04}, @@ -386,6 +387,7 @@ static const struct imx219_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs), .regs = mode_3280x2464_regs, }, + .binning = false, }, { /* 1080P 30fps cropped */ @@ -402,6 +404,7 @@ static const struct imx219_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs), .regs = mode_1920_1080_regs, }, + .binning = false, }, { /* 2x2 binned 30fps mode */ @@ -418,6 +421,7 @@ static const struct imx219_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs), .regs = mode_1640_1232_regs, }, + .binning = true, }, { /* 640x480 30fps mode */ @@ -434,6 +438,7 @@ static const struct imx219_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_640_480_regs), .regs = mode_640_480_regs, }, + .binning = true, }, }; @@ -872,6 +877,35 @@ static int imx219_set_framefmt(struct imx219 *imx219) return -EINVAL; } +static int imx219_set_binning(struct imx219 *imx219) +{ + if (!imx219->mode->binning) { + return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, + IMX219_REG_VALUE_16BIT, + IMX219_BINNING_NONE); + } + + switch (imx219->fmt.code) { + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, + IMX219_REG_VALUE_16BIT, + IMX219_BINNING_2X2_ANALOG); + + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, + IMX219_REG_VALUE_16BIT, + IMX219_BINNING_2X2); + } + + return -EINVAL; +} + static const struct v4l2_rect * __imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg, unsigned int pad, enum v4l2_subdev_format_whence which) @@ -957,6 +991,13 @@ static int imx219_start_streaming(struct imx219 *imx219) goto err_rpm_put; } + ret = imx219_set_binning(imx219); + if (ret) { + dev_err(&client->dev, "%s failed to set binning: %d\n", + __func__, ret); + goto err_rpm_put; + } + /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); if (ret) From 78da5a378bdacd5bf68c3a6389bdc1dd0c0f5b3c Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Tue, 24 Jan 2023 08:55:33 +0100 Subject: [PATCH 0390/1017] media: rc: Fix use-after-free bugs caused by ene_tx_irqsim() [ Upstream commit 29b0589a865b6f66d141d79b2dd1373e4e50fe17 ] When the ene device is detaching, function ene_remove() will be called. But there is no function to cancel tx_sim_timer in ene_remove(), the timer handler ene_tx_irqsim() could race with ene_remove(). As a result, the UAF bugs could happen, the process is shown below. (cleanup routine) | (timer routine) | mod_timer(&dev->tx_sim_timer, ..) ene_remove() | (wait a time) | ene_tx_irqsim() | dev->hw_lock //USE | ene_tx_sample(dev) //USE Fix by adding del_timer_sync(&dev->tx_sim_timer) in ene_remove(), The tx_sim_timer could stop before ene device is deallocated. What's more, The rc_unregister_device() and del_timer_sync() should be called first in ene_remove() and the deallocated functions such as free_irq(), release_region() and so on should be called behind them. Because the rc_unregister_device() is well synchronized. Otherwise, race conditions may happen. The situations that may lead to race conditions are shown below. Firstly, the rx receiver is disabled with ene_rx_disable() before rc_unregister_device() in ene_remove(), which means it can be enabled again if a process opens /dev/lirc0 between ene_rx_disable() and rc_unregister_device(). Secondly, the irqaction descriptor is freed by free_irq() before the rc device is unregistered, which means irqaction descriptor may be accessed again after it is deallocated. Thirdly, the timer can call ene_tx_sample() that can write to the io ports, which means the io ports could be accessed again after they are deallocated by release_region(). Therefore, the rc_unregister_device() and del_timer_sync() should be called first in ene_remove(). Suggested by: Sean Young Fixes: 9ea53b74df9c ("V4L/DVB: STAGING: remove lirc_ene0100 driver") Signed-off-by: Duoming Zhou Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/rc/ene_ir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 6049e5c95394..5aa3953cab82 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1106,6 +1106,8 @@ static void ene_remove(struct pnp_dev *pnp_dev) struct ene_device *dev = pnp_get_drvdata(pnp_dev); unsigned long flags; + rc_unregister_device(dev->rdev); + del_timer_sync(&dev->tx_sim_timer); spin_lock_irqsave(&dev->hw_lock, flags); ene_rx_disable(dev); ene_rx_restore_hw_buffer(dev); @@ -1113,7 +1115,6 @@ static void ene_remove(struct pnp_dev *pnp_dev) free_irq(dev->irq, dev); release_region(dev->hw_io, ENE_IO_SIZE); - rc_unregister_device(dev->rdev); kfree(dev); } From cc2f9c8eb1ee470e055d6d383027077d072899d8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 26 Jan 2023 14:03:51 +0100 Subject: [PATCH 0391/1017] media: i2c: ov7670: 0 instead of -EINVAL was returned [ Upstream commit 6a4c664539e6de9b32b65ddcf767ec1bcc1d7f8a ] If the media bus is unsupported, then return -EINVAL. Instead it returned 'ret' which happened to be 0. This fixes a smatch warning: ov7670.c:1843 ov7670_parse_dt() warn: missing error code? 'ret' Signed-off-by: Hans Verkuil Fixes: 01b8444828fc ("media: v4l2: i2c: ov7670: Implement OF mbus configuration") Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/ov7670.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 154776d0069e..e47800cb6c0f 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -1824,7 +1824,7 @@ static int ov7670_parse_dt(struct device *dev, if (bus_cfg.bus_type != V4L2_MBUS_PARALLEL) { dev_err(dev, "Unsupported media bus type\n"); - return ret; + return -EINVAL; } info->mbus_config = bus_cfg.bus.parallel.flags; From 42f8ba8355682f6c4125b75503cac0cef4ac91d3 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Mon, 23 Jan 2023 03:04:38 +0100 Subject: [PATCH 0392/1017] media: usb: siano: Fix use after free bugs caused by do_submit_urb [ Upstream commit ebad8e731c1c06adf04621d6fd327b860c0861b5 ] There are UAF bugs caused by do_submit_urb(). One of the KASan reports is shown below: [ 36.403605] BUG: KASAN: use-after-free in worker_thread+0x4a2/0x890 [ 36.406105] Read of size 8 at addr ffff8880059600e8 by task kworker/0:2/49 [ 36.408316] [ 36.408867] CPU: 0 PID: 49 Comm: kworker/0:2 Not tainted 6.2.0-rc3-15798-g5a41237ad1d4-dir8 [ 36.411696] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g15584 [ 36.416157] Workqueue: 0x0 (events) [ 36.417654] Call Trace: [ 36.418546] [ 36.419320] dump_stack_lvl+0x96/0xd0 [ 36.420522] print_address_description+0x75/0x350 [ 36.421992] print_report+0x11b/0x250 [ 36.423174] ? _raw_spin_lock_irqsave+0x87/0xd0 [ 36.424806] ? __virt_addr_valid+0xcf/0x170 [ 36.426069] ? worker_thread+0x4a2/0x890 [ 36.427355] kasan_report+0x131/0x160 [ 36.428556] ? worker_thread+0x4a2/0x890 [ 36.430053] worker_thread+0x4a2/0x890 [ 36.431297] ? worker_clr_flags+0x90/0x90 [ 36.432479] kthread+0x166/0x190 [ 36.433493] ? kthread_blkcg+0x50/0x50 [ 36.434669] ret_from_fork+0x22/0x30 [ 36.435923] [ 36.436684] [ 36.437215] Allocated by task 24: [ 36.438289] kasan_set_track+0x50/0x80 [ 36.439436] __kasan_kmalloc+0x89/0xa0 [ 36.440566] smsusb_probe+0x374/0xc90 [ 36.441920] usb_probe_interface+0x2d1/0x4c0 [ 36.443253] really_probe+0x1d5/0x580 [ 36.444539] __driver_probe_device+0xe3/0x130 [ 36.446085] driver_probe_device+0x49/0x220 [ 36.447423] __device_attach_driver+0x19e/0x1b0 [ 36.448931] bus_for_each_drv+0xcb/0x110 [ 36.450217] __device_attach+0x132/0x1f0 [ 36.451470] bus_probe_device+0x59/0xf0 [ 36.452563] device_add+0x4ec/0x7b0 [ 36.453830] usb_set_configuration+0xc63/0xe10 [ 36.455230] usb_generic_driver_probe+0x3b/0x80 [ 36.456166] printk: console [ttyGS0] disabled [ 36.456569] usb_probe_device+0x90/0x110 [ 36.459523] really_probe+0x1d5/0x580 [ 36.461027] __driver_probe_device+0xe3/0x130 [ 36.462465] driver_probe_device+0x49/0x220 [ 36.463847] __device_attach_driver+0x19e/0x1b0 [ 36.465229] bus_for_each_drv+0xcb/0x110 [ 36.466466] __device_attach+0x132/0x1f0 [ 36.467799] bus_probe_device+0x59/0xf0 [ 36.469010] device_add+0x4ec/0x7b0 [ 36.470125] usb_new_device+0x863/0xa00 [ 36.471374] hub_event+0x18c7/0x2220 [ 36.472746] process_one_work+0x34c/0x5b0 [ 36.474041] worker_thread+0x4b7/0x890 [ 36.475216] kthread+0x166/0x190 [ 36.476267] ret_from_fork+0x22/0x30 [ 36.477447] [ 36.478160] Freed by task 24: [ 36.479239] kasan_set_track+0x50/0x80 [ 36.480512] kasan_save_free_info+0x2b/0x40 [ 36.481808] ____kasan_slab_free+0x122/0x1a0 [ 36.483173] __kmem_cache_free+0xc4/0x200 [ 36.484563] smsusb_term_device+0xcd/0xf0 [ 36.485896] smsusb_probe+0xc85/0xc90 [ 36.486976] usb_probe_interface+0x2d1/0x4c0 [ 36.488303] really_probe+0x1d5/0x580 [ 36.489498] __driver_probe_device+0xe3/0x130 [ 36.491140] driver_probe_device+0x49/0x220 [ 36.492475] __device_attach_driver+0x19e/0x1b0 [ 36.493988] bus_for_each_drv+0xcb/0x110 [ 36.495171] __device_attach+0x132/0x1f0 [ 36.496617] bus_probe_device+0x59/0xf0 [ 36.497875] device_add+0x4ec/0x7b0 [ 36.498972] usb_set_configuration+0xc63/0xe10 [ 36.500264] usb_generic_driver_probe+0x3b/0x80 [ 36.501740] usb_probe_device+0x90/0x110 [ 36.503084] really_probe+0x1d5/0x580 [ 36.504241] __driver_probe_device+0xe3/0x130 [ 36.505548] driver_probe_device+0x49/0x220 [ 36.506766] __device_attach_driver+0x19e/0x1b0 [ 36.508368] bus_for_each_drv+0xcb/0x110 [ 36.509646] __device_attach+0x132/0x1f0 [ 36.510911] bus_probe_device+0x59/0xf0 [ 36.512103] device_add+0x4ec/0x7b0 [ 36.513215] usb_new_device+0x863/0xa00 [ 36.514736] hub_event+0x18c7/0x2220 [ 36.516130] process_one_work+0x34c/0x5b0 [ 36.517396] worker_thread+0x4b7/0x890 [ 36.518591] kthread+0x166/0x190 [ 36.519599] ret_from_fork+0x22/0x30 [ 36.520851] [ 36.521405] Last potentially related work creation: [ 36.523143] kasan_save_stack+0x3f/0x60 [ 36.524275] kasan_record_aux_stack_noalloc+0x9d/0xb0 [ 36.525831] insert_work+0x25/0x130 [ 36.527039] __queue_work+0x4d4/0x620 [ 36.528236] queue_work_on+0x72/0xb0 [ 36.529344] __usb_hcd_giveback_urb+0x13f/0x1b0 [ 36.530819] dummy_timer+0x350/0x1a40 [ 36.532149] call_timer_fn+0x2c/0x190 [ 36.533567] expire_timers+0x69/0x1f0 [ 36.534736] __run_timers+0x289/0x2d0 [ 36.535841] run_timer_softirq+0x2d/0x60 [ 36.537110] __do_softirq+0x116/0x380 [ 36.538377] [ 36.538950] Second to last potentially related work creation: [ 36.540855] kasan_save_stack+0x3f/0x60 [ 36.542084] kasan_record_aux_stack_noalloc+0x9d/0xb0 [ 36.543592] insert_work+0x25/0x130 [ 36.544891] __queue_work+0x4d4/0x620 [ 36.546168] queue_work_on+0x72/0xb0 [ 36.547328] __usb_hcd_giveback_urb+0x13f/0x1b0 [ 36.548805] dummy_timer+0x350/0x1a40 [ 36.550116] call_timer_fn+0x2c/0x190 [ 36.551570] expire_timers+0x69/0x1f0 [ 36.552762] __run_timers+0x289/0x2d0 [ 36.553916] run_timer_softirq+0x2d/0x60 [ 36.555118] __do_softirq+0x116/0x380 [ 36.556239] [ 36.556807] The buggy address belongs to the object at ffff888005960000 [ 36.556807] which belongs to the cache kmalloc-4k of size 4096 [ 36.560652] The buggy address is located 232 bytes inside of [ 36.560652] 4096-byte region [ffff888005960000, ffff888005961000) [ 36.564791] [ 36.565355] The buggy address belongs to the physical page: [ 36.567212] page:000000004f0a0731 refcount:1 mapcount:0 mapping:0000000000000000 index:0x00 [ 36.570534] head:000000004f0a0731 order:3 compound_mapcount:0 subpages_mapcount:0 compound0 [ 36.573717] flags: 0x100000000010200(slab|head|node=0|zone=1) [ 36.575481] raw: 0100000000010200 ffff888001042140 dead000000000122 0000000000000000 [ 36.577842] raw: 0000000000000000 0000000000040004 00000001ffffffff 0000000000000000 [ 36.580175] page dumped because: kasan: bad access detected [ 36.581994] [ 36.582548] Memory state around the buggy address: [ 36.583983] ffff88800595ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 36.586240] ffff888005960000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 36.588884] >ffff888005960080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 36.591071] ^ [ 36.593295] ffff888005960100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 36.595705] ffff888005960180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 36.598026] ================================================================== [ 36.600224] Disabling lock debugging due to kernel taint [ 36.602681] general protection fault, probably for non-canonical address 0x43600a000000060I [ 36.607129] CPU: 0 PID: 49 Comm: kworker/0:2 Tainted: G B 6.2.0-rc3-15798-8 [ 36.611115] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g15584 [ 36.615026] Workqueue: events do_submit_urb [ 36.616290] RIP: 0010:_raw_spin_lock_irqsave+0x8a/0xd0 [ 36.618107] Code: 24 00 00 00 00 48 89 df be 04 00 00 00 e8 9e b5 c6 fe 48 89 ef be 04 00 5 [ 36.623522] RSP: 0018:ffff888004b6fcf0 EFLAGS: 00010046 [ 36.625072] RAX: 0000000000000000 RBX: 043600a000000060 RCX: ffffffff9fc0e0d7 [ 36.627206] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffff888004b6fcf0 [ 36.629813] RBP: ffff888004b6fcf0 R08: dffffc0000000000 R09: ffffed100096df9f [ 36.631974] R10: dfffe9100096dfa0 R11: 1ffff1100096df9e R12: ffff888005960020 [ 36.634285] R13: ffff8880059600f0 R14: 0000000000000246 R15: 0000000000000001 [ 36.636438] FS: 0000000000000000(0000) GS:ffff88806d600000(0000) knlGS:0000000000000000 [ 36.639092] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 36.640951] CR2: 00007f07476819a3 CR3: 0000000004a34000 CR4: 00000000000006f0 [ 36.643411] Call Trace: [ 36.644215] [ 36.644902] smscore_getbuffer+0x3e/0x1e0 [ 36.646147] do_submit_urb+0x4f/0x190 [ 36.647449] process_one_work+0x34c/0x5b0 [ 36.648777] worker_thread+0x4b7/0x890 [ 36.649984] ? worker_clr_flags+0x90/0x90 [ 36.651166] kthread+0x166/0x190 [ 36.652151] ? kthread_blkcg+0x50/0x50 [ 36.653547] ret_from_fork+0x22/0x30 [ 36.655051] [ 36.655733] Modules linked in: [ 36.656787] ---[ end trace 0000000000000000 ]--- [ 36.658328] RIP: 0010:_raw_spin_lock_irqsave+0x8a/0xd0 [ 36.660045] Code: 24 00 00 00 00 48 89 df be 04 00 00 00 e8 9e b5 c6 fe 48 89 ef be 04 00 5 [ 36.665730] RSP: 0018:ffff888004b6fcf0 EFLAGS: 00010046 [ 36.667448] RAX: 0000000000000000 RBX: 043600a000000060 RCX: ffffffff9fc0e0d7 [ 36.669675] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffff888004b6fcf0 [ 36.672645] RBP: ffff888004b6fcf0 R08: dffffc0000000000 R09: ffffed100096df9f [ 36.674921] R10: dfffe9100096dfa0 R11: 1ffff1100096df9e R12: ffff888005960020 [ 36.677034] R13: ffff8880059600f0 R14: 0000000000000246 R15: 0000000000000001 [ 36.679184] FS: 0000000000000000(0000) GS:ffff88806d600000(0000) knlGS:0000000000000000 [ 36.681655] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 36.683383] CR2: 00007f07476819a3 CR3: 0000000004a34000 CR4: 00000000000006f0 [ 36.685733] Kernel panic - not syncing: Fatal exception [ 36.688585] Kernel Offset: 0x1d400000 from 0xffffffff81000000 (relocation range: 0xfffffff) [ 36.692199] ---[ end Kernel panic - not syncing: Fatal exception ]--- When the siano device is plugged in, it may call the following functions to initialize the device. smsusb_probe()-->smsusb_init_device()-->smscore_start_device(). When smscore_start_device() gets failed, the function smsusb_term_device() will be called and smsusb_device_t will be deallocated. Although we use usb_kill_urb() in smsusb_stop_streaming() to cancel transfer requests and wait for them to finish, the worker threads that are scheduled by smsusb_onresponse() may be still running. As a result, the UAF bugs could happen. We add cancel_work_sync() in smsusb_stop_streaming() in order that the worker threads could finish before the smsusb_device_t is deallocated. Fixes: dd47fbd40e6e ("[media] smsusb: don't sleep while atomic") Signed-off-by: Duoming Zhou Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/siano/smsusb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index df4c5dcba39c..1babfe6e2c36 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -179,6 +179,7 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev) for (i = 0; i < MAX_URBS; i++) { usb_kill_urb(&dev->surbs[i].urb); + cancel_work_sync(&dev->surbs[i].wq); if (dev->surbs[i].cb) { smscore_putbuffer(dev->coredev, dev->surbs[i].cb); From 2b72ceef174041b9e74fd2897876841737fd8f19 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Thu, 26 Jan 2023 12:00:59 +0100 Subject: [PATCH 0393/1017] media: saa7134: Use video_unregister_device for radio_dev [ Upstream commit bc7635c6435c77a0c168e2cc6535740adfaff4e4 ] The radio device doesn't use vb2, thus calling vb2_video_unregister_device() which results in the following warning being printed on module unload. WARNING: CPU: 1 PID: 215963 at drivers/media/common/videobuf2/videobuf2-v4l2.c:1236 vb2_video_unregister_device+0xc6/0xe0 [videobuf2_v4l2] Fixes: 11788d9b7e91 ("media: media/pci: use vb2_video_unregister_device()") Signed-off-by: Tasos Sahanidis Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/pci/saa7134/saa7134-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index efb757d5168a..e97c30070fc6 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -977,7 +977,7 @@ static void saa7134_unregister_video(struct saa7134_dev *dev) } if (dev->radio_dev) { if (video_is_registered(dev->radio_dev)) - vb2_video_unregister_device(dev->radio_dev); + video_unregister_device(dev->radio_dev); else video_device_release(dev->radio_dev); dev->radio_dev = NULL; From 91f9d708716daf9dfc4d585ff57ef5ef05b69437 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 14 Feb 2023 15:42:31 -0800 Subject: [PATCH 0394/1017] rpmsg: glink: Avoid infinite loop on intent for missing channel [ Upstream commit 3e74ec2f39362bffbd42854acbb67c7f4cb808f9 ] In the event that an intent advertisement arrives on an unknown channel the fifo is not advanced, resulting in the same message being handled over and over. Fixes: dacbb35e930f ("rpmsg: glink: Receive and store the remote intent buffers") Signed-off-by: Bjorn Andersson Reviewed-by: Chris Lew Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230214234231.2069751-1-quic_bjorande@quicinc.com Signed-off-by: Sasha Levin --- drivers/rpmsg/qcom_glink_native.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 7cbed0310c09..98b6d4c09c82 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -929,6 +929,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, spin_unlock_irqrestore(&glink->idr_lock, flags); if (!channel) { dev_err(glink->dev, "intents for non-existing channel\n"); + qcom_glink_rx_advance(glink, ALIGN(msglen, 8)); return; } From f34cc701ea0a0a915b17ad5b108341bd78e8a634 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 29 Sep 2022 16:34:45 +0200 Subject: [PATCH 0395/1017] udf: Define EFSCORRUPTED error code [ Upstream commit 3d2d7e61553dbcc8ba45201d8ae4f383742c8202 ] Similarly to other filesystems define EFSCORRUPTED error code for reporting internal filesystem corruption. Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/udf_sb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 4fa620543d30..2205859731dc 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -51,6 +51,8 @@ #define MF_DUPLICATE_MD 0x01 #define MF_MIRROR_FE_LOADED 0x02 +#define EFSCORRUPTED EUCLEAN + struct udf_meta_data { __u32 s_meta_file_loc; __u32 s_mirror_file_loc; From 199624f3144d79fab1cff533ce6a4b82390520a3 Mon Sep 17 00:00:00 2001 From: Markuss Broks Date: Sat, 21 Jan 2023 22:18:42 +0200 Subject: [PATCH 0396/1017] ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy [ Upstream commit 5d5aa219a790d61cad2c38e1aa32058f16ad2f0b ] For some reason, the driver adding support for Exynos5420 MIPI phy back in 2016 wasn't used on Exynos5420, which caused a kernel panic. Add the proper compatible for it. Signed-off-by: Markuss Broks Link: https://lore.kernel.org/r/20230121201844.46872-2-markuss.broks@gmail.com Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin --- arch/arm/boot/dts/exynos5420.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 83580f076a58..34886535f847 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -605,7 +605,7 @@ }; mipi_phy: mipi-video-phy { - compatible = "samsung,s5pv210-mipi-video-phy"; + compatible = "samsung,exynos5420-mipi-video-phy"; syscon = <&pmu_system_controller>; #phy-cells = <1>; }; From 6e291810fe83a384700eb24a1f714966391ed562 Mon Sep 17 00:00:00 2001 From: Li Nan Date: Tue, 17 Jan 2023 15:08:05 +0800 Subject: [PATCH 0397/1017] blk-iocost: fix divide by 0 error in calc_lcoefs() [ Upstream commit 984af1e66b4126cf145153661cc24c213e2ec231 ] echo max of u64 to cost.model can cause divide by 0 error. # echo 8:0 rbps=18446744073709551615 > /sys/fs/cgroup/io.cost.model divide error: 0000 [#1] PREEMPT SMP RIP: 0010:calc_lcoefs+0x4c/0xc0 Call Trace: ioc_refresh_params+0x2b3/0x4f0 ioc_cost_model_write+0x3cb/0x4c0 ? _copy_from_iter+0x6d/0x6c0 ? kernfs_fop_write_iter+0xfc/0x270 cgroup_file_write+0xa0/0x200 kernfs_fop_write_iter+0x17d/0x270 vfs_write+0x414/0x620 ksys_write+0x73/0x160 __x64_sys_write+0x1e/0x30 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd calc_lcoefs() uses the input value of cost.model in DIV_ROUND_UP_ULL, overflow would happen if bps plus IOC_PAGE_SIZE is greater than ULLONG_MAX, it can cause divide by 0 error. Fix the problem by setting basecost Signed-off-by: Li Nan Signed-off-by: Yu Kuai Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20230117070806.3857142-5-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/blk-iocost.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/block/blk-iocost.c b/block/blk-iocost.c index fb8f959a7f32..9255b642d6ad 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -872,9 +872,14 @@ static void calc_lcoefs(u64 bps, u64 seqiops, u64 randiops, *page = *seqio = *randio = 0; - if (bps) - *page = DIV64_U64_ROUND_UP(VTIME_PER_SEC, - DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE)); + if (bps) { + u64 bps_pages = DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE); + + if (bps_pages) + *page = DIV64_U64_ROUND_UP(VTIME_PER_SEC, bps_pages); + else + *page = 1; + } if (seqiops) { v = DIV64_U64_ROUND_UP(VTIME_PER_SEC, seqiops); From 99ff971b62e5bd5dee65bbe9777375206f5db791 Mon Sep 17 00:00:00 2001 From: Minsuk Kang Date: Mon, 5 Dec 2022 10:43:08 +0900 Subject: [PATCH 0398/1017] wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f099c5c9e2ba08a379bd354a82e05ef839ae29ac ] This patch fixes a use-after-free in ath9k that occurs in ath9k_hif_usb_disconnect() when ath9k_destroy_wmi() is trying to access 'drv_priv' that has already been freed by ieee80211_free_hw(), called by ath9k_htc_hw_deinit(). The patch moves ath9k_destroy_wmi() before ieee80211_free_hw(). Note that urbs from the driver should be killed before freeing 'wmi' with ath9k_destroy_wmi() as their callbacks will access 'wmi'. Found by a modified version of syzkaller. ================================================================== BUG: KASAN: use-after-free in ath9k_destroy_wmi+0x38/0x40 Read of size 8 at addr ffff8881069132a0 by task kworker/0:1/7 CPU: 0 PID: 7 Comm: kworker/0:1 Tainted: G O 5.14.0+ #131 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Workqueue: usb_hub_wq hub_event Call Trace: dump_stack_lvl+0x8e/0xd1 print_address_description.constprop.0.cold+0x93/0x334 ? ath9k_destroy_wmi+0x38/0x40 ? ath9k_destroy_wmi+0x38/0x40 kasan_report.cold+0x83/0xdf ? ath9k_destroy_wmi+0x38/0x40 ath9k_destroy_wmi+0x38/0x40 ath9k_hif_usb_disconnect+0x329/0x3f0 ? ath9k_hif_usb_suspend+0x120/0x120 ? usb_disable_interface+0xfc/0x180 usb_unbind_interface+0x19b/0x7e0 ? usb_autoresume_device+0x50/0x50 device_release_driver_internal+0x44d/0x520 bus_remove_device+0x2e5/0x5a0 device_del+0x5b2/0xe30 ? __device_link_del+0x370/0x370 ? usb_remove_ep_devs+0x43/0x80 ? remove_intf_ep_devs+0x112/0x1a0 usb_disable_device+0x1e3/0x5a0 usb_disconnect+0x267/0x870 hub_event+0x168d/0x3950 ? rcu_read_lock_sched_held+0xa1/0xd0 ? hub_port_debounce+0x2e0/0x2e0 ? check_irq_usage+0x860/0xf20 ? drain_workqueue+0x281/0x360 ? lock_release+0x640/0x640 ? rcu_read_lock_sched_held+0xa1/0xd0 ? rcu_read_lock_bh_held+0xb0/0xb0 ? lockdep_hardirqs_on_prepare+0x273/0x3e0 process_one_work+0x92b/0x1460 ? pwq_dec_nr_in_flight+0x330/0x330 ? rwlock_bug.part.0+0x90/0x90 worker_thread+0x95/0xe00 ? __kthread_parkme+0x115/0x1e0 ? process_one_work+0x1460/0x1460 kthread+0x3a1/0x480 ? set_kthread_struct+0x120/0x120 ret_from_fork+0x1f/0x30 The buggy address belongs to the page: page:ffffea00041a44c0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x106913 flags: 0x200000000000000(node=0|zone=2) raw: 0200000000000000 0000000000000000 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected page_owner tracks the page as freed page last allocated via order 3, migratetype Unmovable, gfp_mask 0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), pid 7, ts 38347963444, free_ts 41399957635 prep_new_page+0x1aa/0x240 get_page_from_freelist+0x159a/0x27c0 __alloc_pages+0x2da/0x6a0 alloc_pages+0xec/0x1e0 kmalloc_order+0x39/0xf0 kmalloc_order_trace+0x19/0x120 __kmalloc+0x308/0x390 wiphy_new_nm+0x6f5/0x1dd0 ieee80211_alloc_hw_nm+0x36d/0x2230 ath9k_htc_probe_device+0x9d/0x1e10 ath9k_htc_hw_init+0x34/0x50 ath9k_hif_usb_firmware_cb+0x25f/0x4e0 request_firmware_work_func+0x131/0x240 process_one_work+0x92b/0x1460 worker_thread+0x95/0xe00 kthread+0x3a1/0x480 page last free stack trace: free_pcp_prepare+0x3d3/0x7f0 free_unref_page+0x1e/0x3d0 device_release+0xa4/0x240 kobject_put+0x186/0x4c0 put_device+0x20/0x30 ath9k_htc_disconnect_device+0x1cf/0x2c0 ath9k_htc_hw_deinit+0x26/0x30 ath9k_hif_usb_disconnect+0x2d9/0x3f0 usb_unbind_interface+0x19b/0x7e0 device_release_driver_internal+0x44d/0x520 bus_remove_device+0x2e5/0x5a0 device_del+0x5b2/0xe30 usb_disable_device+0x1e3/0x5a0 usb_disconnect+0x267/0x870 hub_event+0x168d/0x3950 process_one_work+0x92b/0x1460 Memory state around the buggy address: ffff888106913180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff888106913200: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff >ffff888106913280: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ^ ffff888106913300: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff888106913380: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ================================================================== Reported-by: Dokyung Song Reported-by: Jisoo Jang Reported-by: Minsuk Kang Signed-off-by: Minsuk Kang Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221205014308.1617597-1-linuxlovemin@yonsei.ac.kr Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/hif_usb.c | 2 -- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index de6c0824c9ca..f521dfa2f194 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -1424,8 +1424,6 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (hif_dev->flags & HIF_USB_READY) { ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_hif_usb_dev_deinit(hif_dev); - ath9k_destroy_wmi(hif_dev->htc_handle->drv_priv); ath9k_htc_hw_free(hif_dev->htc_handle); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 07ac88fb1c57..96a3185a96d7 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -988,6 +988,8 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) ath9k_deinit_device(htc_handle->drv_priv); ath9k_stop_wmi(htc_handle->drv_priv); + ath9k_hif_usb_dealloc_urbs((struct hif_device_usb *)htc_handle->hif_dev); + ath9k_destroy_wmi(htc_handle->drv_priv); ieee80211_free_hw(htc_handle->drv_priv->hw); } } From d6ef66194bb4a6c18f5b9649bf62597909b040e4 Mon Sep 17 00:00:00 2001 From: Jisoo Jang Date: Tue, 15 Nov 2022 13:34:58 +0900 Subject: [PATCH 0399/1017] wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds() [ Upstream commit 0a06cadcc2a0044e4a117cc0e61436fc3a0dad69 ] This patch fixes a stack-out-of-bounds read in brcmfmac that occurs when 'buf' that is not null-terminated is passed as an argument of strsep() in brcmf_c_preinit_dcmds(). This buffer is filled with a firmware version string by memcpy() in brcmf_fil_iovar_data_get(). The patch ensures buf is null-terminated. Found by a modified version of syzkaller. [ 47.569679][ T1897] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43236b for chip BCM43236/3 [ 47.582839][ T1897] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available [ 47.601565][ T1897] ================================================================== [ 47.602574][ T1897] BUG: KASAN: stack-out-of-bounds in strsep+0x1b2/0x1f0 [ 47.603447][ T1897] Read of size 1 at addr ffffc90001f6f000 by task kworker/0:2/1897 [ 47.604336][ T1897] [ 47.604621][ T1897] CPU: 0 PID: 1897 Comm: kworker/0:2 Tainted: G O 5.14.0+ #131 [ 47.605617][ T1897] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 [ 47.606907][ T1897] Workqueue: usb_hub_wq hub_event [ 47.607453][ T1897] Call Trace: [ 47.607801][ T1897] dump_stack_lvl+0x8e/0xd1 [ 47.608295][ T1897] print_address_description.constprop.0.cold+0xf/0x334 [ 47.609009][ T1897] ? strsep+0x1b2/0x1f0 [ 47.609434][ T1897] ? strsep+0x1b2/0x1f0 [ 47.609863][ T1897] kasan_report.cold+0x83/0xdf [ 47.610366][ T1897] ? strsep+0x1b2/0x1f0 [ 47.610882][ T1897] strsep+0x1b2/0x1f0 [ 47.611300][ T1897] ? brcmf_fil_iovar_data_get+0x3a/0xf0 [ 47.611883][ T1897] brcmf_c_preinit_dcmds+0x995/0xc40 [ 47.612434][ T1897] ? brcmf_c_set_joinpref_default+0x100/0x100 [ 47.613078][ T1897] ? rcu_read_lock_sched_held+0xa1/0xd0 [ 47.613662][ T1897] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 47.614208][ T1897] ? lock_acquire+0x19d/0x4e0 [ 47.614704][ T1897] ? find_held_lock+0x2d/0x110 [ 47.615236][ T1897] ? brcmf_usb_deq+0x1a7/0x260 [ 47.615741][ T1897] ? brcmf_usb_rx_fill_all+0x5a/0xf0 [ 47.616288][ T1897] brcmf_attach+0x246/0xd40 [ 47.616758][ T1897] ? wiphy_new_nm+0x1703/0x1dd0 [ 47.617280][ T1897] ? kmemdup+0x43/0x50 [ 47.617720][ T1897] brcmf_usb_probe+0x12de/0x1690 [ 47.618244][ T1897] ? brcmf_usbdev_qinit.constprop.0+0x470/0x470 [ 47.618901][ T1897] usb_probe_interface+0x2aa/0x760 [ 47.619429][ T1897] ? usb_probe_device+0x250/0x250 [ 47.619950][ T1897] really_probe+0x205/0xb70 [ 47.620435][ T1897] ? driver_allows_async_probing+0x130/0x130 [ 47.621048][ T1897] __driver_probe_device+0x311/0x4b0 [ 47.621595][ T1897] ? driver_allows_async_probing+0x130/0x130 [ 47.622209][ T1897] driver_probe_device+0x4e/0x150 [ 47.622739][ T1897] __device_attach_driver+0x1cc/0x2a0 [ 47.623287][ T1897] bus_for_each_drv+0x156/0x1d0 [ 47.623796][ T1897] ? bus_rescan_devices+0x30/0x30 [ 47.624309][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 47.624907][ T1897] ? trace_hardirqs_on+0x46/0x160 [ 47.625437][ T1897] __device_attach+0x23f/0x3a0 [ 47.625924][ T1897] ? device_bind_driver+0xd0/0xd0 [ 47.626433][ T1897] ? kobject_uevent_env+0x287/0x14b0 [ 47.627057][ T1897] bus_probe_device+0x1da/0x290 [ 47.627557][ T1897] device_add+0xb7b/0x1eb0 [ 47.628027][ T1897] ? wait_for_completion+0x290/0x290 [ 47.628593][ T1897] ? __fw_devlink_link_to_suppliers+0x5a0/0x5a0 [ 47.629249][ T1897] usb_set_configuration+0xf59/0x16f0 [ 47.629829][ T1897] usb_generic_driver_probe+0x82/0xa0 [ 47.630385][ T1897] usb_probe_device+0xbb/0x250 [ 47.630927][ T1897] ? usb_suspend+0x590/0x590 [ 47.631397][ T1897] really_probe+0x205/0xb70 [ 47.631855][ T1897] ? driver_allows_async_probing+0x130/0x130 [ 47.632469][ T1897] __driver_probe_device+0x311/0x4b0 [ 47.633002][ T1897] ? usb_generic_driver_match+0x75/0x90 [ 47.633573][ T1897] ? driver_allows_async_probing+0x130/0x130 [ 47.634170][ T1897] driver_probe_device+0x4e/0x150 [ 47.634703][ T1897] __device_attach_driver+0x1cc/0x2a0 [ 47.635248][ T1897] bus_for_each_drv+0x156/0x1d0 [ 47.635748][ T1897] ? bus_rescan_devices+0x30/0x30 [ 47.636271][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 47.636881][ T1897] ? trace_hardirqs_on+0x46/0x160 [ 47.637396][ T1897] __device_attach+0x23f/0x3a0 [ 47.637904][ T1897] ? device_bind_driver+0xd0/0xd0 [ 47.638426][ T1897] ? kobject_uevent_env+0x287/0x14b0 [ 47.638985][ T1897] bus_probe_device+0x1da/0x290 [ 47.639512][ T1897] device_add+0xb7b/0x1eb0 [ 47.639977][ T1897] ? __fw_devlink_link_to_suppliers+0x5a0/0x5a0 [ 47.640612][ T1897] ? kfree+0x14a/0x6b0 [ 47.641055][ T1897] ? __usb_get_extra_descriptor+0x116/0x160 [ 47.641679][ T1897] usb_new_device.cold+0x49c/0x1029 [ 47.642245][ T1897] ? hub_disconnect+0x450/0x450 [ 47.642756][ T1897] ? rwlock_bug.part.0+0x90/0x90 [ 47.643273][ T1897] ? _raw_spin_unlock_irq+0x24/0x30 [ 47.643822][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 47.644445][ T1897] hub_event+0x1c98/0x3950 [ 47.644939][ T1897] ? hub_port_debounce+0x2e0/0x2e0 [ 47.645467][ T1897] ? check_irq_usage+0x861/0xf20 [ 47.645975][ T1897] ? drain_workqueue+0x280/0x360 [ 47.646506][ T1897] ? lock_release+0x640/0x640 [ 47.646994][ T1897] ? rcu_read_lock_sched_held+0xa1/0xd0 [ 47.647572][ T1897] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 47.648111][ T1897] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 47.648735][ T1897] process_one_work+0x92b/0x1460 [ 47.649262][ T1897] ? pwq_dec_nr_in_flight+0x330/0x330 [ 47.649816][ T1897] ? rwlock_bug.part.0+0x90/0x90 [ 47.650336][ T1897] worker_thread+0x95/0xe00 [ 47.650830][ T1897] ? __kthread_parkme+0x115/0x1e0 [ 47.651361][ T1897] ? process_one_work+0x1460/0x1460 [ 47.651904][ T1897] kthread+0x3a1/0x480 [ 47.652329][ T1897] ? set_kthread_struct+0x120/0x120 [ 47.652878][ T1897] ret_from_fork+0x1f/0x30 [ 47.653370][ T1897] [ 47.653608][ T1897] [ 47.653848][ T1897] addr ffffc90001f6f000 is located in stack of task kworker/0:2/1897 at offset 512 in frame: [ 47.654891][ T1897] brcmf_c_preinit_dcmds+0x0/0xc40 [ 47.655442][ T1897] [ 47.655690][ T1897] this frame has 4 objects: [ 47.656151][ T1897] [48, 56) 'ptr' [ 47.656159][ T1897] [80, 148) 'revinfo' [ 47.656534][ T1897] [192, 210) 'eventmask' [ 47.656953][ T1897] [256, 512) 'buf' [ 47.657410][ T1897] [ 47.658035][ T1897] Memory state around the buggy address: [ 47.658743][ T1897] ffffc90001f6ef00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 47.659577][ T1897] ffffc90001f6ef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 47.660394][ T1897] >ffffc90001f6f000: f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 [ 47.661199][ T1897] ^ [ 47.661625][ T1897] ffffc90001f6f080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 47.662455][ T1897] ffffc90001f6f100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 [ 47.663318][ T1897] ================================================================== [ 47.664147][ T1897] Disabling lock debugging due to kernel taint Reported-by: Dokyung Song Reported-by: Jisoo Jang Reported-by: Minsuk Kang Signed-off-by: Jisoo Jang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221115043458.37562-1-jisoo.jang@yonsei.ac.kr Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index e3758bd86acf..57bb1fbedaa8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -264,6 +264,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) err); goto done; } + buf[sizeof(buf) - 1] = '\0'; ptr = (char *)buf; strsep(&ptr, "\n"); From f5657f3306031d4ee338d1a91ea5115f0f9c7af7 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 14 Dec 2022 11:41:44 -0800 Subject: [PATCH 0400/1017] rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks [ Upstream commit 0cae5ded535c3a80aed94f119bbd4ee3ae284a65 ] Currently, RCU_LOCKDEP_WARN() checks the condition before checking to see if lockdep is still enabled. This is necessary to avoid the false-positive splats fixed by commit 3066820034b5dd ("rcu: Reject RCU_LOCKDEP_WARN() false positives"). However, the current state can result in false-positive splats during early boot before lockdep is fully initialized. This commit therefore checks debug_lockdep_rcu_enabled() both before and after checking the condition, thus avoiding both sets of false-positive error reports. Reported-by: Steven Rostedt Reported-by: Masami Hiramatsu (Google) Reported-by: Mathieu Desnoyers Signed-off-by: Paul E. McKenney Reviewed-by: Mathieu Desnoyers Cc: Boqun Feng Cc: Matthew Wilcox Cc: Thomas Gleixner Signed-off-by: Sasha Levin --- include/linux/rcupdate.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 1f46db38d6ec..ef8d56b18da6 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -308,11 +308,18 @@ static inline int rcu_read_lock_any_held(void) * RCU_LOCKDEP_WARN - emit lockdep splat if specified condition is met * @c: condition to check * @s: informative message + * + * This checks debug_lockdep_rcu_enabled() before checking (c) to + * prevent early boot splats due to lockdep not yet being initialized, + * and rechecks it after checking (c) to prevent false-positive splats + * due to races with lockdep being disabled. See commit 3066820034b5dd + * ("rcu: Reject RCU_LOCKDEP_WARN() false positives") for more detail. */ #define RCU_LOCKDEP_WARN(c, s) \ do { \ static bool __section(".data.unlikely") __warned; \ - if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \ + if (debug_lockdep_rcu_enabled() && (c) && \ + debug_lockdep_rcu_enabled() && !__warned) { \ __warned = true; \ lockdep_rcu_suspicious(__FILE__, __LINE__, s); \ } \ From 2bf501f1bc78883222bba17aad9402deae11ef1e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 16 Dec 2022 15:55:48 -0800 Subject: [PATCH 0401/1017] rcu: Suppress smp_processor_id() complaint in synchronize_rcu_expedited_wait() [ Upstream commit 2d7f00b2f01301d6e41fd4a28030dab0442265be ] The normal grace period's RCU CPU stall warnings are invoked from the scheduling-clock interrupt handler, and can thus invoke smp_processor_id() with impunity, which allows them to directly invoke dump_cpu_task(). In contrast, the expedited grace period's RCU CPU stall warnings are invoked from process context, which causes the dump_cpu_task() function's calls to smp_processor_id() to complain bitterly in debug kernels. This commit therefore causes synchronize_rcu_expedited_wait() to disable preemption around its call to dump_cpu_task(). Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/tree_exp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h index 0dc16345e668..ef6570137dcd 100644 --- a/kernel/rcu/tree_exp.h +++ b/kernel/rcu/tree_exp.h @@ -564,7 +564,9 @@ static void synchronize_rcu_expedited_wait(void) mask = leaf_node_cpu_bit(rnp, cpu); if (!(READ_ONCE(rnp->expmask) & mask)) continue; + preempt_disable(); // For smp_processor_id() in dump_cpu_task(). dump_cpu_task(cpu); + preempt_enable(); } } jiffies_stall = 3 * rcu_jiffies_till_stall_check() + 3; From d99d194e2f8c7809ebf8b27f345b6ce9a87c17bd Mon Sep 17 00:00:00 2001 From: Zqiang Date: Thu, 1 Dec 2022 07:45:33 +0800 Subject: [PATCH 0402/1017] rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug [ Upstream commit ea5c8987fef20a8cca07e428aa28bc64649c5104 ] The synchronize_rcu_tasks_rude() function invokes rcu_tasks_rude_wait_gp() to wait one rude RCU-tasks grace period. The rcu_tasks_rude_wait_gp() function in turn checks if there is only a single online CPU. If so, it will immediately return, because a call to synchronize_rcu_tasks_rude() is by definition a grace period on a single-CPU system. (We could have blocked!) Unfortunately, this check uses num_online_cpus() without synchronization, which can result in too-short grace periods. To see this, consider the following scenario: CPU0 CPU1 (going offline) migration/1 task: cpu_stopper_thread -> take_cpu_down -> _cpu_disable (dec __num_online_cpus) ->cpuhp_invoke_callback preempt_disable access old_data0 task1 del old_data0 ..... synchronize_rcu_tasks_rude() task1 schedule out .... task2 schedule in rcu_tasks_rude_wait_gp() ->__num_online_cpus == 1 ->return .... task1 schedule in ->free old_data0 preempt_enable When CPU1 decrements __num_online_cpus, its value becomes 1. However, CPU1 has not finished going offline, and will take one last trip through the scheduler and the idle loop before it actually stops executing instructions. Because synchronize_rcu_tasks_rude() is mostly used for tracing, and because both the scheduler and the idle loop can be traced, this means that CPU0's prematurely ended grace period might disrupt the tracing on CPU1. Given that this disruption might include CPU1 executing instructions in memory that was just now freed (and maybe reallocated), this is a matter of some concern. This commit therefore removes that problematic single-CPU check from the rcu_tasks_rude_wait_gp() function. This dispenses with the single-CPU optimization, but there is no evidence indicating that this optimization is important. In addition, synchronize_rcu_tasks_generic() contains a similar optimization (albeit only for early boot), which also splats. (As in exactly why are you invoking synchronize_rcu_tasks_rude() so early in boot, anyway???) It is OK for the synchronize_rcu_tasks_rude() function's check to be unsynchronized because the only times that this check can evaluate to true is when there is only a single CPU running with preemption disabled. While in the area, this commit also fixes a minor bug in which a call to synchronize_rcu_tasks_rude() would instead be attributed to synchronize_rcu_tasks(). [ paulmck: Add "synchronize_" prefix and "()" suffix. ] Signed-off-by: Zqiang Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/tasks.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index df8143c8a6a8..c66d47685b28 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -171,8 +171,9 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func, static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp) { /* Complain if the scheduler has not started. */ - WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE, - "synchronize_rcu_tasks called too soon"); + if (WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE, + "synchronize_%s() called too soon", rtp->name)) + return; /* Wait for the grace period. */ wait_rcu_gp(rtp->call_func); @@ -648,9 +649,6 @@ static void rcu_tasks_be_rude(struct work_struct *work) // Wait for one rude RCU-tasks grace period. static void rcu_tasks_rude_wait_gp(struct rcu_tasks *rtp) { - if (num_online_cpus() <= 1) - return; // Fastpath for only one CPU. - rtp->n_ipis += cpumask_weight(cpu_online_mask); schedule_on_each_cpu(rcu_tasks_be_rude); } From 744e538dcf27f06b44a4f50eb45c0f2417747d18 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Thu, 22 Dec 2022 19:15:59 +0200 Subject: [PATCH 0403/1017] wifi: ath11k: debugfs: fix to work with multiple PCI devices [ Upstream commit 323d91d4684d238f6bc3693fed93caf795378fe0 ] ath11k fails to load if there are multiple ath11k PCI devices with same name: ath11k_pci 0000:01:00.0: Hardware name qcn9074 hw1.0 debugfs: Directory 'ath11k' with parent '/' already present! ath11k_pci 0000:01:00.0: failed to create ath11k debugfs ath11k_pci 0000:01:00.0: failed to create soc core: -17 ath11k_pci 0000:01:00.0: failed to init core: -17 ath11k_pci: probe of 0000:01:00.0 failed with error -17 Fix this by creating a directory for each ath11k device using schema -, for example "pci-0000:06:00.0". This directory created under the top-level ath11k directory, for example /sys/kernel/debug/ath11k. The reference to the toplevel ath11k directory is not stored anymore within ath11k, instead it's retrieved using debugfs_lookup(). If the directory does not exist it will be created. After the last directory from the ath11k directory is removed, for example when doing rmmod ath11k, the empty ath11k directory is left in place, it's a minor cosmetic issue anyway. Here's an example hierarchy with one WCN6855: ath11k `-- pci-0000:06:00.0 |-- mac0 | |-- dfs_block_radar_events | |-- dfs_simulate_radar | |-- ext_rx_stats | |-- ext_tx_stats | |-- fw_dbglog_config | |-- fw_stats | | |-- beacon_stats | | |-- pdev_stats | | `-- vdev_stats | |-- htt_stats | |-- htt_stats_reset | |-- htt_stats_type | `-- pktlog_filter |-- simulate_fw_crash `-- soc_dp_stats I didn't have a test setup where I could connect multiple ath11k devices to the same the host, so I have only tested this with one device. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.9 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 Tested-by: Robert Marko Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221220121231.20120-1-kvalo@kernel.org Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/core.h | 1 - drivers/net/wireless/ath/ath11k/debugfs.c | 48 +++++++++++++++++++---- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index d2f2898d17b4..a66e275af1eb 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -712,7 +712,6 @@ struct ath11k_base { enum ath11k_dfs_region dfs_region; #ifdef CONFIG_ATH11K_DEBUGFS struct dentry *debugfs_soc; - struct dentry *debugfs_ath11k; #endif struct ath11k_soc_dp_stats soc_stats; diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 1b914e67d314..196314ab4ff0 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -836,10 +836,6 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab) if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) return 0; - ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k); - if (IS_ERR(ab->debugfs_soc)) - return PTR_ERR(ab->debugfs_soc); - debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, &fops_simulate_fw_crash); @@ -857,15 +853,51 @@ void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab) int ath11k_debugfs_soc_create(struct ath11k_base *ab) { - ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL); + struct dentry *root; + bool dput_needed; + char name[64]; + int ret; - return PTR_ERR_OR_ZERO(ab->debugfs_ath11k); + root = debugfs_lookup("ath11k", NULL); + if (!root) { + root = debugfs_create_dir("ath11k", NULL); + if (IS_ERR_OR_NULL(root)) + return PTR_ERR(root); + + dput_needed = false; + } else { + /* a dentry from lookup() needs dput() after we don't use it */ + dput_needed = true; + } + + scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus), + dev_name(ab->dev)); + + ab->debugfs_soc = debugfs_create_dir(name, root); + if (IS_ERR_OR_NULL(ab->debugfs_soc)) { + ret = PTR_ERR(ab->debugfs_soc); + goto out; + } + + ret = 0; + +out: + if (dput_needed) + dput(root); + + return ret; } void ath11k_debugfs_soc_destroy(struct ath11k_base *ab) { - debugfs_remove_recursive(ab->debugfs_ath11k); - ab->debugfs_ath11k = NULL; + debugfs_remove_recursive(ab->debugfs_soc); + ab->debugfs_soc = NULL; + + /* We are not removing ath11k directory on purpose, even if it + * would be empty. This simplifies the directory handling and it's + * a minor cosmetic issue to leave an empty ath11k directory to + * debugfs. + */ } void ath11k_debugfs_fw_stats_init(struct ath11k *ar) From 781bff0a532fd9590eff75cc99634d2e75ae6625 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 6 Jan 2023 08:59:51 +0800 Subject: [PATCH 0404/1017] thermal: intel: Fix unsigned comparison with less than zero [ Upstream commit e7fcfe67f9f410736b758969477b17ea285e8e6c ] The return value from the call to intel_tcc_get_tjmax() is int, which can be a negative error code. However, the return value is being assigned to an u32 variable 'tj_max', so making 'tj_max' an int. Eliminate the following warning: ./drivers/thermal/intel/intel_soc_dts_iosf.c:394:5-11: WARNING: Unsigned expression compared with zero: tj_max < 0 Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3637 Reported-by: Abaci Robot Signed-off-by: Yang Li Acked-by: Zhang Rui Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/intel/intel_soc_dts_iosf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c index 4f1a2f7c016c..8d6707e48d02 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -404,7 +404,7 @@ struct intel_soc_dts_sensors *intel_soc_dts_iosf_init( { struct intel_soc_dts_sensors *sensors; bool notification; - u32 tj_max; + int tj_max; int ret; int i; From 6ef02cdb5a304cd06eba6724975b5d9d2991afad Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 5 Jan 2023 14:44:03 +0100 Subject: [PATCH 0405/1017] timers: Prevent union confusion from unexpected restart_syscall() [ Upstream commit 9f76d59173d9d146e96c66886b671c1915a5c5e5 ] The nanosleep syscalls use the restart_block mechanism, with a quirk: The `type` and `rmtp`/`compat_rmtp` fields are set up unconditionally on syscall entry, while the rest of the restart_block is only set up in the unlikely case that the syscall is actually interrupted by a signal (or pseudo-signal) that doesn't have a signal handler. If the restart_block was set up by a previous syscall (futex(..., FUTEX_WAIT, ...) or poll()) and hasn't been invalidated somehow since then, this will clobber some of the union fields used by futex_wait_restart() and do_restart_poll(). If userspace afterwards wrongly calls the restart_syscall syscall, futex_wait_restart()/do_restart_poll() will read struct fields that have been clobbered. This doesn't actually lead to anything particularly interesting because none of the union fields contain trusted kernel data, and futex(..., FUTEX_WAIT, ...) and poll() aren't syscalls where it makes much sense to apply seccomp filters to their arguments. So the current consequences are just of the "if userspace does bad stuff, it can damage itself, and that's not a problem" flavor. But still, it seems like a hazard for future developers, so invalidate the restart_block when partly setting it up in the nanosleep syscalls. Signed-off-by: Jann Horn Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20230105134403.754986-1-jannh@google.com Signed-off-by: Sasha Levin --- kernel/time/hrtimer.c | 2 ++ kernel/time/posix-stubs.c | 2 ++ kernel/time/posix-timers.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 544ce87ba38a..70deb2f01e97 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2024,6 +2024,7 @@ SYSCALL_DEFINE2(nanosleep, struct __kernel_timespec __user *, rqtp, if (!timespec64_valid(&tu)) return -EINVAL; + current->restart_block.fn = do_no_restart_syscall; current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; current->restart_block.nanosleep.rmtp = rmtp; return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL, @@ -2045,6 +2046,7 @@ SYSCALL_DEFINE2(nanosleep_time32, struct old_timespec32 __user *, rqtp, if (!timespec64_valid(&tu)) return -EINVAL; + current->restart_block.fn = do_no_restart_syscall; current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; current->restart_block.nanosleep.compat_rmtp = rmtp; return hrtimer_nanosleep(timespec64_to_ktime(tu), HRTIMER_MODE_REL, diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c index fcb3b21d8bdc..3783d07d60ba 100644 --- a/kernel/time/posix-stubs.c +++ b/kernel/time/posix-stubs.c @@ -146,6 +146,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, return -EINVAL; if (flags & TIMER_ABSTIME) rmtp = NULL; + current->restart_block.fn = do_no_restart_syscall; current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; current->restart_block.nanosleep.rmtp = rmtp; texp = timespec64_to_ktime(t); @@ -239,6 +240,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, return -EINVAL; if (flags & TIMER_ABSTIME) rmtp = NULL; + current->restart_block.fn = do_no_restart_syscall; current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; current->restart_block.nanosleep.compat_rmtp = rmtp; texp = timespec64_to_ktime(t); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index b624788023d8..724ca7eb1a6e 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1270,6 +1270,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, return -EINVAL; if (flags & TIMER_ABSTIME) rmtp = NULL; + current->restart_block.fn = do_no_restart_syscall; current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; current->restart_block.nanosleep.rmtp = rmtp; @@ -1297,6 +1298,7 @@ SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags, return -EINVAL; if (flags & TIMER_ABSTIME) rmtp = NULL; + current->restart_block.fn = do_no_restart_syscall; current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; current->restart_block.nanosleep.compat_rmtp = rmtp; From 4707c94f7f89da7fa656df38d890d9d6a32bd0e0 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Mon, 28 Nov 2022 07:31:48 -0800 Subject: [PATCH 0406/1017] x86/bugs: Reset speculation control settings on init [ Upstream commit 0125acda7d76b943ca55811df40ed6ec0ecf670f ] Currently, x86_spec_ctrl_base is read at boot time and speculative bits are set if Kconfig items are enabled. For example, IBRS is enabled if CONFIG_CPU_IBRS_ENTRY is configured, etc. These MSR bits are not cleared if the mitigations are disabled. This is a problem when kexec-ing a kernel that has the mitigation disabled from a kernel that has the mitigation enabled. In this case, the MSR bits are not cleared during the new kernel boot. As a result, this might have some performance degradation that is hard to pinpoint. This problem does not happen if the machine is (hard) rebooted because the bit will be cleared by default. [ bp: Massage. ] Suggested-by: Pawan Gupta Signed-off-by: Breno Leitao Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20221128153148.1129350-1-leitao@debian.org Signed-off-by: Sasha Levin --- arch/x86/include/asm/msr-index.h | 4 ++++ arch/x86/kernel/cpu/bugs.c | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 5a8ee3b83af2..f71a177b6b18 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -54,6 +54,10 @@ #define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6 /* Disable RRSBA behavior */ #define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT) +/* A mask for bits which the kernel toggles when controlling mitigations */ +#define SPEC_CTRL_MITIGATIONS_MASK (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \ + | SPEC_CTRL_RRSBA_DIS_S) + #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index a2a087a797ae..c5034986ea44 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -136,9 +136,17 @@ void __init check_bugs(void) * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD * init code as it is not enumerated and depends on the family. */ - if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) + if (cpu_feature_enabled(X86_FEATURE_MSR_SPEC_CTRL)) { rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + /* + * Previously running kernel (kexec), may have some controls + * turned ON. Clear them and let the mitigations setup below + * rediscover them based on configuration. + */ + x86_spec_ctrl_base &= ~SPEC_CTRL_MITIGATIONS_MASK; + } + /* Select the proper CPU mitigations before patching alternatives: */ spectre_v1_select_mitigation(); spectre_v2_select_mitigation(); From 0ca2efea4f11c6255061e852ac188264c469c197 Mon Sep 17 00:00:00 2001 From: Jisoo Jang Date: Fri, 30 Dec 2022 16:51:39 +0900 Subject: [PATCH 0407/1017] wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out-of-bounds [ Upstream commit 660145d708be52f946a82e5b633c020f58f996de ] Fix a stack-out-of-bounds read in brcmfmac that occurs when 'buf' that is not null-terminated is passed as an argument of strreplace() in brcmf_c_preinit_dcmds(). This buffer is filled with a CLM version string by memcpy() in brcmf_fil_iovar_data_get(). Ensure buf is null-terminated. Found by a modified version of syzkaller. [ 33.004414][ T1896] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available [ 33.013486][ T1896] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43236/3 wl0: Nov 30 2011 17:33:42 version 5.90.188.22 [ 33.021554][ T1896] ================================================================== [ 33.022379][ T1896] BUG: KASAN: stack-out-of-bounds in strreplace+0xf2/0x110 [ 33.023122][ T1896] Read of size 1 at addr ffffc90001d6efc8 by task kworker/0:2/1896 [ 33.023852][ T1896] [ 33.024096][ T1896] CPU: 0 PID: 1896 Comm: kworker/0:2 Tainted: G O 5.14.0+ #132 [ 33.024927][ T1896] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 [ 33.026065][ T1896] Workqueue: usb_hub_wq hub_event [ 33.026581][ T1896] Call Trace: [ 33.026896][ T1896] dump_stack_lvl+0x57/0x7d [ 33.027372][ T1896] print_address_description.constprop.0.cold+0xf/0x334 [ 33.028037][ T1896] ? strreplace+0xf2/0x110 [ 33.028403][ T1896] ? strreplace+0xf2/0x110 [ 33.028807][ T1896] kasan_report.cold+0x83/0xdf [ 33.029283][ T1896] ? strreplace+0xf2/0x110 [ 33.029666][ T1896] strreplace+0xf2/0x110 [ 33.029966][ T1896] brcmf_c_preinit_dcmds+0xab1/0xc40 [ 33.030351][ T1896] ? brcmf_c_set_joinpref_default+0x100/0x100 [ 33.030787][ T1896] ? rcu_read_lock_sched_held+0xa1/0xd0 [ 33.031223][ T1896] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 33.031661][ T1896] ? lock_acquire+0x19d/0x4e0 [ 33.032091][ T1896] ? find_held_lock+0x2d/0x110 [ 33.032605][ T1896] ? brcmf_usb_deq+0x1a7/0x260 [ 33.033087][ T1896] ? brcmf_usb_rx_fill_all+0x5a/0xf0 [ 33.033582][ T1896] brcmf_attach+0x246/0xd40 [ 33.034022][ T1896] ? wiphy_new_nm+0x1476/0x1d50 [ 33.034383][ T1896] ? kmemdup+0x30/0x40 [ 33.034722][ T1896] brcmf_usb_probe+0x12de/0x1690 [ 33.035223][ T1896] ? brcmf_usbdev_qinit.constprop.0+0x470/0x470 [ 33.035833][ T1896] usb_probe_interface+0x25f/0x710 [ 33.036315][ T1896] really_probe+0x1be/0xa90 [ 33.036656][ T1896] __driver_probe_device+0x2ab/0x460 [ 33.037026][ T1896] ? usb_match_id.part.0+0x88/0xc0 [ 33.037383][ T1896] driver_probe_device+0x49/0x120 [ 33.037790][ T1896] __device_attach_driver+0x18a/0x250 [ 33.038300][ T1896] ? driver_allows_async_probing+0x120/0x120 [ 33.038986][ T1896] bus_for_each_drv+0x123/0x1a0 [ 33.039906][ T1896] ? bus_rescan_devices+0x20/0x20 [ 33.041412][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 33.041861][ T1896] ? trace_hardirqs_on+0x1c/0x120 [ 33.042330][ T1896] __device_attach+0x207/0x330 [ 33.042664][ T1896] ? device_bind_driver+0xb0/0xb0 [ 33.043026][ T1896] ? kobject_uevent_env+0x230/0x12c0 [ 33.043515][ T1896] bus_probe_device+0x1a2/0x260 [ 33.043914][ T1896] device_add+0xa61/0x1ce0 [ 33.044227][ T1896] ? __mutex_unlock_slowpath+0xe7/0x660 [ 33.044891][ T1896] ? __fw_devlink_link_to_suppliers+0x550/0x550 [ 33.045531][ T1896] usb_set_configuration+0x984/0x1770 [ 33.046051][ T1896] ? kernfs_create_link+0x175/0x230 [ 33.046548][ T1896] usb_generic_driver_probe+0x69/0x90 [ 33.046931][ T1896] usb_probe_device+0x9c/0x220 [ 33.047434][ T1896] really_probe+0x1be/0xa90 [ 33.047760][ T1896] __driver_probe_device+0x2ab/0x460 [ 33.048134][ T1896] driver_probe_device+0x49/0x120 [ 33.048516][ T1896] __device_attach_driver+0x18a/0x250 [ 33.048910][ T1896] ? driver_allows_async_probing+0x120/0x120 [ 33.049437][ T1896] bus_for_each_drv+0x123/0x1a0 [ 33.049814][ T1896] ? bus_rescan_devices+0x20/0x20 [ 33.050164][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 33.050579][ T1896] ? trace_hardirqs_on+0x1c/0x120 [ 33.050936][ T1896] __device_attach+0x207/0x330 [ 33.051399][ T1896] ? device_bind_driver+0xb0/0xb0 [ 33.051888][ T1896] ? kobject_uevent_env+0x230/0x12c0 [ 33.052314][ T1896] bus_probe_device+0x1a2/0x260 [ 33.052688][ T1896] device_add+0xa61/0x1ce0 [ 33.053121][ T1896] ? __fw_devlink_link_to_suppliers+0x550/0x550 [ 33.053568][ T1896] usb_new_device.cold+0x463/0xf66 [ 33.053953][ T1896] ? hub_disconnect+0x400/0x400 [ 33.054313][ T1896] ? rwlock_bug.part.0+0x90/0x90 [ 33.054661][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 33.055094][ T1896] hub_event+0x10d5/0x3330 [ 33.055530][ T1896] ? hub_port_debounce+0x280/0x280 [ 33.055934][ T1896] ? __lock_acquire+0x1671/0x5790 [ 33.056387][ T1896] ? wq_calc_node_cpumask+0x170/0x2a0 [ 33.056924][ T1896] ? lock_release+0x640/0x640 [ 33.057383][ T1896] ? rcu_read_lock_sched_held+0xa1/0xd0 [ 33.057916][ T1896] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 33.058402][ T1896] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 33.059019][ T1896] process_one_work+0x873/0x13e0 [ 33.059488][ T1896] ? lock_release+0x640/0x640 [ 33.059932][ T1896] ? pwq_dec_nr_in_flight+0x320/0x320 [ 33.060446][ T1896] ? rwlock_bug.part.0+0x90/0x90 [ 33.060898][ T1896] worker_thread+0x8b/0xd10 [ 33.061348][ T1896] ? __kthread_parkme+0xd9/0x1d0 [ 33.061810][ T1896] ? process_one_work+0x13e0/0x13e0 [ 33.062288][ T1896] kthread+0x379/0x450 [ 33.062660][ T1896] ? _raw_spin_unlock_irq+0x24/0x30 [ 33.063148][ T1896] ? set_kthread_struct+0x100/0x100 [ 33.063606][ T1896] ret_from_fork+0x1f/0x30 [ 33.064070][ T1896] [ 33.064313][ T1896] [ 33.064545][ T1896] addr ffffc90001d6efc8 is located in stack of task kworker/0:2/1896 at offset 512 in frame: [ 33.065478][ T1896] brcmf_c_preinit_dcmds+0x0/0xc40 [ 33.065973][ T1896] [ 33.066191][ T1896] this frame has 4 objects: [ 33.066614][ T1896] [48, 56) 'ptr' [ 33.066618][ T1896] [80, 148) 'revinfo' [ 33.066957][ T1896] [192, 210) 'eventmask' [ 33.067338][ T1896] [256, 512) 'buf' [ 33.067742][ T1896] [ 33.068304][ T1896] Memory state around the buggy address: [ 33.068838][ T1896] ffffc90001d6ee80: f2 00 00 02 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 [ 33.069545][ T1896] ffffc90001d6ef00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 33.070626][ T1896] >ffffc90001d6ef80: 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 f3 f3 [ 33.072052][ T1896] ^ [ 33.073043][ T1896] ffffc90001d6f000: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 33.074230][ T1896] ffffc90001d6f080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 33.074914][ T1896] ================================================================== [ 33.075713][ T1896] Disabling lock debugging due to kernel taint Reviewed-by: Arend van Spriel Signed-off-by: Jisoo Jang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221230075139.56591-1-jisoo.jang@yonsei.ac.kr Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 57bb1fbedaa8..f29de630908d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -281,15 +281,17 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) if (err) { brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err); } else { + buf[sizeof(buf) - 1] = '\0'; clmver = (char *)buf; - /* store CLM version for adding it to revinfo debugfs file */ - memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); /* Replace all newline/linefeed characters with space * character */ strreplace(clmver, '\n', ' '); + /* store CLM version for adding it to revinfo debugfs file */ + memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); + brcmf_dbg(INFO, "CLM version = %s\n", clmver); } From 47dc1f425af57b71111d7b01ebd24e04e8d967ef Mon Sep 17 00:00:00 2001 From: Jisoo Jang Date: Thu, 29 Dec 2022 18:29:06 +0900 Subject: [PATCH 0408/1017] wifi: mt7601u: fix an integer underflow [ Upstream commit 803f3176c5df3b5582c27ea690f204abb60b19b9 ] Fix an integer underflow that leads to a null pointer dereference in 'mt7601u_rx_skb_from_seg()'. The variable 'dma_len' in the URB packet could be manipulated, which could trigger an integer underflow of 'seg_len' in 'mt7601u_rx_process_seg()'. This underflow subsequently causes the 'bad_frame' checks in 'mt7601u_rx_skb_from_seg()' to be bypassed, eventually leading to a dereference of the pointer 'p', which is a null pointer. Ensure that 'dma_len' is greater than 'min_seg_len'. Found by a modified version of syzkaller. KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 0 PID: 12 Comm: ksoftirqd/0 Tainted: G W O 5.14.0+ #139 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 RIP: 0010:skb_add_rx_frag+0x143/0x370 Code: e2 07 83 c2 03 38 ca 7c 08 84 c9 0f 85 86 01 00 00 4c 8d 7d 08 44 89 68 08 48 b8 00 00 00 00 00 fc ff df 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 cd 01 00 00 48 8b 45 08 a8 01 0f 85 3d 01 00 00 RSP: 0018:ffffc900000cfc90 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: ffff888115520dc0 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffff8881118430c0 RDI: ffff8881118430f8 RBP: 0000000000000000 R08: 0000000000000e09 R09: 0000000000000010 R10: ffff888111843017 R11: ffffed1022308602 R12: 0000000000000000 R13: 0000000000000e09 R14: 0000000000000010 R15: 0000000000000008 FS: 0000000000000000(0000) GS:ffff88811a800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000004035af40 CR3: 00000001157f2000 CR4: 0000000000750ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: mt7601u_rx_tasklet+0xc73/0x1270 ? mt7601u_submit_rx_buf.isra.0+0x510/0x510 ? tasklet_action_common.isra.0+0x79/0x2f0 tasklet_action_common.isra.0+0x206/0x2f0 __do_softirq+0x1b5/0x880 ? tasklet_unlock+0x30/0x30 run_ksoftirqd+0x26/0x50 smpboot_thread_fn+0x34f/0x7d0 ? smpboot_register_percpu_thread+0x370/0x370 kthread+0x3a1/0x480 ? set_kthread_struct+0x120/0x120 ret_from_fork+0x1f/0x30 Modules linked in: 88XXau(O) 88x2bu(O) ---[ end trace 57f34f93b4da0f9b ]--- RIP: 0010:skb_add_rx_frag+0x143/0x370 Code: e2 07 83 c2 03 38 ca 7c 08 84 c9 0f 85 86 01 00 00 4c 8d 7d 08 44 89 68 08 48 b8 00 00 00 00 00 fc ff df 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 cd 01 00 00 48 8b 45 08 a8 01 0f 85 3d 01 00 00 RSP: 0018:ffffc900000cfc90 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: ffff888115520dc0 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffff8881118430c0 RDI: ffff8881118430f8 RBP: 0000000000000000 R08: 0000000000000e09 R09: 0000000000000010 R10: ffff888111843017 R11: ffffed1022308602 R12: 0000000000000000 R13: 0000000000000e09 R14: 0000000000000010 R15: 0000000000000008 FS: 0000000000000000(0000) GS:ffff88811a800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000004035af40 CR3: 00000001157f2000 CR4: 0000000000750ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Signed-off-by: Jisoo Jang Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221229092906.2328282-1-jisoo.jang@yonsei.ac.kr Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt7601u/dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c index 11071519fce8..8ba291abecff 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.c +++ b/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -118,7 +118,8 @@ static u16 mt7601u_rx_next_seg_len(u8 *data, u32 data_len) if (data_len < min_seg_len || WARN_ON_ONCE(!dma_len) || WARN_ON_ONCE(dma_len + MT_DMA_HDRS > data_len) || - WARN_ON_ONCE(dma_len & 0x3)) + WARN_ON_ONCE(dma_len & 0x3) || + WARN_ON_ONCE(dma_len < min_seg_len)) return 0; return MT_DMA_HDRS + dma_len; From b33091fc28963deed329ccfce0d53f5323acf663 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Sat, 14 Jan 2023 13:11:41 +0000 Subject: [PATCH 0409/1017] inet: fix fast path in __inet_hash_connect() [ Upstream commit 21cbd90a6fab7123905386985e3e4a80236b8714 ] __inet_hash_connect() has a fast path taken if sk_head(&tb->owners) is equal to the sk parameter. sk_head() returns the hlist_entry() with respect to the sk_node field. However entries in the tb->owners list are inserted with respect to the sk_bind_node field with sk_add_bind_node(). Thus the check would never pass and the fast path never execute. This fast path has never been executed or tested as this bug seems to be present since commit 1da177e4c3f4 ("Linux-2.6.12-rc2"), thus remove it to reduce code complexity. Signed-off-by: Pietro Borrello Reviewed-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20230112-inet_hash_connect_bind_head-v3-1-b591fd212b93@diag.uniroma1.it Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/ipv4/inet_hashtables.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 2615b72118d1..79bf550c9dfc 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -760,17 +760,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, u32 index; if (port) { - head = &hinfo->bhash[inet_bhashfn(net, port, - hinfo->bhash_size)]; - tb = inet_csk(sk)->icsk_bind_hash; - spin_lock_bh(&head->lock); - if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { - inet_ehash_nolisten(sk, NULL, NULL); - spin_unlock_bh(&head->lock); - return 0; - } - spin_unlock(&head->lock); - /* No definite answer... Walk to established hash table */ + local_bh_disable(); ret = check_established(death_row, sk, port, NULL); local_bh_enable(); return ret; From 9f1865ebfa7a81263746521c1dc1ed4346266d8b Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 13 Dec 2022 16:01:31 -0800 Subject: [PATCH 0410/1017] ice: add missing checks for PF vsi type [ Upstream commit 6a8d013e904ad9a66706fcc926ec9993bed7d190 ] There were a few places we had missed checking the VSI type to make sure it was definitely a PF VSI, before calling setup functions intended only for the PF VSI. This doesn't fix any explicit bugs but cleans up the code in a few places and removes one explicit != vsi->type check that can be superseded by this code (it's a super set) Signed-off-by: Jesse Brandeburg Tested-by: Gurucharan G (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_main.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index c1465096239b..4f0d63fa5709 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -5200,15 +5200,12 @@ int ice_vsi_cfg(struct ice_vsi *vsi) { int err; - if (vsi->netdev) { + if (vsi->netdev && vsi->type == ICE_VSI_PF) { ice_set_rx_mode(vsi->netdev); - if (vsi->type != ICE_VSI_LB) { - err = ice_vsi_vlan_setup(vsi); - - if (err) - return err; - } + err = ice_vsi_vlan_setup(vsi); + if (err) + return err; } ice_vsi_cfg_dcb_rings(vsi); @@ -5267,7 +5264,7 @@ static int ice_up_complete(struct ice_vsi *vsi) if (vsi->port_info && (vsi->port_info->phy.link_info.link_info & ICE_AQ_LINK_UP) && - vsi->netdev) { + vsi->netdev && vsi->type == ICE_VSI_PF) { ice_print_link_msg(vsi, true); netif_tx_start_all_queues(vsi->netdev); netif_carrier_on(vsi->netdev); @@ -5277,7 +5274,9 @@ static int ice_up_complete(struct ice_vsi *vsi) * set the baseline so counters are ready when interface is up */ ice_update_eth_stats(vsi); - ice_service_task_schedule(pf); + + if (vsi->type == ICE_VSI_PF) + ice_service_task_schedule(pf); return 0; } From 94933dab75d595fc4fd2389577d19fee3015729e Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Mon, 23 Jan 2023 13:45:58 +0000 Subject: [PATCH 0411/1017] ACPI: Don't build ACPICA with '-Os' [ Upstream commit 8f9e0a52810dd83406c768972d022c37e7a18f1f ] The ACPICA code has been built with '-Os' since the beginning of git history, though there's no explanatory comment as to why. This is unfortunate as GCC drops the alignment specificed by '-falign-functions=N' when '-Os' is used, as reported in GCC bug 88345: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345 This prevents CONFIG_FUNCTION_ALIGNMENT and CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B from having their expected effect on the ACPICA code. This is doubly unfortunate as in subsequent patches arm64 will depend upon CONFIG_FUNCTION_ALIGNMENT for its ftrace implementation. Drop the '-Os' flag when building the ACPICA code. With this removed, the code builds cleanly and works correctly in testing so far. I've tested this by selecting CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B=y, building and booting a kernel using ACPI, and looking for misaligned text symbols: * arm64: Before, v6.2-rc3: # uname -rm 6.2.0-rc3 aarch64 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l 5009 Before, v6.2-rc3 + fixed __cold: # uname -rm 6.2.0-rc3-00001-g2a2bedf8bfa9 aarch64 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l 919 After: # uname -rm 6.2.0-rc3-00002-g267bddc38572 aarch64 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l 323 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | grep acpi | wc -l 0 * x86_64: Before, v6.2-rc3: # uname -rm 6.2.0-rc3 x86_64 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l 11537 Before, v6.2-rc3 + fixed __cold: # uname -rm 6.2.0-rc3-00001-g2a2bedf8bfa9 x86_64 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l 2805 After: # uname -rm 6.2.0-rc3-00002-g267bddc38572 x86_64 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | wc -l 1357 # grep ' [Tt] ' /proc/kallsyms | grep -iv '[048c]0 [Tt] ' | grep acpi | wc -l 0 With the patch applied, the remaining unaligned text labels are a combination of static call trampolines and labels in assembly, which can be dealt with in subsequent patches. Signed-off-by: Mark Rutland Acked-by: Rafael J. Wysocki Cc: Florent Revest Cc: Len Brown Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Robert Moore Cc: Steven Rostedt Cc: Will Deacon Cc: linux-acpi@vger.kernel.org Link: https://lore.kernel.org/r/20230123134603.1064407-4-mark.rutland@arm.com Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- drivers/acpi/acpica/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 59700433a96e..f919811156b1 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -3,7 +3,7 @@ # Makefile for ACPICA Core interpreter # -ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA +ccflags-y := -D_LINUX -DBUILDING_ACPICA ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # use acpi.o to put all files here into acpi.o modparam namespace From 2fc7748d4823fc69a05d0003608b9398ca8cc165 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 20 Dec 2022 16:25:12 +0800 Subject: [PATCH 0412/1017] clocksource: Suspend the watchdog temporarily when high read latency detected [ Upstream commit b7082cdfc464bf9231300605d03eebf943dda307 ] Bugs have been reported on 8 sockets x86 machines in which the TSC was wrongly disabled when the system is under heavy workload. [ 818.380354] clocksource: timekeeping watchdog on CPU336: hpet wd-wd read-back delay of 1203520ns [ 818.436160] clocksource: wd-tsc-wd read-back delay of 181880ns, clock-skew test skipped! [ 819.402962] clocksource: timekeeping watchdog on CPU338: hpet wd-wd read-back delay of 324000ns [ 819.448036] clocksource: wd-tsc-wd read-back delay of 337240ns, clock-skew test skipped! [ 819.880863] clocksource: timekeeping watchdog on CPU339: hpet read-back delay of 150280ns, attempt 3, marking unstable [ 819.936243] tsc: Marking TSC unstable due to clocksource watchdog [ 820.068173] TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'. [ 820.092382] sched_clock: Marking unstable (818769414384, 1195404998) [ 820.643627] clocksource: Checking clocksource tsc synchronization from CPU 267 to CPUs 0,4,25,70,126,430,557,564. [ 821.067990] clocksource: Switched to clocksource hpet This can be reproduced by running memory intensive 'stream' tests, or some of the stress-ng subcases such as 'ioport'. The reason for these issues is the when system is under heavy load, the read latency of the clocksources can be very high. Even lightweight TSC reads can show high latencies, and latencies are much worse for external clocksources such as HPET or the APIC PM timer. These latencies can result in false-positive clocksource-unstable determinations. These issues were initially reported by a customer running on a production system, and this problem was reproduced on several generations of Xeon servers, especially when running the stress-ng test. These Xeon servers were not production systems, but they did have the latest steppings and firmware. Given that the clocksource watchdog is a continual diagnostic check with frequency of twice a second, there is no need to rush it when the system is under heavy load. Therefore, when high clocksource read latencies are detected, suspend the watchdog timer for 5 minutes. Signed-off-by: Feng Tang Acked-by: Waiman Long Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: Feng Tang Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/time/clocksource.c | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index e34ceb91f4c5..86e0fbe583f2 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -312,6 +312,15 @@ static void clocksource_verify_percpu(struct clocksource *cs) testcpu, cs_nsec_min, cs_nsec_max, cs->name); } +static inline void clocksource_reset_watchdog(void) +{ + struct clocksource *cs; + + list_for_each_entry(cs, &watchdog_list, wd_list) + cs->flags &= ~CLOCK_SOURCE_WATCHDOG; +} + + static void clocksource_watchdog(struct timer_list *unused) { u64 csnow, wdnow, cslast, wdlast, delta; @@ -319,6 +328,7 @@ static void clocksource_watchdog(struct timer_list *unused) int64_t wd_nsec, cs_nsec; struct clocksource *cs; enum wd_read_status read_ret; + unsigned long extra_wait = 0; u32 md; spin_lock(&watchdog_lock); @@ -338,13 +348,30 @@ static void clocksource_watchdog(struct timer_list *unused) read_ret = cs_watchdog_read(cs, &csnow, &wdnow); - if (read_ret != WD_READ_SUCCESS) { - if (read_ret == WD_READ_UNSTABLE) - /* Clock readout unreliable, so give it up. */ - __clocksource_unstable(cs); + if (read_ret == WD_READ_UNSTABLE) { + /* Clock readout unreliable, so give it up. */ + __clocksource_unstable(cs); continue; } + /* + * When WD_READ_SKIP is returned, it means the system is likely + * under very heavy load, where the latency of reading + * watchdog/clocksource is very big, and affect the accuracy of + * watchdog check. So give system some space and suspend the + * watchdog check for 5 minutes. + */ + if (read_ret == WD_READ_SKIP) { + /* + * As the watchdog timer will be suspended, and + * cs->last could keep unchanged for 5 minutes, reset + * the counters. + */ + clocksource_reset_watchdog(); + extra_wait = HZ * 300; + break; + } + /* Clocksource initialized ? */ if (!(cs->flags & CLOCK_SOURCE_WATCHDOG) || atomic_read(&watchdog_reset_pending)) { @@ -434,7 +461,7 @@ static void clocksource_watchdog(struct timer_list *unused) * pair clocksource_stop_watchdog() clocksource_start_watchdog(). */ if (!timer_pending(&watchdog_timer)) { - watchdog_timer.expires += WATCHDOG_INTERVAL; + watchdog_timer.expires += WATCHDOG_INTERVAL + extra_wait; add_timer_on(&watchdog_timer, next_cpu); } out: @@ -459,14 +486,6 @@ static inline void clocksource_stop_watchdog(void) watchdog_running = 0; } -static inline void clocksource_reset_watchdog(void) -{ - struct clocksource *cs; - - list_for_each_entry(cs, &watchdog_list, wd_list) - cs->flags &= ~CLOCK_SOURCE_WATCHDOG; -} - static void clocksource_resume_watchdog(void) { atomic_inc(&watchdog_reset_pending); From 1fc9760afd8a012f303eea4532a205a2eb158e8f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 5 Jan 2023 20:19:48 -0800 Subject: [PATCH 0413/1017] crypto: hisilicon: Wipe entire pool on error [ Upstream commit aa85923a954e7704bc9d3847dabeb8540aa98d13 ] To work around a Clang __builtin_object_size bug that shows up under CONFIG_FORTIFY_SOURCE and UBSAN_BOUNDS, move the per-loop-iteration mem_block wipe into a single wipe of the entire pool structure after the loop. Reported-by: Nathan Chancellor Link: https://github.com/ClangBuiltLinux/linux/issues/1780 Cc: Weili Qian Cc: Zhou Wang Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-crypto@vger.kernel.org Signed-off-by: Kees Cook Tested-by: Nathan Chancellor # build Link: https://lore.kernel.org/r/20230106041945.never.831-kees@kernel.org Signed-off-by: Sasha Levin --- drivers/crypto/hisilicon/sgl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c index 725a739800b0..ce77826c7fb0 100644 --- a/drivers/crypto/hisilicon/sgl.c +++ b/drivers/crypto/hisilicon/sgl.c @@ -113,9 +113,8 @@ err_free_mem: for (j = 0; j < i; j++) { dma_free_coherent(dev, block_size, block[j].sgl, block[j].sgl_dma); - memset(block + j, 0, sizeof(*block)); } - kfree(pool); + kfree_sensitive(pool); return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool); From 841881320562cbeac7046b537b91cd000480cea2 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 26 Jan 2023 16:08:19 -0800 Subject: [PATCH 0414/1017] net: bcmgenet: Add a check for oversized packets [ Upstream commit 5c0862c2c962052ed5055220a00ac1cefb92fbcd ] Occasionnaly we may get oversized packets from the hardware which exceed the nomimal 2KiB buffer size we allocate SKBs with. Add an early check which drops the packet to avoid invoking skb_over_panic() and move on to processing the next packet. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index e0a6a2e62d23..7667cbb5adfd 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2263,6 +2263,14 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring, __func__, p_index, ring->c_index, ring->read_ptr, dma_length_status); + if (unlikely(len > RX_BUF_LENGTH)) { + netif_err(priv, rx_status, dev, "oversized packet\n"); + dev->stats.rx_length_errors++; + dev->stats.rx_errors++; + dev_kfree_skb_any(skb); + goto next; + } + if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { netif_err(priv, rx_status, dev, "dropping fragmented packet!\n"); From 7873def499dfc1a5406f0ac06d288b4e9ee461e4 Mon Sep 17 00:00:00 2001 From: Michael Schmitz Date: Thu, 12 Jan 2023 16:55:27 +1300 Subject: [PATCH 0415/1017] m68k: Check syscall_trace_enter() return code [ Upstream commit 2ca8a1de4437f21562e57f9ac123914747a8e7a1 ] Check return code of syscall_trace_enter(), and skip syscall if -1. Return code will be left at what had been set by ptrace or seccomp (in regs->d0). No regression seen in testing with strace on ARAnyM. Signed-off-by: Michael Schmitz Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230112035529.13521-2-schmitzmic@gmail.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/68000/entry.S | 2 ++ arch/m68k/coldfire/entry.S | 2 ++ arch/m68k/kernel/entry.S | 3 +++ 3 files changed, 7 insertions(+) diff --git a/arch/m68k/68000/entry.S b/arch/m68k/68000/entry.S index 259b3661b614..94abf3d8afc5 100644 --- a/arch/m68k/68000/entry.S +++ b/arch/m68k/68000/entry.S @@ -47,6 +47,8 @@ do_trace: jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp + addql #1,%d0 + jeq ret_from_exception movel %sp@(PT_OFF_ORIG_D0),%d1 movel #-ENOSYS,%d0 cmpl #NR_syscalls,%d1 diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S index d43a02795a4a..f1d41a9328a2 100644 --- a/arch/m68k/coldfire/entry.S +++ b/arch/m68k/coldfire/entry.S @@ -92,6 +92,8 @@ ENTRY(system_call) jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp + addql #1,%d0 + jeq ret_from_exception movel %d3,%a0 jbsr %a0@ movel %d0,%sp@(PT_OFF_D0) /* save the return value */ diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 9dd76fbb7c6b..546bab6bfc27 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -167,9 +167,12 @@ do_trace_entry: jbsr syscall_trace RESTORE_SWITCH_STACK addql #4,%sp + addql #1,%d0 | optimization for cmpil #-1,%d0 + jeq ret_from_syscall movel %sp@(PT_OFF_ORIG_D0),%d0 cmpl #NR_syscalls,%d0 jcs syscall + jra ret_from_syscall badsys: movel #-ENOSYS,%sp@(PT_OFF_D0) jra ret_from_syscall From 46ce77b07cd83b12cbe6f1aa617cf4487b06317a Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 1 Jan 2023 12:47:57 +0100 Subject: [PATCH 0416/1017] wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup [ Upstream commit 1b88b47e898edef0e56e3a2f4e49f052a136153d ] Free rx_head skb in mt76_dma_rx_cleanup routine in order to avoid possible memory leak at module unload. Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/dma.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index f01b455783b2..7991705e9d13 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -476,6 +476,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) bool more; spin_lock_bh(&q->lock); + do { buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more); if (!buf) @@ -483,6 +484,12 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) skb_free_frag(buf); } while (1); + + if (q->rx_head) { + dev_kfree_skb(q->rx_head); + q->rx_head = NULL; + } + spin_unlock_bh(&q->lock); if (!q->rx_page.va) @@ -505,12 +512,6 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid) mt76_dma_rx_cleanup(dev, q); mt76_dma_sync_idx(dev, q); mt76_dma_rx_fill(dev, q); - - if (!q->rx_head) - return; - - dev_kfree_skb(q->rx_head); - q->rx_head = NULL; } static void From 1ef724fed392f7ed56e64817b04ba75e64903101 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 2 Feb 2023 13:44:49 +0100 Subject: [PATCH 0417/1017] ACPI: video: Fix Lenovo Ideapad Z570 DMI match [ Upstream commit 2d11eae42d52a131f06061015e49dc0f085c5bfc ] Multiple Ideapad Z570 variants need acpi_backlight=native to force native use on these pre Windows 8 machines since acpi_video backlight control does not work here. The original DMI quirk matches on a product_name of "102434U" but other variants may have different product_name-s such as e.g. "1024D9U". Move to checking product_version instead as is more or less standard for Lenovo DMI quirks for similar reasons. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/video_detect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index b13713199ad9..038542b3a80a 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -313,7 +313,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { .ident = "Lenovo Ideapad Z570", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "102434U"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"), }, }, { From 206c511e4214b713a684022cfa84b1bd5ccae5c6 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Wed, 11 Jan 2023 13:34:02 +0200 Subject: [PATCH 0418/1017] net/mlx5: fw_tracer: Fix debug print [ Upstream commit 988c2352273997a242f15c4fc3711773515006a2 ] The debug message specify tdsn, but takes as an argument the tmsn. The correct argument is tmsn, hence, fix the print. Signed-off-by: Shay Drory Reviewed-by: Moshe Shemesh Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c index 40d7bfca3749..0a011a41c039 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -603,7 +603,7 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer, } else { cur_string = mlx5_tracer_message_get(tracer, tracer_event); if (!cur_string) { - pr_debug("%s Got string event for unknown string tdsm: %d\n", + pr_debug("%s Got string event for unknown string tmsn: %d\n", __func__, tracer_event->string_event.tmsn); return -1; } From d80f947bb303f501d397bcad285393ed1e532035 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 14:39:21 -0800 Subject: [PATCH 0419/1017] coda: Avoid partial allocation of sig_inputArgs [ Upstream commit 48df133578c70185a95a49390d42df1996ddba2a ] GCC does not like having a partially allocated object, since it cannot reason about it for bounds checking when it is passed to other code. Instead, fully allocate sig_inputArgs. (Alternatively, sig_inputArgs should be defined as a struct coda_in_hdr, if it is actually not using any other part of the union.) Seen under GCC 13: ../fs/coda/upcall.c: In function 'coda_upcall': ../fs/coda/upcall.c:801:22: warning: array subscript 'union inputArgs[0]' is partly outside array bounds of 'unsigned char[20]' [-Warray-bounds=] 801 | sig_inputArgs->ih.opcode = CODA_SIGNAL; | ^~ Cc: Jan Harkes Cc: coda@cs.cmu.edu Cc: codalist@coda.cs.cmu.edu Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20230127223921.never.882-kees@kernel.org Signed-off-by: Sasha Levin --- fs/coda/upcall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index eb3b1898da46..610484c90260 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -790,7 +790,7 @@ static int coda_upcall(struct venus_comm *vcp, sig_req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); if (!sig_req) goto exit; - sig_inputArgs = kvzalloc(sizeof(struct coda_in_hdr), GFP_KERNEL); + sig_inputArgs = kvzalloc(sizeof(*sig_inputArgs), GFP_KERNEL); if (!sig_inputArgs) { kfree(sig_req); goto exit; From 0c2b778edd8a4609e6650c55d490af9359c1e62f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 31 Jan 2023 17:37:59 -0800 Subject: [PATCH 0420/1017] uaccess: Add minimum bounds check on kernel buffer size [ Upstream commit 04ffde1319a715bd0550ded3580d4ea3bc003776 ] While there is logic about the difference between ksize and usize, copy_struct_from_user() didn't check the size of the destination buffer (when it was known) against ksize. Add this check so there is an upper bounds check on the possible memset() call, otherwise lower bounds checks made by callers will trigger bounds warnings under -Warray-bounds. Seen under GCC 13: In function 'copy_struct_from_user', inlined from 'iommufd_fops_ioctl' at ../drivers/iommu/iommufd/main.c:333:8: ../include/linux/fortify-string.h:59:33: warning: '__builtin_memset' offset [57, 4294967294] is out of the bounds [0, 56] of object 'buf' with type 'union ucmd_buffer' [-Warray-bounds=] 59 | #define __underlying_memset __builtin_memset | ^ ../include/linux/fortify-string.h:453:9: note: in expansion of macro '__underlying_memset' 453 | __underlying_memset(p, c, __fortify_size); \ | ^~~~~~~~~~~~~~~~~~~ ../include/linux/fortify-string.h:461:25: note: in expansion of macro '__fortify_memset_chk' 461 | #define memset(p, c, s) __fortify_memset_chk(p, c, s, \ | ^~~~~~~~~~~~~~~~~~~~ ../include/linux/uaccess.h:334:17: note: in expansion of macro 'memset' 334 | memset(dst + size, 0, rest); | ^~~~~~ ../drivers/iommu/iommufd/main.c: In function 'iommufd_fops_ioctl': ../drivers/iommu/iommufd/main.c:311:27: note: 'buf' declared here 311 | union ucmd_buffer buf; | ^~~ Cc: Christian Brauner Cc: Rasmus Villemoes Cc: Arnd Bergmann Cc: Dinh Nguyen Cc: Catalin Marinas Cc: Andrew Morton Cc: Geert Uytterhoeven Cc: Alexander Potapenko Acked-by: Aleksa Sarai Signed-off-by: Kees Cook Link: https://lore.kernel.org/lkml/20230203193523.never.667-kees@kernel.org/ Signed-off-by: Sasha Levin --- include/linux/uaccess.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index c7c6e8b8344d..20668760daa0 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -348,6 +348,10 @@ copy_struct_from_user(void *dst, size_t ksize, const void __user *src, size_t size = min(ksize, usize); size_t rest = max(ksize, usize) - size; + /* Double check if ksize is larger than a known object size. */ + if (WARN_ON_ONCE(ksize > __builtin_object_size(dst, 1))) + return -E2BIG; + /* Deal with trailing bytes. */ if (usize < ksize) { memset(dst + size, 0, rest); From e974e8f1e37d22c0de07374f8ddc84073fef2f1d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Feb 2023 16:15:15 +0100 Subject: [PATCH 0421/1017] PM: EM: fix memory leak with using debugfs_lookup() [ Upstream commit a0e8c13ccd6a9a636d27353da62c2410c4eca337 ] When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- kernel/power/energy_model.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 119b929dcff0..334173fe6940 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -72,10 +72,7 @@ static void em_debug_create_pd(struct device *dev) static void em_debug_remove_pd(struct device *dev) { - struct dentry *debug_dir; - - debug_dir = debugfs_lookup(dev_name(dev), rootdir); - debugfs_remove_recursive(debug_dir); + debugfs_lookup_and_remove(dev_name(dev), rootdir); } static int __init em_debug_init(void) From 348cc9ab33803bc0ed6e9cfd61b07f09f98debec Mon Sep 17 00:00:00 2001 From: Moises Cardona Date: Sun, 25 Dec 2022 14:07:13 -0500 Subject: [PATCH 0422/1017] Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE [ Upstream commit 1eec3b95b5ce7fb2cdd273ac4f8b24b1ed6776a1 ] This patch adds VID:PID 13d3:3529 to the btusb.c file. This VID:PID is found in the Realtek RTL8821CE module (M.2 module AW-CB304NF on an ASUS E210MA laptop) Output of /sys/kernel/debug/usb/devices: T: Bus=01 Lev=01 Prnt=01 Port=07 Cnt=02 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3529 Rev= 1.10 S: Manufacturer=Realtek S: Product=Bluetooth Radio C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Moises Cardona Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/btusb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3d905fda9b29..2695ece47eb0 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -393,6 +393,10 @@ static const struct usb_device_id blacklist_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), .driver_info = BTUSB_IGNORE }, + /* Realtek 8821CE Bluetooth devices */ + { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + /* Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, From 9f73793b81637c60ccc83cc508645310b8ab7d80 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Thu, 1 Dec 2022 09:06:42 -0500 Subject: [PATCH 0423/1017] drm/amd/display: Fix potential null-deref in dm_resume [ Upstream commit 7a7175a2cd84b7874bebbf8e59f134557a34161b ] [Why] Fixing smatch error: dm_resume() error: we previously assumed 'aconnector->dc_link' could be null [How] Check if dc_link null at the beginning of the loop, so further checks can be dropped. Reported-by: kernel test robot Reported-by: Dan Carpenter Reviewed-by: Wayne Lin Acked-by: Jasdeep Dhillon Signed-off-by: Roman Li Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fbe15f4b75fd..dbdf0e210522 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2051,12 +2051,14 @@ static int dm_resume(void *handle) drm_for_each_connector_iter(connector, &iter) { aconnector = to_amdgpu_dm_connector(connector); + if (!aconnector->dc_link) + continue; + /* * this is the case when traversing through already created * MST connectors, should be skipped */ - if (aconnector->dc_link && - aconnector->dc_link->type == dc_connection_mst_branch) + if (aconnector->dc_link->type == dc_connection_mst_branch) continue; mutex_lock(&aconnector->hpd_lock); From f4cb425252086a5f81e77200a84837102dddfea3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 16 Sep 2022 11:22:05 +0300 Subject: [PATCH 0424/1017] drm/omap: dsi: Fix excessive stack usage [ Upstream commit cfca78971b9233aef0891507a98fba62046d4542 ] dsi_dump_dsi_irqs(), a function used for debugfs prints, has a large struct in its frame, which can result in: drivers/gpu/drm/omapdrm/dss/dsi.c:1126:1: warning: the frame size of 1060 bytes is larger than 1024 bytes [-Wframe-larger-than=] As the performance of the function is of no concern, let's allocate the struct with kmalloc instead. Compile-tested only. Signed-off-by: Tomi Valkeinen Reported-by: kernel test robot Reviewed-by: Arnd Bergmann Link: https://patchwork.freedesktop.org/patch/msgid/20220916082206.167427-1-tomi.valkeinen@ideasonboard.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/omapdrm/dss/dsi.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index eeccf40bae41..1b1ddc5fe6dc 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -1444,22 +1444,26 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) { struct dsi_data *dsi = s->private; unsigned long flags; - struct dsi_irq_stats stats; + struct dsi_irq_stats *stats; + + stats = kmalloc(sizeof(*stats), GFP_KERNEL); + if (!stats) + return -ENOMEM; spin_lock_irqsave(&dsi->irq_stats_lock, flags); - stats = dsi->irq_stats; + *stats = dsi->irq_stats; memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats)); dsi->irq_stats.last_reset = jiffies; spin_unlock_irqrestore(&dsi->irq_stats_lock, flags); seq_printf(s, "period %u ms\n", - jiffies_to_msecs(jiffies - stats.last_reset)); + jiffies_to_msecs(jiffies - stats->last_reset)); - seq_printf(s, "irqs %d\n", stats.irq_count); + seq_printf(s, "irqs %d\n", stats->irq_count); #define PIS(x) \ - seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); + seq_printf(s, "%-20s %10d\n", #x, stats->dsi_irqs[ffs(DSI_IRQ_##x)-1]); seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1); PIS(VC0); @@ -1483,10 +1487,10 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) #define PIS(x) \ seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \ - stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ - stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ - stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ - stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); + stats->vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ + stats->vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ + stats->vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ + stats->vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); seq_printf(s, "-- VC interrupts --\n"); PIS(CS); @@ -1502,7 +1506,7 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) #define PIS(x) \ seq_printf(s, "%-20s %10d\n", #x, \ - stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); + stats->cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); seq_printf(s, "-- CIO interrupts --\n"); PIS(ERRSYNCESC1); @@ -1527,6 +1531,8 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) PIS(ULPSACTIVENOT_ALL1); #undef PIS + kfree(stats); + return 0; } #endif From bc919c866dd5a6bc0533f1418cb021ac83b1b913 Mon Sep 17 00:00:00 2001 From: Jingyuan Liang Date: Tue, 13 Dec 2022 22:53:30 +0000 Subject: [PATCH 0425/1017] HID: Add Mapping for System Microphone Mute [ Upstream commit 2d60f9f4f26785a00273cb81fe60eff129ebd449 ] HUTRR110 added a new usage code for a key that is supposed to mute/unmute microphone system-wide. Map the new usage code(0x01 0xa9) to keycode KEY_MICMUTE. Additionally hid-debug is adjusted to recognize this keycode as well. Signed-off-by: Jingyuan Liang Reviewed-by: Dmitry Torokhov Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-debug.c | 1 + drivers/hid/hid-input.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index f4e2e6937758..1f60a381ae63 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -933,6 +933,7 @@ static const char *keys[KEY_MAX + 1] = { [KEY_VOICECOMMAND] = "VoiceCommand", [KEY_EMOJI_PICKER] = "EmojiPicker", [KEY_DICTATE] = "Dictate", + [KEY_MICMUTE] = "MicrophoneMute", [KEY_BRIGHTNESS_MIN] = "BrightnessMin", [KEY_BRIGHTNESS_MAX] = "BrightnessMax", [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto", diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 75a4d8d6bb0f..3399953256d8 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -675,6 +675,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; } + if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */ + switch (usage->hid & 0xf) { + case 0x9: map_key_clear(KEY_MICMUTE); break; + default: goto ignore; + } + break; + } + if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */ switch (usage->hid & 0xf) { case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break; From 819d8dba030dc99bdf6dfacac671db23cec28427 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Mon, 19 Dec 2022 10:02:38 +0100 Subject: [PATCH 0426/1017] drm/tiny: ili9486: Do not assume 8-bit only SPI controllers [ Upstream commit 77772e607522daa61f3af74df018559db75c43d6 ] The pixel data for the ILI9486 is always 16-bits wide and it must be sent over the SPI bus. When the controller is only able to deal with 8-bit transfers, this 16-bits data needs to be swapped before the sending to account for the big endian bus, this is on the contrary not needed when the SPI controller already supports 16-bits transfers. The decision about swapping the pixel data or not is taken in the MIPI DBI code by probing the controller capabilities: if the controller only suppors 8-bit transfers the data is swapped, otherwise it is not. This swapping/non-swapping is relying on the assumption that when the controller does support 16-bit transactions then the data is sent unswapped in 16-bits-per-word over SPI. The problem with the ILI9486 driver is that it is forcing 8-bit transactions also for controllers supporting 16-bits, violating the assumption and corrupting the pixel data. Align the driver to what is done in the MIPI DBI code by adjusting the transfer size to the maximum allowed by the SPI controller. Reviewed-by: Neil Armstrong Signed-off-by: Carlo Caione Reviewed-by: Kamlesh Gurudasani Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20221116-s905x_spi_ili9486-v4-2-f86b4463b9e4@baylibre.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/tiny/ili9486.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c index 403af68fa440..7ea26e5fbcb2 100644 --- a/drivers/gpu/drm/tiny/ili9486.c +++ b/drivers/gpu/drm/tiny/ili9486.c @@ -43,6 +43,7 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par, size_t num) { struct spi_device *spi = mipi->spi; + unsigned int bpw = 8; void *data = par; u32 speed_hz; int i, ret; @@ -56,8 +57,6 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par, * The displays are Raspberry Pi HATs and connected to the 8-bit only * SPI controller, so 16-bit command and parameters need byte swapping * before being transferred as 8-bit on the big endian SPI bus. - * Pixel data bytes have already been swapped before this function is - * called. */ buf[0] = cpu_to_be16(*cmd); gpiod_set_value_cansleep(mipi->dc, 0); @@ -71,12 +70,18 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par, for (i = 0; i < num; i++) buf[i] = cpu_to_be16(par[i]); num *= 2; - speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); data = buf; } + /* + * Check whether pixel data bytes needs to be swapped or not + */ + if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes) + bpw = 16; + gpiod_set_value_cansleep(mipi->dc, 1); - ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, data, num); + speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); + ret = mipi_dbi_spi_transfer(spi, speed_hz, bpw, data, num); free: kfree(buf); From ce9e9d3dcbb0d1551ffd1a7f16e7c051f3ba4140 Mon Sep 17 00:00:00 2001 From: Liwei Song Date: Fri, 6 Jan 2023 17:47:29 +0800 Subject: [PATCH 0427/1017] drm/radeon: free iio for atombios when driver shutdown [ Upstream commit 4773fadedca918faec443daaca5e4ea1c0ced144 ] Fix below kmemleak when unload radeon driver: unreferenced object 0xffff9f8608ede200 (size 512): comm "systemd-udevd", pid 326, jiffies 4294682822 (age 716.338s) hex dump (first 32 bytes): 00 00 00 00 c4 aa ec aa 14 ab 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<0000000062fadebe>] kmem_cache_alloc_trace+0x2f1/0x500 [<00000000b6883cea>] atom_parse+0x117/0x230 [radeon] [<00000000158c23fd>] radeon_atombios_init+0xab/0x170 [radeon] [<00000000683f672e>] si_init+0x57/0x750 [radeon] [<00000000566cc31f>] radeon_device_init+0x559/0x9c0 [radeon] [<0000000046efabb3>] radeon_driver_load_kms+0xc1/0x1a0 [radeon] [<00000000b5155064>] drm_dev_register+0xdd/0x1d0 [<0000000045fec835>] radeon_pci_probe+0xbd/0x100 [radeon] [<00000000e69ecca3>] pci_device_probe+0xe1/0x160 [<0000000019484b76>] really_probe.part.0+0xc1/0x2c0 [<000000003f2649da>] __driver_probe_device+0x96/0x130 [<00000000231c5bb1>] driver_probe_device+0x24/0xf0 [<0000000000a42377>] __driver_attach+0x77/0x190 [<00000000d7574da6>] bus_for_each_dev+0x7f/0xd0 [<00000000633166d2>] driver_attach+0x1e/0x30 [<00000000313b05b8>] bus_add_driver+0x12c/0x1e0 iio was allocated in atom_index_iio() called by atom_parse(), but it doesn't got released when the dirver is shutdown. Fix this kmemleak by free it in radeon_atombios_fini(). Signed-off-by: Liwei Song Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/radeon/radeon_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 8287410f471f..131f425c363a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1022,6 +1022,7 @@ void radeon_atombios_fini(struct radeon_device *rdev) { if (rdev->mode_info.atom_context) { kfree(rdev->mode_info.atom_context->scratch); + kfree(rdev->mode_info.atom_context->iio); } kfree(rdev->mode_info.atom_context); rdev->mode_info.atom_context = NULL; From d473c55ce1975c9e601c25293328a5039225d2b2 Mon Sep 17 00:00:00 2001 From: Konstantin Meskhidze Date: Wed, 30 Nov 2022 10:50:46 +0800 Subject: [PATCH 0428/1017] drm: amd: display: Fix memory leakage [ Upstream commit 6b8701be1f66064ca72733c5f6e13748cdbf8397 ] This commit fixes memory leakage in dc_construct_ctx() function. Signed-off-by: Konstantin Meskhidze Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 99887bcfada0..7e0a55aa2b18 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -616,6 +616,7 @@ static bool dc_construct_ctx(struct dc *dc, dc_ctx->perf_trace = dc_perf_trace_create(); if (!dc_ctx->perf_trace) { + kfree(dc_ctx); ASSERT_CRITICAL(false); return false; } From 540c66180afd59309a442d3bf1f2393464c8b4c5 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 10 Jan 2023 10:16:51 +0800 Subject: [PATCH 0429/1017] drm/msm/dsi: Add missing check for alloc_ordered_workqueue [ Upstream commit 115906ca7b535afb1fe7b5406c566ccd3873f82b ] Add check for the return value of alloc_ordered_workqueue as it may return NULL pointer and cause NULL pointer dereference. Signed-off-by: Jiasheng Jiang Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/517646/ Link: https://lore.kernel.org/r/20230110021651.12770-1-jiasheng@iscas.ac.cn Signed-off-by: Dmitry Baryshkov Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 51e8318cc8ff..5a76aa138917 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1913,6 +1913,9 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) /* setup workqueue */ msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); + if (!msm_host->workqueue) + return -ENOMEM; + INIT_WORK(&msm_host->err_work, dsi_err_worker); INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker); From fcfc7740228d2a4ce105950a41494ede86712d09 Mon Sep 17 00:00:00 2001 From: Jakob Koschel Date: Fri, 20 Jan 2023 00:23:20 +0100 Subject: [PATCH 0430/1017] docs/scripts/gdb: add necessary make scripts_gdb step [ Upstream commit 6b219431037bf98c9efd49716aea9b68440477a3 ] In order to debug the kernel successfully with gdb you need to run 'make scripts_gdb' nowadays. This was changed with the following commit: Commit 67274c083438340ad16c ("scripts/gdb: delay generation of gdb constants.py") In order to have a complete guide for beginners this remark should be added to the offial documentation. Signed-off-by: Jakob Koschel Link: https://lore.kernel.org/r/20230112-documentation-gdb-v2-1-292785c43dc9@gmail.com Signed-off-by: Jonathan Corbet Signed-off-by: Sasha Levin --- Documentation/dev-tools/gdb-kernel-debugging.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst index 4756f6b3a04e..10cdd990b63d 100644 --- a/Documentation/dev-tools/gdb-kernel-debugging.rst +++ b/Documentation/dev-tools/gdb-kernel-debugging.rst @@ -39,6 +39,10 @@ Setup this mode. In this case, you should build the kernel with CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR. +- Build the gdb scripts (required on kernels v5.1 and above):: + + make scripts_gdb + - Enable the gdb stub of QEMU/KVM, either - at VM startup time by appending "-s" to the QEMU command line From 0adacf6d6b1233f24a1e1775e0e2766fd0b69314 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 14:41:29 -0800 Subject: [PATCH 0431/1017] ASoC: kirkwood: Iterate over array indexes instead of using pointer math [ Upstream commit b3bcedc0402fcdc5c8624c433562d9d1882749d8 ] Walking the dram->cs array was seen as accesses beyond the first array item by the compiler. Instead, use the array index directly. This allows for run-time bounds checking under CONFIG_UBSAN_BOUNDS as well. Seen with GCC 13 with -fstrict-flex-arrays: ../sound/soc/kirkwood/kirkwood-dma.c: In function 'kirkwood_dma_conf_mbus_windows.constprop': ../sound/soc/kirkwood/kirkwood-dma.c:90:24: warning: array subscript 0 is outside array bounds of 'const struct mbus_dram_window[0]' [-Warray-bounds=] 90 | if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) { | ~~^~~~~~ Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: alsa-devel@alsa-project.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20230127224128.never.410-kees@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/kirkwood/kirkwood-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index e037826b2451..2d41e6ab2ce4 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -86,7 +86,7 @@ kirkwood_dma_conf_mbus_windows(void __iomem *base, int win, /* try to find matching cs for current dma address */ for (i = 0; i < dram->num_cs; i++) { - const struct mbus_dram_window *cs = dram->cs + i; + const struct mbus_dram_window *cs = &dram->cs[i]; if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) { writel(cs->base & 0xffff0000, base + KIRKWOOD_AUDIO_WIN_BASE_REG(win)); From b4ff71c6f0290f9a12437ae27e0e666147e91e1e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 14:52:07 -0800 Subject: [PATCH 0432/1017] regulator: max77802: Bounds check regulator id against opmode [ Upstream commit 4fd8bcec5fd7c0d586206fa2f42bd67b06cdaa7e ] Explicitly bounds-check the id before accessing the opmode array. Seen with GCC 13: ../drivers/regulator/max77802-regulator.c: In function 'max77802_enable': ../drivers/regulator/max77802-regulator.c:217:29: warning: array subscript [0, 41] is outside array bounds of 'unsigned int[42]' [-Warray-bounds=] 217 | if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) | ~~~~~~~~~~~~~~~~^~~~ ../drivers/regulator/max77802-regulator.c:62:22: note: while referencing 'opmode' 62 | unsigned int opmode[MAX77802_REG_MAX]; | ^~~~~~ Cc: Javier Martinez Canillas Cc: Liam Girdwood Cc: Mark Brown Signed-off-by: Kees Cook Acked-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20230127225203.never.864-kees@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/max77802-regulator.c | 34 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c index 7b8ec8c0bd15..660e179a82a2 100644 --- a/drivers/regulator/max77802-regulator.c +++ b/drivers/regulator/max77802-regulator.c @@ -95,9 +95,11 @@ static int max77802_set_suspend_disable(struct regulator_dev *rdev) { unsigned int val = MAX77802_OFF_PWRREQ; struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; max77802->opmode[id] = val; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val << shift); @@ -111,7 +113,7 @@ static int max77802_set_suspend_disable(struct regulator_dev *rdev) static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); unsigned int val; int shift = max77802_get_opmode_shift(id); @@ -128,6 +130,9 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) return -EINVAL; } + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; + max77802->opmode[id] = val; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val << shift); @@ -136,8 +141,10 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) static unsigned max77802_get_mode(struct regulator_dev *rdev) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; return max77802_map_mode(max77802->opmode[id]); } @@ -161,10 +168,13 @@ static int max77802_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); unsigned int val; int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; + /* * If the regulator has been disabled for suspend * then is invalid to try setting a suspend mode. @@ -210,9 +220,11 @@ static int max77802_set_suspend_mode(struct regulator_dev *rdev, static int max77802_enable(struct regulator_dev *rdev) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) max77802->opmode[id] = MAX77802_OPMODE_NORMAL; @@ -541,7 +553,7 @@ static int max77802_pmic_probe(struct platform_device *pdev) for (i = 0; i < MAX77802_REG_MAX; i++) { struct regulator_dev *rdev; - int id = regulators[i].id; + unsigned int id = regulators[i].id; int shift = max77802_get_opmode_shift(id); int ret; @@ -559,10 +571,12 @@ static int max77802_pmic_probe(struct platform_device *pdev) * the hardware reports OFF as the regulator operating mode. * Default to operating mode NORMAL in that case. */ - if (val == MAX77802_STATUS_OFF) - max77802->opmode[id] = MAX77802_OPMODE_NORMAL; - else - max77802->opmode[id] = val; + if (id < ARRAY_SIZE(max77802->opmode)) { + if (val == MAX77802_STATUS_OFF) + max77802->opmode[id] = MAX77802_OPMODE_NORMAL; + else + max77802->opmode[id] = val; + } rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); From bfa4ffd8159159ea17d4759a4c3a355a81617c99 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 16:53:58 -0800 Subject: [PATCH 0433/1017] regulator: s5m8767: Bounds check id indexing into arrays [ Upstream commit e314e15a0b58f9d051c00b25951073bcdae61953 ] The compiler has no way to know if "id" is within the array bounds of the regulators array. Add a check for this and a build-time check that the regulators and reg_voltage_map arrays are sized the same. Seen with GCC 13: ../drivers/regulator/s5m8767.c: In function 's5m8767_pmic_probe': ../drivers/regulator/s5m8767.c:936:35: warning: array subscript [0, 36] is outside array bounds of 'struct regulator_desc[37]' [-Warray-bounds=] 936 | regulators[id].vsel_reg = | ~~~~~~~~~~^~~~ Cc: Krzysztof Kozlowski Cc: Liam Girdwood Cc: Mark Brown Cc: linux-samsung-soc@vger.kernel.org Signed-off-by: Kees Cook Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230128005358.never.313-kees@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/s5m8767.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 35269f998210..754c6fcc6e64 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -923,10 +923,14 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) for (i = 0; i < pdata->num_regulators; i++) { const struct sec_voltage_desc *desc; - int id = pdata->regulators[i].id; + unsigned int id = pdata->regulators[i].id; int enable_reg, enable_val; struct regulator_dev *rdev; + BUILD_BUG_ON(ARRAY_SIZE(regulators) != ARRAY_SIZE(reg_voltage_map)); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(regulators))) + continue; + desc = reg_voltage_map[id]; if (desc) { regulators[id].n_voltages = From 2f8623377f3e0cfaa80558631b8694d02a492b4c Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Tue, 31 Jan 2023 15:06:53 +0100 Subject: [PATCH 0434/1017] gfs2: Improve gfs2_make_fs_rw error handling [ Upstream commit b66f723bb552ad59c2acb5d45ea45c890f84498b ] In gfs2_make_fs_rw(), make sure to call gfs2_consist() to report an inconsistency and mark the filesystem as withdrawn when gfs2_find_jhead() fails. At the end of gfs2_make_fs_rw(), when we discover that the filesystem has been withdrawn, make sure we report an error. This also replaces the gfs2_withdrawn() check after gfs2_find_jhead(). Reported-by: Tetsuo Handa Cc: syzbot+f51cb4b9afbd87ec06f2@syzkaller.appspotmail.com Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin --- fs/gfs2/super.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index d14b98aa1c3e..5cb7e771b57a 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -145,8 +145,10 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) return -EIO; error = gfs2_find_jhead(sdp->sd_jdesc, &head, false); - if (error || gfs2_withdrawn(sdp)) + if (error) { + gfs2_consist(sdp); return error; + } if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { gfs2_consist(sdp); @@ -158,7 +160,9 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) gfs2_log_pointers_init(sdp, head.lh_blkno); error = gfs2_quota_init(sdp); - if (!error && !gfs2_withdrawn(sdp)) + if (!error && gfs2_withdrawn(sdp)) + error = -EIO; + if (!error) set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); return error; } From 5735878a7b7db7e9ce731cb36cec298a9de67549 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 3 Jan 2023 12:46:20 +0100 Subject: [PATCH 0435/1017] hwmon: (coretemp) Simplify platform device handling [ Upstream commit 6d03bbff456befeccdd4d663177c4d6c75d0c4ff ] Coretemp's platform driver is unconventional. All the real work is done globally by the initcall and CPU hotplug notifiers, while the "driver" effectively just wraps an allocation and the registration of the hwmon interface in a long-winded round-trip through the driver core. The whole logic of dynamically creating and destroying platform devices to bring the interfaces up and down is error prone, since it assumes platform_device_add() will synchronously bind the driver and set drvdata before it returns, thus results in a NULL dereference if drivers_autoprobe is turned off for the platform bus. Furthermore, the unusual approach of doing that from within a CPU hotplug notifier, already commented in the code that it deadlocks suspend, also causes lockdep issues for other drivers or subsystems which may want to legitimately register a CPU hotplug notifier from a platform bus notifier. All of these issues can be solved by ripping this unusual behaviour out completely, simply tying the platform devices to the lifetime of the module itself, and directly managing the hwmon interfaces from the hotplug notifiers. There is a slight user-visible change in that /sys/bus/platform/drivers/coretemp will no longer appear, and /sys/devices/platform/coretemp.n will remain present if package n is hotplugged off, but hwmon users should really only be looking for the presence of the hwmon interfaces, whose behaviour remains unchanged. Link: https://lore.kernel.org/lkml/20220922101036.87457-1-janusz.krzysztofik@linux.intel.com/ Link: https://gitlab.freedesktop.org/drm/intel/issues/6641 Signed-off-by: Robin Murphy Signed-off-by: Janusz Krzysztofik Link: https://lore.kernel.org/r/20230103114620.15319-1-janusz.krzysztofik@linux.intel.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/coretemp.c | 134 ++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 73 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 42b84ebff057..eaae5de2ab61 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -550,66 +550,49 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx) ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO); } -static int coretemp_probe(struct platform_device *pdev) +static int coretemp_device_add(int zoneid) { - struct device *dev = &pdev->dev; + struct platform_device *pdev; struct platform_data *pdata; + int err; /* Initialize the per-zone data structures */ - pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL); + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - pdata->pkg_id = pdev->id; + pdata->pkg_id = zoneid; ida_init(&pdata->ida); - platform_set_drvdata(pdev, pdata); - - pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME, - pdata, NULL); - return PTR_ERR_OR_ZERO(pdata->hwmon_dev); -} - -static int coretemp_remove(struct platform_device *pdev) -{ - struct platform_data *pdata = platform_get_drvdata(pdev); - int i; - - for (i = MAX_CORE_DATA - 1; i >= 0; --i) - if (pdata->core_data[i]) - coretemp_remove_core(pdata, i); - - ida_destroy(&pdata->ida); - return 0; -} - -static struct platform_driver coretemp_driver = { - .driver = { - .name = DRVNAME, - }, - .probe = coretemp_probe, - .remove = coretemp_remove, -}; - -static struct platform_device *coretemp_device_add(unsigned int cpu) -{ - int err, zoneid = topology_logical_die_id(cpu); - struct platform_device *pdev; - - if (zoneid < 0) - return ERR_PTR(-ENOMEM); pdev = platform_device_alloc(DRVNAME, zoneid); - if (!pdev) - return ERR_PTR(-ENOMEM); - - err = platform_device_add(pdev); - if (err) { - platform_device_put(pdev); - return ERR_PTR(err); + if (!pdev) { + err = -ENOMEM; + goto err_free_pdata; } + err = platform_device_add(pdev); + if (err) + goto err_put_dev; + + platform_set_drvdata(pdev, pdata); zone_devices[zoneid] = pdev; - return pdev; + return 0; + +err_put_dev: + platform_device_put(pdev); +err_free_pdata: + kfree(pdata); + return err; +} + +static void coretemp_device_remove(int zoneid) +{ + struct platform_device *pdev = zone_devices[zoneid]; + struct platform_data *pdata = platform_get_drvdata(pdev); + + ida_destroy(&pdata->ida); + kfree(pdata); + platform_device_unregister(pdev); } static int coretemp_cpu_online(unsigned int cpu) @@ -633,7 +616,10 @@ static int coretemp_cpu_online(unsigned int cpu) if (!cpu_has(c, X86_FEATURE_DTHERM)) return -ENODEV; - if (!pdev) { + pdata = platform_get_drvdata(pdev); + if (!pdata->hwmon_dev) { + struct device *hwmon; + /* Check the microcode version of the CPU */ if (chk_ucode_version(cpu)) return -EINVAL; @@ -644,9 +630,11 @@ static int coretemp_cpu_online(unsigned int cpu) * online. So, initialize per-pkg data structures and * then bring this core online. */ - pdev = coretemp_device_add(cpu); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); + hwmon = hwmon_device_register_with_groups(&pdev->dev, DRVNAME, + pdata, NULL); + if (IS_ERR(hwmon)) + return PTR_ERR(hwmon); + pdata->hwmon_dev = hwmon; /* * Check whether pkgtemp support is available. @@ -656,7 +644,6 @@ static int coretemp_cpu_online(unsigned int cpu) coretemp_add_core(pdev, cpu, 1); } - pdata = platform_get_drvdata(pdev); /* * Check whether a thread sibling is already online. If not add the * interface for this CPU core. @@ -675,18 +662,14 @@ static int coretemp_cpu_offline(unsigned int cpu) struct temp_data *tdata; int i, indx = -1, target; - /* - * Don't execute this on suspend as the device remove locks - * up the machine. - */ + /* No need to tear down any interfaces for suspend */ if (cpuhp_tasks_frozen) return 0; /* If the physical CPU device does not exist, just return */ - if (!pdev) - return 0; - pd = platform_get_drvdata(pdev); + if (!pd->hwmon_dev) + return 0; for (i = 0; i < NUM_REAL_CORES; i++) { if (pd->cpu_map[i] == topology_core_id(cpu)) { @@ -718,13 +701,14 @@ static int coretemp_cpu_offline(unsigned int cpu) } /* - * If all cores in this pkg are offline, remove the device. This - * will invoke the platform driver remove function, which cleans up - * the rest. + * If all cores in this pkg are offline, remove the interface. */ + tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; if (cpumask_empty(&pd->cpumask)) { - zone_devices[topology_logical_die_id(cpu)] = NULL; - platform_device_unregister(pdev); + if (tdata) + coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO); + hwmon_device_unregister(pd->hwmon_dev); + pd->hwmon_dev = NULL; return 0; } @@ -732,7 +716,6 @@ static int coretemp_cpu_offline(unsigned int cpu) * Check whether this core is the target for the package * interface. We need to assign it to some other cpu. */ - tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; if (tdata && tdata->cpu == cpu) { target = cpumask_first(&pd->cpumask); mutex_lock(&tdata->update_lock); @@ -751,7 +734,7 @@ static enum cpuhp_state coretemp_hp_online; static int __init coretemp_init(void) { - int err; + int i, err; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal @@ -767,20 +750,22 @@ static int __init coretemp_init(void) if (!zone_devices) return -ENOMEM; - err = platform_driver_register(&coretemp_driver); - if (err) - goto outzone; + for (i = 0; i < max_zones; i++) { + err = coretemp_device_add(i); + if (err) + goto outzone; + } err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online", coretemp_cpu_online, coretemp_cpu_offline); if (err < 0) - goto outdrv; + goto outzone; coretemp_hp_online = err; return 0; -outdrv: - platform_driver_unregister(&coretemp_driver); outzone: + while (i--) + coretemp_device_remove(i); kfree(zone_devices); return err; } @@ -788,8 +773,11 @@ module_init(coretemp_init) static void __exit coretemp_exit(void) { + int i; + cpuhp_remove_state(coretemp_hp_online); - platform_driver_unregister(&coretemp_driver); + for (i = 0; i < max_zones; i++) + coretemp_device_remove(i); kfree(zone_devices); } module_exit(coretemp_exit) From ca64ebcb45019a1f80c16c4824b4493fa0c24dca Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 3 Feb 2023 15:27:14 +0200 Subject: [PATCH 0436/1017] pinctrl: at91: use devm_kasprintf() to avoid potential leaks [ Upstream commit 1c4e5c470a56f7f7c649c0c70e603abc1eab15c4 ] Use devm_kasprintf() instead of kasprintf() to avoid any potential leaks. At the moment drivers have no remove functionality thus there is no need for fixes tag. Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230203132714.1931596-1-claudiu.beznea@microchip.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-at91-pio4.c | 4 ++-- drivers/pinctrl/pinctrl-at91.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 578b387100d9..d2e2b101978f 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -1081,8 +1081,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) pin_desc[i].number = i; /* Pin naming convention: P(bank_name)(bank_pin_number). */ - pin_desc[i].name = kasprintf(GFP_KERNEL, "P%c%d", - bank + 'A', line); + pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d", + bank + 'A', line); group->name = group_names[i] = pin_desc[i].name; group->pin = pin_desc[i].number; diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 9015486e38c1..52ecd47c18e2 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1891,7 +1891,7 @@ static int at91_gpio_probe(struct platform_device *pdev) } for (i = 0; i < chip->ngpio; i++) - names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); + names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); chip->names = (const char *const *)names; From 7df5da8e6bcf27f09d74c55e3d6e3b8f7c973307 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 25 Jan 2023 13:17:22 +0100 Subject: [PATCH 0437/1017] HID: logitech-hidpp: Don't restart communication if not necessary [ Upstream commit 498ba20690357691103de0f766960355247c78be ] Don't stop and restart communication with the device unless we need to modify the connect flags used because of a device quirk. Signed-off-by: Bastien Nocera Link: https://lore.kernel.org/r/20230125121723.3122-1-hadess@hadess.net Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-logitech-hidpp.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 66b105162039..f5ea8e1d8445 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -3763,6 +3763,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) bool connected; unsigned int connect_mask = HID_CONNECT_DEFAULT; struct hidpp_ff_private_data data; + bool will_restart = false; /* report_fixup needs drvdata to be set before we call hid_parse */ hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); @@ -3818,6 +3819,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT || + hidpp->quirks & HIDPP_QUIRK_UNIFYING) + will_restart = true; + INIT_WORK(&hidpp->work, delayed_work_cb); mutex_init(&hidpp->send_mutex); init_waitqueue_head(&hidpp->wait); @@ -3832,7 +3837,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) * Plain USB connections need to actually call start and open * on the transport driver to allow incoming data. */ - ret = hid_hw_start(hdev, 0); + ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask); if (ret) { hid_err(hdev, "hw start failed\n"); goto hid_hw_start_fail; @@ -3869,6 +3874,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) hidpp->wireless_feature_index = 0; else if (ret) goto hid_hw_init_fail; + ret = 0; } if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { @@ -3883,19 +3889,21 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) hidpp_connect_event(hidpp); - /* Reset the HID node state */ - hid_device_io_stop(hdev); - hid_hw_close(hdev); - hid_hw_stop(hdev); + if (will_restart) { + /* Reset the HID node state */ + hid_device_io_stop(hdev); + hid_hw_close(hdev); + hid_hw_stop(hdev); - if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) - connect_mask &= ~HID_CONNECT_HIDINPUT; + if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) + connect_mask &= ~HID_CONNECT_HIDINPUT; - /* Now export the actual inputs and hidraw nodes to the world */ - ret = hid_hw_start(hdev, connect_mask); - if (ret) { - hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); - goto hid_hw_start_fail; + /* Now export the actual inputs and hidraw nodes to the world */ + ret = hid_hw_start(hdev, connect_mask); + if (ret) { + hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); + goto hid_hw_start_fail; + } } if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { From 861229a52bac05d8259346fe6959d125676b63cb Mon Sep 17 00:00:00 2001 From: Darrell Kavanagh Date: Tue, 14 Feb 2023 16:46:59 +0000 Subject: [PATCH 0438/1017] drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5 [ Upstream commit 38b2d8efd03d2e56431b611e3523f0158306451d ] Another Lenovo convertable where the panel is installed landscape but is reported to the kernel as portrait. Signed-off-by: Darrell Kavanagh Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20230214164659.3583-1-darrell.kavanagh@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index ce739ba45c55..8768073794fb 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -278,6 +278,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Lenovo IdeaPad Duet 3 10IGL5 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, }, { /* Lenovo Yoga Book X90F / X91F / X91L */ .matches = { /* Non exact match to match all versions */ From 52206dd1c77f04093be0dce7c9a6d58634ae6a53 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 16 Feb 2023 15:29:44 -0500 Subject: [PATCH 0439/1017] dm thin: add cond_resched() to various workqueue loops [ Upstream commit e4f80303c2353952e6e980b23914e4214487f2a6 ] Otherwise on resource constrained systems these workqueues may be too greedy. Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/dm-thin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index f3c519e18a12..c890bb3e5185 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2217,6 +2217,7 @@ static void process_thin_deferred_bios(struct thin_c *tc) throttle_work_update(&pool->throttle); dm_pool_issue_prefetches(pool->pmd); } + cond_resched(); } blk_finish_plug(&plug); } @@ -2299,6 +2300,7 @@ static void process_thin_deferred_cells(struct thin_c *tc) else pool->process_cell(tc, cell); } + cond_resched(); } while (!list_empty(&cells)); } From 9b8047b2100081e42b7c2a513db9bbeac9c25958 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 16 Feb 2023 15:31:08 -0500 Subject: [PATCH 0440/1017] dm cache: add cond_resched() to various workqueue loops [ Upstream commit 76227f6dc805e9e960128bcc6276647361e0827c ] Otherwise on resource constrained systems these workqueues may be too greedy. Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/dm-cache-target.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 9b2aec309801..f98ad4366301 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -1883,6 +1883,7 @@ static void process_deferred_bios(struct work_struct *ws) else commit_needed = process_bio(cache, bio) || commit_needed; + cond_resched(); } if (commit_needed) @@ -1905,6 +1906,7 @@ static void requeue_deferred_bios(struct cache *cache) while ((bio = bio_list_pop(&bios))) { bio->bi_status = BLK_STS_DM_REQUEUE; bio_endio(bio); + cond_resched(); } } @@ -1945,6 +1947,8 @@ static void check_migrations(struct work_struct *ws) r = mg_start(cache, op, NULL); if (r) break; + + cond_resched(); } } From 759f6a72bc5aaa44634adbac26e14fac709a3c8b Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 17 Jan 2023 14:38:30 -0500 Subject: [PATCH 0441/1017] nfsd: zero out pointers after putting nfsd_files on COPY setup error [ Upstream commit 1f0001d43d0c0ac2a19a34a914f6595ad97cbc1d ] At first, I thought this might be a source of nfsd_file overputs, but the current callers seem to avoid an extra put when nfsd4_verify_copy returns an error. Still, it's "bad form" to leave the pointers filled out when we don't have a reference to them anymore, and that might lead to bugs later. Zero them out as a defensive coding measure. Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4proc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 735ee8a79870..f82cfe843b99 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1075,8 +1075,10 @@ out: return status; out_put_dst: nfsd_file_put(*dst); + *dst = NULL; out_put_src: nfsd_file_put(*src); + *src = NULL; goto out; } From bf990eebeaa7585326ee7b02ea589480deda1181 Mon Sep 17 00:00:00 2001 From: Jun ASAKA Date: Sat, 17 Dec 2022 11:06:59 +0800 Subject: [PATCH 0442/1017] wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu commit c6015bf3ff1ffb3caa27eb913797438a0fc634a0 upstream. Fixing transmission failure which results in "authentication with ... timed out". This can be fixed by disable the REG_TXPAUSE. Signed-off-by: Jun ASAKA Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221217030659.12577-1-JunASAKA@zzy040330.moe Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c index 199e7e031d7d..3b3cb3a6e2e8 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -1671,6 +1671,11 @@ static void rtl8192e_enable_rf(struct rtl8xxxu_priv *priv) val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); val8 &= ~BIT(0); rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); + + /* + * Fix transmission failure of rtl8192e. + */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); } struct rtl8xxxu_fileops rtl8192eu_fops = { From e5b643645a9af861b31356374446dc34a8129a4e Mon Sep 17 00:00:00 2001 From: Alper Nebi Yasak Date: Sun, 22 Jan 2023 22:04:31 +0300 Subject: [PATCH 0443/1017] firmware: coreboot: framebuffer: Ignore reserved pixel color bits commit e6acaf25cba14661211bb72181c35dd13b24f5b3 upstream. The coreboot framebuffer doesn't support transparency, its 'reserved' bit field is merely padding for byte/word alignment of pixel colors [1]. When trying to match the framebuffer to a simplefb format, the kernel driver unnecessarily requires the format's transparency bit field to exactly match this padding, even if the former is zero-width. Due to a coreboot bug [2] (fixed upstream), some boards misreport the reserved field's size as equal to its position (0x18 for both on a 'Lick' Chromebook), and the driver fails to probe where it would have otherwise worked fine with e.g. the a8r8g8b8 or x8r8g8b8 formats. Remove the transparency comparison with reserved bits. When the bits-per-pixel and other color components match, transparency will already be in a subset of the reserved field. Not forcing it to match reserved bits allows the driver to work on the boards which misreport the reserved field. It also enables using simplefb formats that don't have transparency bits, although this doesn't currently happen due to format support and ordering in linux/platform_data/simplefb.h. [1] https://review.coreboot.org/plugins/gitiles/coreboot/+/4.19/src/commonlib/include/commonlib/coreboot_tables.h#255 [2] https://review.coreboot.org/plugins/gitiles/coreboot/+/4.13/src/drivers/intel/fsp2_0/graphics.c#82 Signed-off-by: Alper Nebi Yasak Link: https://lore.kernel.org/r/20230122190433.195941-1-alpernebiyasak@gmail.com Cc: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/google/framebuffer-coreboot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/firmware/google/framebuffer-coreboot.c b/drivers/firmware/google/framebuffer-coreboot.c index 916f26adc595..922c079d13c8 100644 --- a/drivers/firmware/google/framebuffer-coreboot.c +++ b/drivers/firmware/google/framebuffer-coreboot.c @@ -43,9 +43,7 @@ static int framebuffer_probe(struct coreboot_device *dev) fb->green_mask_pos == formats[i].green.offset && fb->green_mask_size == formats[i].green.length && fb->blue_mask_pos == formats[i].blue.offset && - fb->blue_mask_size == formats[i].blue.length && - fb->reserved_mask_pos == formats[i].transp.offset && - fb->reserved_mask_size == formats[i].transp.length) + fb->blue_mask_size == formats[i].blue.length) pdata.format = formats[i].name; } if (!pdata.format) From 66b40f8756d2ef55c60a20831fa5ce28ffdb6f03 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 2 Feb 2023 16:54:27 +0100 Subject: [PATCH 0444/1017] rtc: pm8xxx: fix set-alarm race commit c88db0eff9722fc2b6c4d172a50471d20e08ecc6 upstream. Make sure to disable the alarm before updating the four alarm time registers to avoid spurious alarms during the update. Note that the disable needs to be done outside of the ctrl_reg_lock section to prevent a racing alarm interrupt from disabling the newly set alarm when the lock is released. Fixes: 9a9a54ad7aa2 ("drivers/rtc: add support for Qualcomm PMIC8xxx RTC") Cc: stable@vger.kernel.org # 3.1 Signed-off-by: Johan Hovold Reviewed-by: David Collins Link: https://lore.kernel.org/r/20230202155448.6715-2-johan+linaro@kernel.org Signed-off-by: Alexandre Belloni Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-pm8xxx.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index b45ee2cb2c04..3417eef0aca3 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -219,7 +219,6 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { int rc, i; u8 value[NUM_8_BIT_RTC_REGS]; - unsigned int ctrl_reg; unsigned long secs, irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; @@ -231,6 +230,11 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) secs >>= 8; } + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, 0); + if (rc) + return rc; + spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, @@ -240,19 +244,11 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) goto rtc_rw_fail; } - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); - if (rc) - goto rtc_rw_fail; - - if (alarm->enabled) - ctrl_reg |= regs->alarm_en; - else - ctrl_reg &= ~regs->alarm_en; - - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC alarm control register failed\n"); - goto rtc_rw_fail; + if (alarm->enabled) { + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, regs->alarm_en); + if (rc) + goto rtc_rw_fail; } dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n", From be2dad7bc932216f9db755e92cbfda46b0dfa513 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 25 Jan 2023 10:13:13 -0600 Subject: [PATCH 0445/1017] ipmi_ssif: Rename idle state and check commit 8230831c43a328c2be6d28c65d3f77e14c59986b upstream. Rename the SSIF_IDLE() to IS_SSIF_IDLE(), since that is more clear, and rename SSIF_NORMAL to SSIF_IDLE, since that's more accurate. Cc: stable@vger.kernel.org Signed-off-by: Corey Minyard Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_ssif.c | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 477139749513..0f2bac24e564 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -92,7 +92,7 @@ #define SSIF_WATCH_WATCHDOG_TIMEOUT msecs_to_jiffies(250) enum ssif_intf_state { - SSIF_NORMAL, + SSIF_IDLE, SSIF_GETTING_FLAGS, SSIF_GETTING_EVENTS, SSIF_CLEARING_FLAGS, @@ -100,8 +100,8 @@ enum ssif_intf_state { /* FIXME - add watchdog stuff. */ }; -#define SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_NORMAL \ - && (ssif)->curr_msg == NULL) +#define IS_SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_IDLE \ + && (ssif)->curr_msg == NULL) /* * Indexes into stats[] in ssif_info below. @@ -348,9 +348,9 @@ static void return_hosed_msg(struct ssif_info *ssif_info, /* * Must be called with the message lock held. This will release the - * message lock. Note that the caller will check SSIF_IDLE and start a - * new operation, so there is no need to check for new messages to - * start in here. + * message lock. Note that the caller will check IS_SSIF_IDLE and + * start a new operation, so there is no need to check for new + * messages to start in here. */ static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) { @@ -367,7 +367,7 @@ static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) if (start_send(ssif_info, msg, 3) != 0) { /* Error, just go to normal state. */ - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; } } @@ -382,7 +382,7 @@ static void start_flag_fetch(struct ssif_info *ssif_info, unsigned long *flags) mb[0] = (IPMI_NETFN_APP_REQUEST << 2); mb[1] = IPMI_GET_MSG_FLAGS_CMD; if (start_send(ssif_info, mb, 2) != 0) - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; } static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, @@ -393,7 +393,7 @@ static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, flags = ipmi_ssif_lock_cond(ssif_info, &oflags); ssif_info->curr_msg = NULL; - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); ipmi_free_smi_msg(msg); } @@ -407,7 +407,7 @@ static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags) msg = ipmi_alloc_smi_msg(); if (!msg) { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -430,7 +430,7 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info, msg = ipmi_alloc_smi_msg(); if (!msg) { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -448,9 +448,9 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info, /* * Must be called with the message lock held. This will release the - * message lock. Note that the caller will check SSIF_IDLE and start a - * new operation, so there is no need to check for new messages to - * start in here. + * message lock. Note that the caller will check IS_SSIF_IDLE and + * start a new operation, so there is no need to check for new + * messages to start in here. */ static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) { @@ -466,7 +466,7 @@ static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) /* Events available. */ start_event_fetch(ssif_info, flags); else { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); } } @@ -579,7 +579,7 @@ static void watch_timeout(struct timer_list *t) if (ssif_info->watch_timeout) { mod_timer(&ssif_info->watch_timer, jiffies + ssif_info->watch_timeout); - if (SSIF_IDLE(ssif_info)) { + if (IS_SSIF_IDLE(ssif_info)) { start_flag_fetch(ssif_info, flags); /* Releases lock */ return; } @@ -782,7 +782,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, } switch (ssif_info->ssif_state) { - case SSIF_NORMAL: + case SSIF_IDLE: ipmi_ssif_unlock_cond(ssif_info, flags); if (!msg) break; @@ -800,7 +800,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, * Error fetching flags, or invalid length, * just give up for now. */ - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); dev_warn(&ssif_info->client->dev, "Error getting flags: %d %d, %x\n", @@ -835,7 +835,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, "Invalid response clearing flags: %x %x\n", data[0], data[1]); } - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); break; @@ -913,7 +913,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, } flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) { + if (IS_SSIF_IDLE(ssif_info) && !ssif_info->stopping) { if (ssif_info->req_events) start_event_fetch(ssif_info, flags); else if (ssif_info->req_flags) @@ -1087,7 +1087,7 @@ static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags) unsigned long oflags; restart: - if (!SSIF_IDLE(ssif_info)) { + if (!IS_SSIF_IDLE(ssif_info)) { ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -1310,7 +1310,7 @@ static void shutdown_ssif(void *send_info) dev_set_drvdata(&ssif_info->client->dev, NULL); /* make sure the driver is not looking for flags any more. */ - while (ssif_info->ssif_state != SSIF_NORMAL) + while (ssif_info->ssif_state != SSIF_IDLE) schedule_timeout(1); ssif_info->stopping = true; @@ -1882,7 +1882,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) } spin_lock_init(&ssif_info->lock); - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; timer_setup(&ssif_info->retry_timer, retry_timeout, 0); timer_setup(&ssif_info->watch_timer, watch_timeout, 0); From 6cf48403c46ae4f4ac74a439ca2ff2ddb5eab8c5 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 27 Feb 2023 20:03:00 +0100 Subject: [PATCH 0446/1017] s390/extmem: return correct segment type in __segment_load() commit 8c42dd78df148c90e48efff204cce38743906a79 upstream. Commit f05f62d04271f ("s390/vmem: get rid of memory segment list") reshuffled the call to vmem_add_mapping() in __segment_load(), which now overwrites rc after it was set to contain the segment type code. As result, __segment_load() will now always return 0 on success, which corresponds to the segment type code SEG_TYPE_SW, i.e. a writeable segment. This results in a kernel crash when loading a read-only segment as dcssblk block device, and trying to write to it. Instead of reshuffling code again, make sure to return the segment type on success, and also describe this rather delicate and unexpected logic in the function comment. Also initialize new segtype variable with invalid value, to prevent possible future confusion. Fixes: f05f62d04271 ("s390/vmem: get rid of memory segment list") Cc: # 5.9+ Signed-off-by: Gerald Schaefer Reviewed-by: Heiko Carstens Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- arch/s390/mm/extmem.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 5060956b8e7d..1bc42ce26599 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -289,15 +289,17 @@ segment_overlaps_others (struct dcss_segment *seg) /* * real segment loading function, called from segment_load + * Must return either an error code < 0, or the segment type code >= 0 */ static int __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end) { unsigned long start_addr, end_addr, dummy; struct dcss_segment *seg; - int rc, diag_cc; + int rc, diag_cc, segtype; start_addr = end_addr = 0; + segtype = -1; seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA); if (seg == NULL) { rc = -ENOMEM; @@ -326,9 +328,9 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long seg->res_name[8] = '\0'; strlcat(seg->res_name, " (DCSS)", sizeof(seg->res_name)); seg->res->name = seg->res_name; - rc = seg->vm_segtype; - if (rc == SEG_TYPE_SC || - ((rc == SEG_TYPE_SR || rc == SEG_TYPE_ER) && !do_nonshared)) + segtype = seg->vm_segtype; + if (segtype == SEG_TYPE_SC || + ((segtype == SEG_TYPE_SR || segtype == SEG_TYPE_ER) && !do_nonshared)) seg->res->flags |= IORESOURCE_READONLY; /* Check for overlapping resources before adding the mapping. */ @@ -386,7 +388,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long out_free: kfree(seg); out: - return rc; + return rc < 0 ? rc : segtype; } /* From d43abcf91c5ed55443d26cd8c7721bd8409a7aff Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Mon, 23 Jan 2023 22:50:32 +0100 Subject: [PATCH 0447/1017] s390: discard .interp section commit e9c9cb90e76ffaabcc7ca8f275d9e82195fd6367 upstream. When debugging vmlinux with QEMU + GDB, the following GDB error may occur: (gdb) c Continuing. Warning: Cannot insert breakpoint -1. Cannot access memory at address 0xffffffffffff95c0 Command aborted. (gdb) The reason is that, when .interp section is present, GDB tries to locate the file specified in it in memory and put a number of breakpoints there (see enable_break() function in gdb/solib-svr4.c). Sometimes GDB finds a bogus location that matches its heuristics, fails to set a breakpoint and stops. This makes further debugging impossible. The .interp section contains misleading information anyway (vmlinux does not need ld.so), so fix by discarding it. Signed-off-by: Ilya Leoshkevich Cc: Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 9505bdb0aa54..d7291eb0d0c0 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -188,5 +188,6 @@ SECTIONS DISCARDS /DISCARD/ : { *(.eh_frame) + *(.interp) } } From d8724dc0ce7642081b399ad5c1009cc4964d8ac7 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Wed, 1 Mar 2023 02:23:08 +0100 Subject: [PATCH 0448/1017] s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler commit 42e19e6f04984088b6f9f0507c4c89a8152d9730 upstream. Recent test_kprobe_missed kprobes kunit test uncovers the following error (reported when CONFIG_DEBUG_ATOMIC_SLEEP is enabled): BUG: sleeping function called from invalid context at kernel/locking/mutex.c:580 in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 662, name: kunit_try_catch preempt_count: 0, expected: 0 RCU nest depth: 0, expected: 0 no locks held by kunit_try_catch/662. irq event stamp: 280 hardirqs last enabled at (279): [<00000003e60a3d42>] __do_pgm_check+0x17a/0x1c0 hardirqs last disabled at (280): [<00000003e3bd774a>] kprobe_exceptions_notify+0x27a/0x318 softirqs last enabled at (0): [<00000003e3c5c890>] copy_process+0x14a8/0x4c80 softirqs last disabled at (0): [<0000000000000000>] 0x0 CPU: 46 PID: 662 Comm: kunit_try_catch Tainted: G N 6.2.0-173644-g44c18d77f0c0 #2 Hardware name: IBM 3931 A01 704 (LPAR) Call Trace: [<00000003e60a3a00>] dump_stack_lvl+0x120/0x198 [<00000003e3d02e82>] __might_resched+0x60a/0x668 [<00000003e60b9908>] __mutex_lock+0xc0/0x14e0 [<00000003e60bad5a>] mutex_lock_nested+0x32/0x40 [<00000003e3f7b460>] unregister_kprobe+0x30/0xd8 [<00000003e51b2602>] test_kprobe_missed+0xf2/0x268 [<00000003e51b5406>] kunit_try_run_case+0x10e/0x290 [<00000003e51b7dfa>] kunit_generic_run_threadfn_adapter+0x62/0xb8 [<00000003e3ce30f8>] kthread+0x2d0/0x398 [<00000003e3b96afa>] __ret_from_fork+0x8a/0xe8 [<00000003e60ccada>] ret_from_fork+0xa/0x40 The reason for this error report is that kprobes handling code failed to restore irqs. The problem is that when kprobe is triggered from another kprobe post_handler current sequence of enable_singlestep / disable_singlestep is the following: enable_singlestep <- original kprobe (saves kprobe_saved_imask) enable_singlestep <- kprobe triggered from post_handler (clobbers kprobe_saved_imask) disable_singlestep <- kprobe triggered from post_handler (restores kprobe_saved_imask) disable_singlestep <- original kprobe (restores wrong clobbered kprobe_saved_imask) There is just one kprobe_ctlblk per cpu and both calls saves and loads irq mask to kprobe_saved_imask. To fix the problem simply move resume_execution (which calls disable_singlestep) before calling post_handler. This also fixes the problem that post_handler is called with pt_regs which were not yet adjusted after single-stepping. Cc: stable@vger.kernel.org Fixes: 4ba069b802c2 ("[S390] add kprobes support.") Reviewed-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/kprobes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index aae24dc75df6..4f0d5ead3547 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -402,12 +402,11 @@ static int post_kprobe_handler(struct pt_regs *regs) if (!p) return 0; + resume_execution(p, regs); if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) { kcb->kprobe_status = KPROBE_HIT_SSDONE; p->post_handler(p, regs, 0); } - - resume_execution(p, regs); pop_kprobe(kcb); preempt_enable_no_resched(); From 59102ded74805820e5114ead1f7bb5a84bc029e2 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Wed, 1 Mar 2023 17:58:06 +0100 Subject: [PATCH 0449/1017] s390/kprobes: fix current_kprobe never cleared after kprobes reenter commit cd57953936f2213dfaccce10d20f396956222c7d upstream. Recent test_kprobe_missed kprobes kunit test uncovers the following problem. Once kprobe is triggered from another kprobe (kprobe reenter), all future kprobes on this cpu are considered as kprobe reenter, thus pre_handler and post_handler are not being called and kprobes are counted as "missed". Commit b9599798f953 ("[S390] kprobes: activation and deactivation") introduced a simpler scheme for kprobes (de)activation and status tracking by using push_kprobe/pop_kprobe, which supposed to work for both initial kprobe entry as well as kprobe reentry and helps to avoid handling those two cases differently. The problem is that a sequence of calls in case of kprobes reenter: push_kprobe() <- NULL (current_kprobe) push_kprobe() <- kprobe1 (current_kprobe) pop_kprobe() -> kprobe1 (current_kprobe) pop_kprobe() -> kprobe1 (current_kprobe) leaves "kprobe1" as "current_kprobe" on this cpu, instead of setting it to NULL. In fact push_kprobe/pop_kprobe can only store a single state (there is just one prev_kprobe in kprobe_ctlblk). Which is a hack but sufficient, there is no need to have another prev_kprobe just to store NULL. To make a simple and backportable fix simply reset "prev_kprobe" when kprobe is poped from this "stack". No need to worry about "kprobe_status" in this case, because its value is only checked when current_kprobe != NULL. Cc: stable@vger.kernel.org Fixes: b9599798f953 ("[S390] kprobes: activation and deactivation") Reviewed-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/kprobes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 4f0d5ead3547..0f7e7a68d57b 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -241,6 +241,7 @@ static void pop_kprobe(struct kprobe_ctlblk *kcb) { __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; + kcb->prev_kprobe.kp = NULL; } NOKPROBE_SYMBOL(pop_kprobe); From 69493675fdfb81192981bf106533c248cc980752 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 11 Jan 2023 12:37:58 +0100 Subject: [PATCH 0450/1017] cifs: Fix uninitialized memory read in smb3_qfs_tcon() commit d447e794a37288ec7a080aa1b044a8d9deebbab7 upstream. oparms was not fully initialized Signed-off-by: Volker Lendecke Reviewed-by: Paulo Alcantara (SUSE) Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2ops.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 844db4652dd1..8fdd34ff20ef 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -859,12 +859,13 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon, bool no_cached_open = tcon->nohandlecache; struct cached_fid *cfid = NULL; - oparms.tcon = tcon; - oparms.desired_access = FILE_READ_ATTRIBUTES; - oparms.disposition = FILE_OPEN; - oparms.create_options = cifs_create_options(cifs_sb, 0); - oparms.fid = &fid; - oparms.reconnect = false; + oparms = (struct cifs_open_parms) { + .tcon = tcon, + .desired_access = FILE_READ_ATTRIBUTES, + .disposition = FILE_OPEN, + .create_options = cifs_create_options(cifs_sb, 0), + .fid = &fid, + }; if (no_cached_open) { rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, From 300b6404e60161355bca54552ae38b49c3bbf63d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 25 Jan 2023 10:45:05 +0100 Subject: [PATCH 0451/1017] ARM: dts: exynos: correct HDMI phy compatible in Exynos4 commit af1c89ddb74f170eccd5a57001d7317560b638ea upstream. The HDMI phy compatible was missing vendor prefix. Fixes: ed80d4cab772 ("ARM: dts: add hdmi related nodes for exynos4 SoCs") Cc: Link: https://lore.kernel.org/r/20230125094513.155063-1-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos4.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index a1e54449f33f..41f0e64b1365 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -605,7 +605,7 @@ status = "disabled"; hdmi_i2c_phy: hdmiphy@38 { - compatible = "exynos4210-hdmiphy"; + compatible = "samsung,exynos4210-hdmiphy"; reg = <0x38>; }; }; From dc9f78b6d254427a06e568f2887b1011ef3143ef Mon Sep 17 00:00:00 2001 From: Liu Shixin Date: Mon, 12 Dec 2022 10:16:27 +0800 Subject: [PATCH 0452/1017] hfs: fix missing hfs_bnode_get() in __hfs_bnode_create commit a9dc087fd3c484fd1ed18c5efb290efaaf44ce03 upstream. Syzbot found a kernel BUG in hfs_bnode_put(): kernel BUG at fs/hfs/bnode.c:466! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 3634 Comm: kworker/u4:5 Not tainted 6.1.0-rc7-syzkaller-00190-g97ee9d1c1696 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Workqueue: writeback wb_workfn (flush-7:0) RIP: 0010:hfs_bnode_put+0x46f/0x480 fs/hfs/bnode.c:466 Code: 8a 80 ff e9 73 fe ff ff 89 d9 80 e1 07 80 c1 03 38 c1 0f 8c a0 fe ff ff 48 89 df e8 db 8a 80 ff e9 93 fe ff ff e8 a1 68 2c ff <0f> 0b e8 9a 68 2c ff 0f 0b 0f 1f 84 00 00 00 00 00 55 41 57 41 56 RSP: 0018:ffffc90003b4f258 EFLAGS: 00010293 RAX: ffffffff825e318f RBX: 0000000000000000 RCX: ffff8880739dd7c0 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffc90003b4f430 R08: ffffffff825e2d9b R09: ffffed10045157d1 R10: ffffed10045157d1 R11: 1ffff110045157d0 R12: ffff8880228abe80 R13: ffff88807016c000 R14: dffffc0000000000 R15: ffff8880228abe00 FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa6ebe88718 CR3: 000000001e93d000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: hfs_write_inode+0x1bc/0xb40 write_inode fs/fs-writeback.c:1440 [inline] __writeback_single_inode+0x4d6/0x670 fs/fs-writeback.c:1652 writeback_sb_inodes+0xb3b/0x18f0 fs/fs-writeback.c:1878 __writeback_inodes_wb+0x125/0x420 fs/fs-writeback.c:1949 wb_writeback+0x440/0x7b0 fs/fs-writeback.c:2054 wb_check_start_all fs/fs-writeback.c:2176 [inline] wb_do_writeback fs/fs-writeback.c:2202 [inline] wb_workfn+0x827/0xef0 fs/fs-writeback.c:2235 process_one_work+0x877/0xdb0 kernel/workqueue.c:2289 worker_thread+0xb14/0x1330 kernel/workqueue.c:2436 kthread+0x266/0x300 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 The BUG_ON() is triggered at here: /* Dispose of resources used by a node */ void hfs_bnode_put(struct hfs_bnode *node) { if (node) { BUG_ON(!atomic_read(&node->refcnt)); <- we have issue here!!!! } } By tracing the refcnt, I found the node is created by hfs_bmap_alloc() with refcnt 1. Then the node is used by hfs_btree_write(). There is a missing of hfs_bnode_get() after find the node. The issue happened in following path: hfs_bmap_alloc hfs_bnode_find __hfs_bnode_create <- allocate a new node with refcnt 1. hfs_bnode_put <- decrease the refcnt hfs_btree_write hfs_bnode_find __hfs_bnode_create hfs_bnode_findhash <- find the node without refcnt increased. hfs_bnode_put <- trigger the BUG_ON() since refcnt is 0. Link: https://lkml.kernel.org/r/20221212021627.3766829-1-liushixin2@huawei.com Reported-by: syzbot+5b04b49a7ec7226c7426@syzkaller.appspotmail.com Signed-off-by: Liu Shixin Cc: Fabio M. De Francesco Cc: Viacheslav Dubeyko Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/hfs/bnode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index c0a73a6ffb28..397e02a56697 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -281,6 +281,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) tree->node_hash[hash] = node; tree->node_hash_cnt++; } else { + hfs_bnode_get(node2); spin_unlock(&tree->hash_lock); kfree(node); wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags)); From ef7d71d7bd57b8b7fe514e459927696c1c6d1047 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Sun, 26 Feb 2023 20:49:47 +0800 Subject: [PATCH 0453/1017] fs: hfsplus: fix UAF issue in hfsplus_put_super commit 07db5e247ab5858439b14dd7cc1fe538b9efcf32 upstream. The current hfsplus_put_super first calls hfs_btree_close on sbi->ext_tree, then invokes iput on sbi->hidden_dir, resulting in an use-after-free issue in hfsplus_release_folio. As shown in hfsplus_fill_super, the error handling code also calls iput before hfs_btree_close. To fix this error, we move all iput calls before hfsplus_btree_close. Note that this patch is tested on Syzbot. Link: https://lkml.kernel.org/r/20230226124948.3175736-1-mudongliangabcd@gmail.com Reported-by: syzbot+57e3e98f7e3b80f64d56@syzkaller.appspotmail.com Tested-by: Dongliang Mu Signed-off-by: Dongliang Mu Cc: Bart Van Assche Cc: Jens Axboe Cc: Muchun Song Cc: Roman Gushchin Cc: "Theodore Ts'o" Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/hfsplus/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 807119ae5adf..7648f64a17a8 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -295,11 +295,11 @@ static void hfsplus_put_super(struct super_block *sb) hfsplus_sync_fs(sb, 1); } + iput(sbi->alloc_file); + iput(sbi->hidden_dir); hfs_btree_close(sbi->attr_tree); hfs_btree_close(sbi->cat_tree); hfs_btree_close(sbi->ext_tree); - iput(sbi->alloc_file); - iput(sbi->hidden_dir); kfree(sbi->s_vhdr_buf); kfree(sbi->s_backup_vhdr_buf); unload_nls(sbi->nls); From 34b05883414cc97e4c592988bb45225aede4ff63 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 20 Oct 2022 14:27:37 +0800 Subject: [PATCH 0454/1017] exfat: fix reporting fs error when reading dir beyond EOF commit 706fdcac002316893434d753be8cfb549fe1d40d upstream. Since seekdir() does not check whether the position is valid, the position may exceed the size of the directory. We found that for a directory with discontinuous clusters, if the position exceeds the size of the directory and the excess size is greater than or equal to the cluster size, exfat_readdir() will return -EIO, causing a file system error and making the file system unavailable. Reproduce this bug by: seekdir(dir, dir_size + cluster_size); dirent = readdir(dir); The following log will be printed if mount with 'errors=remount-ro'. [11166.712896] exFAT-fs (sdb1): error, invalid access to FAT (entry 0xffffffff) [11166.712905] exFAT-fs (sdb1): Filesystem has been set read-only Fixes: 1e5654de0f51 ("exfat: handle wrong stream entry size in exfat_readdir()") Cc: stable@vger.kernel.org # v5.7+ Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon Signed-off-by: Greg Kroah-Hartman --- fs/exfat/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index dedbc55cd48f..09c5ea4c4556 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -102,7 +102,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent clu.dir = ei->hint_bmap.clu; } - while (clu_offset > 0) { + while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) { if (exfat_get_next_cluster(sb, &(clu.dir))) return -EIO; From c2d1997074ce3207cd779c26bc8b32b077d93085 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Thu, 22 Sep 2022 14:43:47 +0800 Subject: [PATCH 0455/1017] exfat: fix unexpected EOF while reading dir commit 6cb5d1a16a51d080fbc1649a5144cbc5ca7d6f88 upstream. If the position is not aligned with the dentry size, the return value of readdir() will be NULL and errno is 0, which means the end of the directory stream is reached. If the position is aligned with dentry size, but there is no file or directory at the position, exfat_readdir() will continue to get dentry from the next dentry. So the dentry gotten by readdir() may not be at the position. After this commit, if the position is not aligned with the dentry size, round the position up to the dentry size and continue to get the dentry. Fixes: ca06197382bd ("exfat: add directory operations") Cc: stable@vger.kernel.org # v5.7+ Reported-by: Wang Yugui Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Reviewed-by: Aoyama Wataru Reviewed-by: Sungjong Seo Signed-off-by: Namjae Jeon Signed-off-by: Greg Kroah-Hartman --- fs/exfat/dir.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 09c5ea4c4556..6caded58cda5 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -236,10 +236,7 @@ static int exfat_iterate(struct file *filp, struct dir_context *ctx) fake_offset = 1; } - if (cpos & (DENTRY_SIZE - 1)) { - err = -ENOENT; - goto unlock; - } + cpos = round_up(cpos, DENTRY_SIZE); /* name buffer should be allocated before use */ err = exfat_alloc_namebuf(nb); From 4017209e08d23ab6f52f51caa7a81df23a7fd8f8 Mon Sep 17 00:00:00 2001 From: Sungjong Seo Date: Thu, 29 Dec 2022 20:52:38 +0900 Subject: [PATCH 0456/1017] exfat: redefine DIR_DELETED as the bad cluster number commit bdaadfd343e3cba49ad0b009ff4b148dad0fa404 upstream. When a file or a directory is deleted, the hint for the cluster of its parent directory in its in-memory inode is set as DIR_DELETED. Therefore, DIR_DELETED must be one of invalid cluster numbers. According to the exFAT specification, a volume can have at most 2^32-11 clusters. However, DIR_DELETED is wrongly defined as 0xFFFF0321, which could be a valid cluster number. To fix it, let's redefine DIR_DELETED as 0xFFFFFFF7, the bad cluster number. Fixes: 1acf1a564b60 ("exfat: add in-memory and on-disk structures and headers") Cc: stable@vger.kernel.org # v5.7+ Reported-by: Yuezhang Mo Signed-off-by: Sungjong Seo Signed-off-by: Namjae Jeon Signed-off-by: Greg Kroah-Hartman --- fs/exfat/exfat_fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 0d139c7d150d..07b09af57436 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -42,7 +42,7 @@ enum { #define ES_2_ENTRIES 2 #define ES_ALL_ENTRIES 0 -#define DIR_DELETED 0xFFFF0321 +#define DIR_DELETED 0xFFFFFFF7 /* type values */ #define TYPE_UNUSED 0x0000 From f9dbc35ecb9431d1396f550c4a471486e3133b68 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Wed, 4 Jan 2023 14:37:47 +0800 Subject: [PATCH 0457/1017] exfat: fix inode->i_blocks for non-512 byte sector size device commit 39c1ce8eafc0ff64fb9e28536ccc7df6a8e2999d upstream. inode->i_blocks is not real number of blocks, but 512 byte ones. Fixes: 98d917047e8b ("exfat: add file operations") Cc: stable@vger.kernel.org # v5.7+ Reported-by: Wang Yugui Tested-by: Wang Yugui Signed-off-by: Yuezhang Mo Reviewed-by: Andy Wu Signed-off-by: Namjae Jeon Signed-off-by: Greg Kroah-Hartman --- fs/exfat/file.c | 3 +-- fs/exfat/inode.c | 6 ++---- fs/exfat/namei.c | 2 +- fs/exfat/super.c | 3 +-- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/fs/exfat/file.c b/fs/exfat/file.c index c819e8427ea5..819f47278305 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -250,8 +250,7 @@ void exfat_truncate(struct inode *inode, loff_t size) else mark_inode_dirty(inode); - inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> - inode->i_blkbits; + inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; write_size: aligned_size = i_size_read(inode); if (aligned_size & (blocksize - 1)) { diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index 2a9f6a80584e..4bd73820a4ac 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -242,8 +242,7 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset, return err; } /* end of if != DIR_DELETED */ - inode->i_blocks += - num_to_be_allocated << sbi->sect_per_clus_bits; + inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9; /* * Move *clu pointer along FAT chains (hole care) because the @@ -600,8 +599,7 @@ static int exfat_fill_inode(struct inode *inode, struct exfat_dir_entry *info) exfat_save_attr(inode, info->attr); - inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> - inode->i_blkbits; + inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; inode->i_mtime = info->mtime; inode->i_ctime = info->mtime; ei->i_crtime = info->crtime; diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 935f60050900..1382d816912c 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -398,7 +398,7 @@ static int exfat_find_empty_entry(struct inode *inode, ei->i_size_ondisk += sbi->cluster_size; ei->i_size_aligned += sbi->cluster_size; ei->flags = p_dir->flags; - inode->i_blocks += 1 << sbi->sect_per_clus_bits; + inode->i_blocks += sbi->cluster_size >> 9; } return dentry; diff --git a/fs/exfat/super.c b/fs/exfat/super.c index ba70ed1c9804..62d79af257a9 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -364,8 +364,7 @@ static int exfat_read_root(struct inode *inode) inode->i_op = &exfat_dir_inode_operations; inode->i_fop = &exfat_dir_operations; - inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> - inode->i_blkbits; + inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff; ei->i_size_aligned = i_size_read(inode); ei->i_size_ondisk = i_size_read(inode); From 00b5587326625d0fddb2a5f5a3d4acd950102ace Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 22 Jan 2023 23:04:14 -0800 Subject: [PATCH 0458/1017] f2fs: fix information leak in f2fs_move_inline_dirents() commit 9a5571cff4ffcfc24847df9fd545cc5799ac0ee5 upstream. When converting an inline directory to a regular one, f2fs is leaking uninitialized memory to disk because it doesn't initialize the entire directory block. Fix this by zero-initializing the block. This bug was introduced by commit 4ec17d688d74 ("f2fs: avoid unneeded initializing when converting inline dentry"), which didn't consider the security implications of leaking uninitialized memory to disk. This was found by running xfstest generic/435 on a KMSAN-enabled kernel. Fixes: 4ec17d688d74 ("f2fs: avoid unneeded initializing when converting inline dentry") Cc: # v4.3+ Signed-off-by: Eric Biggers Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/inline.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index f97c23ec93ce..4e794c1390cc 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -420,18 +420,17 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage, dentry_blk = page_address(page); + /* + * Start by zeroing the full block, to ensure that all unused space is + * zeroed and no uninitialized memory is leaked to disk. + */ + memset(dentry_blk, 0, F2FS_BLKSIZE); + make_dentry_ptr_inline(dir, &src, inline_dentry); make_dentry_ptr_block(dir, &dst, dentry_blk); /* copy data from inline dentry block to new dentry block */ memcpy(dst.bitmap, src.bitmap, src.nr_bitmap); - memset(dst.bitmap + src.nr_bitmap, 0, dst.nr_bitmap - src.nr_bitmap); - /* - * we do not need to zero out remainder part of dentry and filename - * field, since we have used bitmap for marking the usage status of - * them, besides, we can also ignore copying/zeroing reserved space - * of dentry block, because them haven't been used so far. - */ memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max); memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN); From e9f20138b5fb1a70e3ff5b50606f65e4461eda9e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 2 Feb 2023 17:02:39 -0800 Subject: [PATCH 0459/1017] f2fs: fix cgroup writeback accounting with fs-layer encryption commit 844545c51a5b2a524b22a2fe9d0b353b827d24b4 upstream. When writing a page from an encrypted file that is using filesystem-layer encryption (not inline encryption), f2fs encrypts the pagecache page into a bounce page, then writes the bounce page. It also passes the bounce page to wbc_account_cgroup_owner(). That's incorrect, because the bounce page is a newly allocated temporary page that doesn't have the memory cgroup of the original pagecache page. This makes wbc_account_cgroup_owner() not account the I/O to the owner of the pagecache page as it should. Fix this by always passing the pagecache page to wbc_account_cgroup_owner(). Fixes: 578c647879f7 ("f2fs: implement cgroup writeback support") Cc: stable@vger.kernel.org Reported-by: Matthew Wilcox (Oracle) Signed-off-by: Eric Biggers Acked-by: Tejun Heo Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/data.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 9270330ec5ce..db26e87b8f0d 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -721,7 +721,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) } if (fio->io_wbc && !is_read_io(fio->op)) - wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE); + wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE); __attach_io_flag(fio); bio_set_op_attrs(bio, fio->op, fio->op_flags); @@ -929,7 +929,7 @@ alloc_new: } if (fio->io_wbc) - wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE); + wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE); inc_page_count(fio->sbi, WB_DATA_TYPE(page)); @@ -1003,7 +1003,7 @@ alloc_new: } if (fio->io_wbc) - wbc_account_cgroup_owner(fio->io_wbc, bio_page, PAGE_SIZE); + wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE); io->last_block_in_bio = fio->new_blkaddr; f2fs_trace_ios(fio, 0); From 2c559b3ba8e0b9e3c4bb08159a28ccadc698410f Mon Sep 17 00:00:00 2001 From: Heming Zhao via Ocfs2-devel Date: Fri, 17 Feb 2023 08:37:17 +0800 Subject: [PATCH 0460/1017] ocfs2: fix defrag path triggering jbd2 ASSERT commit 60eed1e3d45045623e46944ebc7c42c30a4350f0 upstream. code path: ocfs2_ioctl_move_extents ocfs2_move_extents ocfs2_defrag_extent __ocfs2_move_extent + ocfs2_journal_access_di + ocfs2_split_extent //sub-paths call jbd2_journal_restart + ocfs2_journal_dirty //crash by jbs2 ASSERT crash stacks: PID: 11297 TASK: ffff974a676dcd00 CPU: 67 COMMAND: "defragfs.ocfs2" #0 [ffffb25d8dad3900] machine_kexec at ffffffff8386fe01 #1 [ffffb25d8dad3958] __crash_kexec at ffffffff8395959d #2 [ffffb25d8dad3a20] crash_kexec at ffffffff8395a45d #3 [ffffb25d8dad3a38] oops_end at ffffffff83836d3f #4 [ffffb25d8dad3a58] do_trap at ffffffff83833205 #5 [ffffb25d8dad3aa0] do_invalid_op at ffffffff83833aa6 #6 [ffffb25d8dad3ac0] invalid_op at ffffffff84200d18 [exception RIP: jbd2_journal_dirty_metadata+0x2ba] RIP: ffffffffc09ca54a RSP: ffffb25d8dad3b70 RFLAGS: 00010207 RAX: 0000000000000000 RBX: ffff9706eedc5248 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffff97337029ea28 RDI: ffff9706eedc5250 RBP: ffff9703c3520200 R8: 000000000f46b0b2 R9: 0000000000000000 R10: 0000000000000001 R11: 00000001000000fe R12: ffff97337029ea28 R13: 0000000000000000 R14: ffff9703de59bf60 R15: ffff9706eedc5250 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #7 [ffffb25d8dad3ba8] ocfs2_journal_dirty at ffffffffc137fb95 [ocfs2] #8 [ffffb25d8dad3be8] __ocfs2_move_extent at ffffffffc139a950 [ocfs2] #9 [ffffb25d8dad3c80] ocfs2_defrag_extent at ffffffffc139b2d2 [ocfs2] Analysis This bug has the same root cause of 'commit 7f27ec978b0e ("ocfs2: call ocfs2_journal_access_di() before ocfs2_journal_dirty() in ocfs2_write_end_nolock()")'. For this bug, jbd2_journal_restart() is called by ocfs2_split_extent() during defragmenting. How to fix For ocfs2_split_extent() can handle journal operations totally by itself. Caller doesn't need to call journal access/dirty pair, and caller only needs to call journal start/stop pair. The fix method is to remove journal access/dirty from __ocfs2_move_extent(). The discussion for this patch: https://oss.oracle.com/pipermail/ocfs2-devel/2023-February/000647.html Link: https://lkml.kernel.org/r/20230217003717.32469-1-heming.zhao@suse.com Signed-off-by: Heming Zhao Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Gang He Cc: Jun Piao Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/ocfs2/move_extents.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 758d9661ef1e..e2742546a977 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -107,14 +107,6 @@ static int __ocfs2_move_extent(handle_t *handle, */ replace_rec.e_flags = ext_flags & ~OCFS2_EXT_REFCOUNTED; - ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), - context->et.et_root_bh, - OCFS2_JOURNAL_ACCESS_WRITE); - if (ret) { - mlog_errno(ret); - goto out; - } - ret = ocfs2_split_extent(handle, &context->et, path, index, &replace_rec, context->meta_ac, &context->dealloc); @@ -123,8 +115,6 @@ static int __ocfs2_move_extent(handle_t *handle, goto out; } - ocfs2_journal_dirty(handle, context->et.et_root_bh); - context->new_phys_cpos = new_p_cpos; /* From 6bf9caa58526eef67411733f4f26e6c13cfb94a4 Mon Sep 17 00:00:00 2001 From: Heming Zhao via Ocfs2-devel Date: Mon, 20 Feb 2023 13:05:26 +0800 Subject: [PATCH 0461/1017] ocfs2: fix non-auto defrag path not working issue commit 236b9254f8d1edc273ad88b420aa85fbd84f492d upstream. This fixes three issues on move extents ioctl without auto defrag: a) In ocfs2_find_victim_alloc_group(), we have to convert bits to block first in case of global bitmap. b) In ocfs2_probe_alloc_group(), when finding enough bits in block group bitmap, we have to back off move_len to start pos as well, otherwise it may corrupt filesystem. c) In ocfs2_ioctl_move_extents(), set me_threshold both for non-auto and auto defrag paths. Otherwise it will set move_max_hop to 0 and finally cause unexpectedly ENOSPC error. Currently there are no tools triggering the above issues since defragfs.ocfs2 enables auto defrag by default. Tested with manually changing defragfs.ocfs2 to run non auto defrag path. Link: https://lkml.kernel.org/r/20230220050526.22020-1-heming.zhao@suse.com Signed-off-by: Heming Zhao Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Gang He Cc: Jun Piao Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/ocfs2/move_extents.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index e2742546a977..98e77ea957ff 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -436,7 +436,7 @@ static int ocfs2_find_victim_alloc_group(struct inode *inode, bg = (struct ocfs2_group_desc *)gd_bh->b_data; if (vict_blkno < (le64_to_cpu(bg->bg_blkno) + - le16_to_cpu(bg->bg_bits))) { + (le16_to_cpu(bg->bg_bits) << bits_per_unit))) { *ret_bh = gd_bh; *vict_bit = (vict_blkno - blkno) >> @@ -551,6 +551,7 @@ static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh, last_free_bits++; if (last_free_bits == move_len) { + i -= move_len; *goal_bit = i; *phys_cpos = base_cpos + i; break; @@ -1022,18 +1023,19 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp) context->range = ⦥ + /* + * ok, the default theshold for the defragmentation + * is 1M, since our maximum clustersize was 1M also. + * any thought? + */ + if (!range.me_threshold) + range.me_threshold = 1024 * 1024; + + if (range.me_threshold > i_size_read(inode)) + range.me_threshold = i_size_read(inode); + if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) { context->auto_defrag = 1; - /* - * ok, the default theshold for the defragmentation - * is 1M, since our maximum clustersize was 1M also. - * any thought? - */ - if (!range.me_threshold) - range.me_threshold = 1024 * 1024; - - if (range.me_threshold > i_size_read(inode)) - range.me_threshold = i_size_read(inode); if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG) context->partial = 1; From 9c792a59e078cb9675a23a9ce633c475957d1a18 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Dec 2022 14:24:03 +0100 Subject: [PATCH 0462/1017] udf: Truncate added extents on failed expansion commit 70bfb3a8d661d4fdc742afc061b88a7f3fc9f500 upstream. When a file expansion failed because we didn't have enough space for indirect extents make sure we truncate extents created so far so that we don't leave extents beyond EOF. CC: stable@vger.kernel.org Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/udf/inode.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 2132bfab67f3..bd649f1a82a0 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -525,8 +525,10 @@ static int udf_do_extend_file(struct inode *inode, } if (fake) { - udf_add_aext(inode, last_pos, &last_ext->extLocation, - last_ext->extLength, 1); + err = udf_add_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); + if (err < 0) + goto out_err; count++; } else { struct kernel_lb_addr tmploc; @@ -560,7 +562,7 @@ static int udf_do_extend_file(struct inode *inode, err = udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); if (err) - return err; + goto out_err; count++; } if (new_block_bytes) { @@ -569,7 +571,7 @@ static int udf_do_extend_file(struct inode *inode, err = udf_add_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); if (err) - return err; + goto out_err; count++; } @@ -583,6 +585,11 @@ out: return -EIO; return count; +out_err: + /* Remove extents we've created so far */ + udf_clear_extent_cache(inode); + udf_truncate_extents(inode); + return err; } /* Extend the final block of the file to final_block_len bytes */ From 965982feb333aefa9256c0fe188b5f1b958aef63 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 16 Dec 2022 12:37:51 +0100 Subject: [PATCH 0463/1017] udf: Do not bother merging very long extents commit 53cafe1d6d8ef9f93318e5bfccc0d24f27d41ced upstream. When merging very long extents we try to push as much length as possible to the first extent. However this is unnecessarily complicated and not really worth the trouble. Furthermore there was a bug in the logic resulting in corrupting extents in the file as syzbot reproducer shows. So just don't bother with the merging of extents that are too long together. CC: stable@vger.kernel.org Reported-by: syzbot+60f291a24acecb3c2bd5@syzkaller.appspotmail.com Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/udf/inode.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index bd649f1a82a0..6b6968f4c55e 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1093,23 +1093,8 @@ static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr, blocksize - 1) >> blocksize_bits)))) { if (((li->extLength & UDF_EXTENT_LENGTH_MASK) + - (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + - blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) { - lip1->extLength = (lip1->extLength - - (li->extLength & - UDF_EXTENT_LENGTH_MASK) + - UDF_EXTENT_LENGTH_MASK) & - ~(blocksize - 1); - li->extLength = (li->extLength & - UDF_EXTENT_FLAG_MASK) + - (UDF_EXTENT_LENGTH_MASK + 1) - - blocksize; - lip1->extLocation.logicalBlockNum = - li->extLocation.logicalBlockNum + - ((li->extLength & - UDF_EXTENT_LENGTH_MASK) >> - blocksize_bits); - } else { + (lip1->extLength & UDF_EXTENT_LENGTH_MASK) + + blocksize - 1) <= UDF_EXTENT_LENGTH_MASK) { li->extLength = lip1->extLength + (((li->extLength & UDF_EXTENT_LENGTH_MASK) + From eb2133900cac2d2f78befd6be41666cf1a2315d9 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 2 Jan 2023 20:14:47 +0100 Subject: [PATCH 0464/1017] udf: Do not update file length for failed writes to inline files commit 256fe4162f8b5a1625b8603ca5f7ff79725bfb47 upstream. When write to inline file fails (or happens only partly), we still updated length of inline data as if the whole write succeeded. Fix the update of length of inline data to happen only if the write succeeds. Reported-by: syzbot+0937935b993956ba28ab@syzkaller.appspotmail.com CC: stable@vger.kernel.org Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/udf/file.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/fs/udf/file.c b/fs/udf/file.c index ad8eefad27d7..e283a62701b8 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -147,26 +147,24 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out; down_write(&iinfo->i_data_sem); - if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { - loff_t end = iocb->ki_pos + iov_iter_count(from); - - if (inode->i_sb->s_blocksize < - (udf_file_entry_alloc_offset(inode) + end)) { - err = udf_expand_file_adinicb(inode); - if (err) { - inode_unlock(inode); - udf_debug("udf_expand_adinicb: err=%d\n", err); - return err; - } - } else { - iinfo->i_lenAlloc = max(end, inode->i_size); - up_write(&iinfo->i_data_sem); + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && + inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + + iocb->ki_pos + iov_iter_count(from))) { + err = udf_expand_file_adinicb(inode); + if (err) { + inode_unlock(inode); + udf_debug("udf_expand_adinicb: err=%d\n", err); + return err; } } else up_write(&iinfo->i_data_sem); retval = __generic_file_write_iter(iocb, from); out: + down_write(&iinfo->i_data_sem); + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && retval > 0) + iinfo->i_lenAlloc = inode->i_size; + up_write(&iinfo->i_data_sem); inode_unlock(inode); if (retval > 0) { From 63478c3ce24bba1fb4736102bfb1aa986e215cb0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 3 Jan 2023 09:56:56 +0100 Subject: [PATCH 0465/1017] udf: Preserve link count of system files commit fc8033a34a3ca7d23353e645e6dde5d364ac5f12 upstream. System files in UDF filesystem have link count 0. To not confuse VFS we fudge the link count to be 1 when reading such inodes however we forget to restore the link count of 0 when writing such inodes. Fix that. CC: stable@vger.kernel.org Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/udf/inode.c | 9 +++++++-- fs/udf/super.c | 1 + fs/udf/udf_i.h | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 6b6968f4c55e..8fed514be5f3 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1385,6 +1385,7 @@ reread: ret = -EIO; goto out; } + iinfo->i_hidden = hidden_inode; iinfo->i_unique = 0; iinfo->i_lenEAttr = 0; iinfo->i_lenExtents = 0; @@ -1720,8 +1721,12 @@ static int udf_update_inode(struct inode *inode, int do_sync) if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); - else - fe->fileLinkCount = cpu_to_le16(inode->i_nlink); + else { + if (iinfo->i_hidden) + fe->fileLinkCount = cpu_to_le16(0); + else + fe->fileLinkCount = cpu_to_le16(inode->i_nlink); + } fe->informationLength = cpu_to_le64(inode->i_size); diff --git a/fs/udf/super.c b/fs/udf/super.c index 3448098e5476..4af9ce34ee80 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -147,6 +147,7 @@ static struct inode *udf_alloc_inode(struct super_block *sb) ei->i_next_alloc_goal = 0; ei->i_strat4096 = 0; ei->i_streamdir = 0; + ei->i_hidden = 0; init_rwsem(&ei->i_data_sem); ei->cached_extent.lstart = -1; spin_lock_init(&ei->i_extent_cache_lock); diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index 06ff7006b822..312b7c9ef10e 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h @@ -44,7 +44,8 @@ struct udf_inode_info { unsigned i_use : 1; /* unallocSpaceEntry */ unsigned i_strat4096 : 1; unsigned i_streamdir : 1; - unsigned reserved : 25; + unsigned i_hidden : 1; /* hidden system inode */ + unsigned reserved : 24; __u8 *i_data; struct kernel_lb_addr i_locStreamdir; __u64 i_lenStreams; From a44ec34b90440ada190924f5908b97026504fdcd Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 3 Jan 2023 10:03:35 +0100 Subject: [PATCH 0466/1017] udf: Detect system inodes linked into directory hierarchy commit 85a37983ec69cc9fcd188bc37c4de15ee326355a upstream. When UDF filesystem is corrupted, hidden system inodes can be linked into directory hierarchy which is an avenue for further serious corruption of the filesystem and kernel confusion as noticed by syzbot fuzzed images. Refuse to access system inodes linked into directory hierarchy and vice versa. CC: stable@vger.kernel.org Reported-by: syzbot+38695a20b8addcbc1084@syzkaller.appspotmail.com Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/udf/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 8fed514be5f3..71acce2c0b6a 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1897,8 +1897,13 @@ struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino, if (!inode) return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) + if (!(inode->i_state & I_NEW)) { + if (UDF_I(inode)->i_hidden != hidden_inode) { + iput(inode); + return ERR_PTR(-EFSCORRUPTED); + } return inode; + } memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); err = udf_read_inode(inode, hidden_inode); From bacfce056ea694ad023ce577950abde515de0599 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 23 Jan 2023 14:18:47 +0100 Subject: [PATCH 0467/1017] udf: Fix file corruption when appending just after end of preallocated extent commit 36ec52ea038b18a53e198116ef7d7e70c87db046 upstream. When we append new block just after the end of preallocated extent, the code in inode_getblk() wrongly determined we're going to use the preallocated extent which resulted in adding block into a wrong logical offset in the file. Sequence like this manifests it: xfs_io -f -c "pwrite 0x2cacf 0xd122" -c "truncate 0x2dd6f" \ -c "pwrite 0x27fd9 0x69a9" -c "pwrite 0x32981 0x7244" The code that determined the use of preallocated extent is actually stale because udf_do_extend_file() does not create preallocation anymore so after calling that function we are sure there's no usable preallocation. Just remove the faulty condition. CC: stable@vger.kernel.org Fixes: 16d055656814 ("udf: Discard preallocation before extending file with a hole") Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/udf/inode.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 71acce2c0b6a..81876284a83c 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -804,19 +804,17 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, c = 0; offset = 0; count += ret; - /* We are not covered by a preallocated extent? */ - if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != - EXT_NOT_RECORDED_ALLOCATED) { - /* Is there any real extent? - otherwise we overwrite - * the fake one... */ - if (count) - c = !c; - laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | - inode->i_sb->s_blocksize; - memset(&laarr[c].extLocation, 0x00, - sizeof(struct kernel_lb_addr)); - count++; - } + /* + * Is there any real extent? - otherwise we overwrite the fake + * one... + */ + if (count) + c = !c; + laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | + inode->i_sb->s_blocksize; + memset(&laarr[c].extLocation, 0x00, + sizeof(struct kernel_lb_addr)); + count++; endnum = c + 1; lastblock = 1; } else { From 76a9886e1b61ce5592df5ae78a19ed30399ae189 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Mon, 19 Dec 2022 17:19:24 +0000 Subject: [PATCH 0468/1017] KVM: Destroy target device if coalesced MMIO unregistration fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b1cb1fac22abf102ffeb29dd3eeca208a3869d54 upstream. Destroy and free the target coalesced MMIO device if unregistering said device fails. As clearly noted in the code, kvm_io_bus_unregister_dev() does not destroy the target device. BUG: memory leak unreferenced object 0xffff888112a54880 (size 64): comm "syz-executor.2", pid 5258, jiffies 4297861402 (age 14.129s) hex dump (first 32 bytes): 38 c7 67 15 00 c9 ff ff 38 c7 67 15 00 c9 ff ff 8.g.....8.g..... e0 c7 e1 83 ff ff ff ff 00 30 67 15 00 c9 ff ff .........0g..... backtrace: [<0000000006995a8a>] kmalloc include/linux/slab.h:556 [inline] [<0000000006995a8a>] kzalloc include/linux/slab.h:690 [inline] [<0000000006995a8a>] kvm_vm_ioctl_register_coalesced_mmio+0x8e/0x3d0 arch/x86/kvm/../../../virt/kvm/coalesced_mmio.c:150 [<00000000022550c2>] kvm_vm_ioctl+0x47d/0x1600 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3323 [<000000008a75102f>] vfs_ioctl fs/ioctl.c:46 [inline] [<000000008a75102f>] file_ioctl fs/ioctl.c:509 [inline] [<000000008a75102f>] do_vfs_ioctl+0xbab/0x1160 fs/ioctl.c:696 [<0000000080e3f669>] ksys_ioctl+0x76/0xa0 fs/ioctl.c:713 [<0000000059ef4888>] __do_sys_ioctl fs/ioctl.c:720 [inline] [<0000000059ef4888>] __se_sys_ioctl fs/ioctl.c:718 [inline] [<0000000059ef4888>] __x64_sys_ioctl+0x6f/0xb0 fs/ioctl.c:718 [<000000006444fa05>] do_syscall_64+0x9f/0x4e0 arch/x86/entry/common.c:290 [<000000009a4ed50b>] entry_SYSCALL_64_after_hwframe+0x49/0xbe BUG: leak checking failed Fixes: 5d3c4c79384a ("KVM: Stop looking for coalesced MMIO zones if the bus is destroyed") Cc: stable@vger.kernel.org Reported-by: 柳菁峰 Reported-by: Michal Luczaj Link: https://lore.kernel.org/r/20221219171924.67989-1-seanjc@google.com Link: https://lore.kernel.org/all/20230118220003.1239032-1-mhal@rbox.co Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- virt/kvm/coalesced_mmio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index d5bebb37238c..ce6f3b916ef9 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c @@ -187,15 +187,17 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, r = kvm_io_bus_unregister_dev(kvm, zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev); + kvm_iodevice_destructor(&dev->dev); + /* * On failure, unregister destroys all devices on the * bus _except_ the target device, i.e. coalesced_zones - * has been modified. No need to restart the walk as - * there aren't any zones left. + * has been modified. Bail after destroying the target + * device, there's no need to restart the walk as there + * aren't any zones left. */ if (r) break; - kvm_iodevice_destructor(&dev->dev); } } From 018798c6fbefe03b05eff96629fb9b15a1115c3d Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Sat, 7 Jan 2023 01:10:20 +0000 Subject: [PATCH 0469/1017] KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI commit ba5838abb05334e4abfdff1490585c7f365e0424 upstream. Inject a #GP if the guest attempts to set reserved bits in the x2APIC-only Self-IPI register. Bits 7:0 hold the vector, all other bits are reserved. Reported-by: Marc Orr Cc: Ben Gardon Cc: Venkatesh Srinivas Cc: stable@vger.kernel.org Reviewed-by: Maxim Levitsky Link: https://lore.kernel.org/r/20230107011025.565472-2-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/lapic.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 260727eaa6b9..21189804524a 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2115,10 +2115,14 @@ int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) break; case APIC_SELF_IPI: - if (apic_x2apic_mode(apic)) - kvm_apic_send_ipi(apic, APIC_DEST_SELF | (val & APIC_VECTOR_MASK), 0); - else + /* + * Self-IPI exists only when x2APIC is enabled. Bits 7:0 hold + * the vector, everything else is reserved. + */ + if (!apic_x2apic_mode(apic) || (val & ~APIC_VECTOR_MASK)) ret = 1; + else + kvm_apic_send_ipi(apic, APIC_DEST_SELF | val, 0); break; default: ret = 1; From edd7f5bc6f9749a5093921e01fc120c465000f01 Mon Sep 17 00:00:00 2001 From: Nico Boehr Date: Fri, 27 Jan 2023 15:05:32 +0100 Subject: [PATCH 0470/1017] KVM: s390: disable migration mode when dirty tracking is disabled commit f2d3155e2a6bac44d16f04415a321e8707d895c6 upstream. Migration mode is a VM attribute which enables tracking of changes in storage attributes (PGSTE). It assumes dirty tracking is enabled on all memslots to keep a dirty bitmap of pages with changed storage attributes. When enabling migration mode, we currently check that dirty tracking is enabled for all memslots. However, userspace can disable dirty tracking without disabling migration mode. Since migration mode is pointless with dirty tracking disabled, disable migration mode whenever userspace disables dirty tracking on any slot. Also update the documentation to clarify that dirty tracking must be enabled when enabling migration mode, which is already enforced by the code in kvm_s390_vm_start_migration(). Also highlight in the documentation for KVM_S390_GET_CMMA_BITS that it can now fail with -EINVAL when dirty tracking is disabled while migration mode is on. Move all the error codes to a table so this stays readable. To disable migration mode, slots_lock should be held, which is taken in kvm_set_memory_region() and thus held in kvm_arch_prepare_memory_region(). Restructure the prepare code a bit so all the sanity checking is done before disabling migration mode. This ensures migration mode isn't disabled when some sanity check fails. Cc: stable@vger.kernel.org Fixes: 190df4a212a7 ("KVM: s390: CMMA tracking, ESSA emulation, migration mode") Signed-off-by: Nico Boehr Reviewed-by: Janosch Frank Reviewed-by: Claudio Imbrenda Link: https://lore.kernel.org/r/20230127140532.230651-2-nrb@linux.ibm.com Message-Id: <20230127140532.230651-2-nrb@linux.ibm.com> [frankja@linux.ibm.com: fixed commit message typo, moved api.rst error table upwards] Signed-off-by: Janosch Frank Signed-off-by: Greg Kroah-Hartman --- Documentation/virt/kvm/api.rst | 18 ++++++++++++------ Documentation/virt/kvm/devices/vm.rst | 4 ++++ arch/s390/kvm/kvm-s390.c | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 2b4b64797191..08295f488d05 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -4031,6 +4031,18 @@ not holding a previously reported uncorrected error). :Parameters: struct kvm_s390_cmma_log (in, out) :Returns: 0 on success, a negative value on error +Errors: + + ====== ============================================================= + ENOMEM not enough memory can be allocated to complete the task + ENXIO if CMMA is not enabled + EINVAL if KVM_S390_CMMA_PEEK is not set but migration mode was not enabled + EINVAL if KVM_S390_CMMA_PEEK is not set but dirty tracking has been + disabled (and thus migration mode was automatically disabled) + EFAULT if the userspace address is invalid or if no page table is + present for the addresses (e.g. when using hugepages). + ====== ============================================================= + This ioctl is used to get the values of the CMMA bits on the s390 architecture. It is meant to be used in two scenarios: @@ -4111,12 +4123,6 @@ mask is unused. values points to the userspace buffer where the result will be stored. -This ioctl can fail with -ENOMEM if not enough memory can be allocated to -complete the task, with -ENXIO if CMMA is not enabled, with -EINVAL if -KVM_S390_CMMA_PEEK is not set but migration mode was not enabled, with --EFAULT if the userspace address is invalid or if no page table is -present for the addresses (e.g. when using hugepages). - 4.108 KVM_S390_SET_CMMA_BITS ---------------------------- diff --git a/Documentation/virt/kvm/devices/vm.rst b/Documentation/virt/kvm/devices/vm.rst index 60acc39e0e93..147efec626e5 100644 --- a/Documentation/virt/kvm/devices/vm.rst +++ b/Documentation/virt/kvm/devices/vm.rst @@ -302,6 +302,10 @@ Allows userspace to start migration mode, needed for PGSTE migration. Setting this attribute when migration mode is already active will have no effects. +Dirty tracking must be enabled on all memslots, else -EINVAL is returned. When +dirty tracking is disabled on any memslot, migration mode is automatically +stopped. + :Parameters: none :Returns: -ENOMEM if there is not enough free memory to start migration mode; -EINVAL if the state of the VM is invalid (e.g. no memory defined); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 59db85fb63e1..7ffc73ba220f 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -5012,6 +5012,23 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, /* When we are protected, we should not change the memory slots */ if (kvm_s390_pv_get_handle(kvm)) return -EINVAL; + + if (!kvm->arch.migration_mode) + return 0; + + /* + * Turn off migration mode when: + * - userspace creates a new memslot with dirty logging off, + * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and + * dirty logging is turned off. + * Migration mode expects dirty page logging being enabled to store + * its dirty bitmap. + */ + if (change != KVM_MR_DELETE && + !(mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) + WARN(kvm_s390_vm_stop_migration(kvm), + "Failed to stop migration mode"); + return 0; } From 537be939a86a37793705f926b6a1882f8bb7ffee Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 30 Nov 2022 23:36:48 +0000 Subject: [PATCH 0471/1017] x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows) commit 6a3236580b0b1accc3976345e723104f74f6f8e6 upstream. Set GIF=1 prior to disabling SVM to ensure that INIT is recognized if the kernel is disabling SVM in an emergency, e.g. if the kernel is about to jump into a crash kernel or may reboot without doing a full CPU RESET. If GIF is left cleared, the new kernel (or firmware) will be unabled to awaken APs. Eat faults on STGI (due to EFER.SVME=0) as it's possible that SVM could be disabled via NMI shootdown between reading EFER.SVME and executing STGI. Link: https://lore.kernel.org/all/cbcb6f35-e5d7-c1c9-4db9-fe5cc4de579a@amd.com Cc: stable@vger.kernel.org Cc: Andrew Cooper Cc: Tom Lendacky Reviewed-by: Thomas Gleixner Link: https://lore.kernel.org/r/20221130233650.1404148-3-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/virtext.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h index fda3e7747c22..8eefa3386d8c 100644 --- a/arch/x86/include/asm/virtext.h +++ b/arch/x86/include/asm/virtext.h @@ -120,7 +120,21 @@ static inline void cpu_svm_disable(void) wrmsrl(MSR_VM_HSAVE_PA, 0); rdmsrl(MSR_EFER, efer); - wrmsrl(MSR_EFER, efer & ~EFER_SVME); + if (efer & EFER_SVME) { + /* + * Force GIF=1 prior to disabling SVM to ensure INIT and NMI + * aren't blocked, e.g. if a fatal error occurred between CLGI + * and STGI. Note, STGI may #UD if SVM is disabled from NMI + * context between reading EFER and executing STGI. In that + * case, GIF must already be set, otherwise the NMI would have + * been blocked, so just eat the fault. + */ + asm_volatile_goto("1: stgi\n\t" + _ASM_EXTABLE(1b, %l[fault]) + ::: "memory" : fault); +fault: + wrmsrl(MSR_EFER, efer & ~EFER_SVME); + } } /** Makes sure SVM is disabled, if it is supported on the CPU From 8ff2cc2f87750507048d372e8d0f4d27ef446d3b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 30 Nov 2022 23:36:47 +0000 Subject: [PATCH 0472/1017] x86/crash: Disable virt in core NMI crash handler to avoid double shootdown commit 26044aff37a5455b19a91785086914fd33053ef4 upstream. Disable virtualization in crash_nmi_callback() and rework the emergency_vmx_disable_all() path to do an NMI shootdown if and only if a shootdown has not already occurred. NMI crash shootdown fundamentally can't support multiple invocations as responding CPUs are deliberately put into halt state without unblocking NMIs. But, the emergency reboot path doesn't have any work of its own, it simply cares about disabling virtualization, i.e. so long as a shootdown occurred, emergency reboot doesn't care who initiated the shootdown, or when. If "crash_kexec_post_notifiers" is specified on the kernel command line, panic() will invoke crash_smp_send_stop() and result in a second call to nmi_shootdown_cpus() during native_machine_emergency_restart(). Invoke the callback _before_ disabling virtualization, as the current VMCS needs to be cleared before doing VMXOFF. Note, this results in a subtle change in ordering between disabling virtualization and stopping Intel PT on the responding CPUs. While VMX and Intel PT do interact, VMXOFF and writes to MSR_IA32_RTIT_CTL do not induce faults between one another, which is all that matters when panicking. Harden nmi_shootdown_cpus() against multiple invocations to try and capture any such kernel bugs via a WARN instead of hanging the system during a crash/dump, e.g. prior to the recent hardening of register_nmi_handler(), re-registering the NMI handler would trigger a double list_add() and hang the system if CONFIG_BUG_ON_DATA_CORRUPTION=y. list_add double add: new=ffffffff82220800, prev=ffffffff8221cfe8, next=ffffffff82220800. WARNING: CPU: 2 PID: 1319 at lib/list_debug.c:29 __list_add_valid+0x67/0x70 Call Trace: __register_nmi_handler+0xcf/0x130 nmi_shootdown_cpus+0x39/0x90 native_machine_emergency_restart+0x1c9/0x1d0 panic+0x237/0x29b Extract the disabling logic to a common helper to deduplicate code, and to prepare for doing the shootdown in the emergency reboot path if SVM is supported. Note, prior to commit ed72736183c4 ("x86/reboot: Force all cpus to exit VMX root if VMX is supported"), nmi_shootdown_cpus() was subtly protected against a second invocation by a cpu_vmx_enabled() check as the kdump handler would disable VMX if it ran first. Fixes: ed72736183c4 ("x86/reboot: Force all cpus to exit VMX root if VMX is supported") Cc: stable@vger.kernel.org Reported-by: Guilherme G. Piccoli Cc: Vitaly Kuznetsov Cc: Paolo Bonzini Link: https://lore.kernel.org/all/20220427224924.592546-2-gpiccoli@igalia.com Tested-by: Guilherme G. Piccoli Reviewed-by: Thomas Gleixner Link: https://lore.kernel.org/r/20221130233650.1404148-2-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/reboot.h | 2 ++ arch/x86/kernel/crash.c | 17 +-------- arch/x86/kernel/reboot.c | 65 ++++++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index 04c17be9b5fd..bc5b4d788c08 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -25,6 +25,8 @@ void __noreturn machine_real_restart(unsigned int type); #define MRR_BIOS 0 #define MRR_APM 1 +void cpu_emergency_disable_virtualization(void); + typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); void nmi_panic_self_stop(struct pt_regs *regs); void nmi_shootdown_cpus(nmi_shootdown_cb callback); diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index b1deacbeb266..a932a07d0025 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -94,15 +93,6 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs) */ cpu_crash_vmclear_loaded_vmcss(); - /* Disable VMX or SVM if needed. - * - * We need to disable virtualization on all CPUs. - * Having VMX or SVM enabled on any CPU may break rebooting - * after the kdump kernel has finished its task. - */ - cpu_emergency_vmxoff(); - cpu_emergency_svm_disable(); - /* * Disable Intel PT to stop its logging */ @@ -161,12 +151,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs) */ cpu_crash_vmclear_loaded_vmcss(); - /* Booting kdump kernel with VMX or SVM enabled won't work, - * because (among other limitations) we can't disable paging - * with the virt flags. - */ - cpu_emergency_vmxoff(); - cpu_emergency_svm_disable(); + cpu_emergency_disable_virtualization(); /* * Disable Intel PT to stop its logging diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index df3514835b35..aa615803c1bc 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -528,10 +528,7 @@ static inline void kb_wait(void) } } -static void vmxoff_nmi(int cpu, struct pt_regs *regs) -{ - cpu_emergency_vmxoff(); -} +static inline void nmi_shootdown_cpus_on_restart(void); /* Use NMIs as IPIs to tell all CPUs to disable virtualization */ static void emergency_vmx_disable_all(void) @@ -554,7 +551,7 @@ static void emergency_vmx_disable_all(void) __cpu_emergency_vmxoff(); /* Halt and exit VMX root operation on the other CPUs. */ - nmi_shootdown_cpus(vmxoff_nmi); + nmi_shootdown_cpus_on_restart(); } } @@ -795,6 +792,17 @@ void machine_crash_shutdown(struct pt_regs *regs) /* This is the CPU performing the emergency shutdown work. */ int crashing_cpu = -1; +/* + * Disable virtualization, i.e. VMX or SVM, to ensure INIT is recognized during + * reboot. VMX blocks INIT if the CPU is post-VMXON, and SVM blocks INIT if + * GIF=0, i.e. if the crash occurred between CLGI and STGI. + */ +void cpu_emergency_disable_virtualization(void) +{ + cpu_emergency_vmxoff(); + cpu_emergency_svm_disable(); +} + #if defined(CONFIG_SMP) static nmi_shootdown_cb shootdown_callback; @@ -817,7 +825,14 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs) return NMI_HANDLED; local_irq_disable(); - shootdown_callback(cpu, regs); + if (shootdown_callback) + shootdown_callback(cpu, regs); + + /* + * Prepare the CPU for reboot _after_ invoking the callback so that the + * callback can safely use virtualization instructions, e.g. VMCLEAR. + */ + cpu_emergency_disable_virtualization(); atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ @@ -828,18 +843,32 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs) return NMI_HANDLED; } -/* - * Halt all other CPUs, calling the specified function on each of them +/** + * nmi_shootdown_cpus - Stop other CPUs via NMI + * @callback: Optional callback to be invoked from the NMI handler * - * This function can be used to halt all other CPUs on crash - * or emergency reboot time. The function passed as parameter - * will be called inside a NMI handler on all CPUs. + * The NMI handler on the remote CPUs invokes @callback, if not + * NULL, first and then disables virtualization to ensure that + * INIT is recognized during reboot. + * + * nmi_shootdown_cpus() can only be invoked once. After the first + * invocation all other CPUs are stuck in crash_nmi_callback() and + * cannot respond to a second NMI. */ void nmi_shootdown_cpus(nmi_shootdown_cb callback) { unsigned long msecs; + local_irq_disable(); + /* + * Avoid certain doom if a shootdown already occurred; re-registering + * the NMI handler will cause list corruption, modifying the callback + * will do who knows what, etc... + */ + if (WARN_ON_ONCE(crash_ipi_issued)) + return; + /* Make a note of crashing cpu. Will be used in NMI callback. */ crashing_cpu = safe_smp_processor_id(); @@ -867,7 +896,17 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback) msecs--; } - /* Leave the nmi callback set */ + /* + * Leave the nmi callback set, shootdown is a one-time thing. Clearing + * the callback could result in a NULL pointer dereference if a CPU + * (finally) responds after the timeout expires. + */ +} + +static inline void nmi_shootdown_cpus_on_restart(void) +{ + if (!crash_ipi_issued) + nmi_shootdown_cpus(NULL); } /* @@ -897,6 +936,8 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback) /* No other CPUs to shoot down */ } +static inline void nmi_shootdown_cpus_on_restart(void) { } + void run_crash_ipi_callback(struct pt_regs *regs) { } From 051f991c571bb17d5b37eb7d73741ff0bd8b1b99 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 30 Nov 2022 23:36:49 +0000 Subject: [PATCH 0473/1017] x86/reboot: Disable virtualization in an emergency if SVM is supported commit d81f952aa657b76cea381384bef1fea35c5fd266 upstream. Disable SVM on all CPUs via NMI shootdown during an emergency reboot. Like VMX, SVM can block INIT, e.g. if the emergency reboot is triggered between CLGI and STGI, and thus can prevent bringing up other CPUs via INIT-SIPI-SIPI. Cc: stable@vger.kernel.org Reviewed-by: Thomas Gleixner Link: https://lore.kernel.org/r/20221130233650.1404148-4-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/reboot.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index aa615803c1bc..4d8c0e258150 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -530,27 +530,26 @@ static inline void kb_wait(void) static inline void nmi_shootdown_cpus_on_restart(void); -/* Use NMIs as IPIs to tell all CPUs to disable virtualization */ -static void emergency_vmx_disable_all(void) +static void emergency_reboot_disable_virtualization(void) { /* Just make sure we won't change CPUs while doing this */ local_irq_disable(); /* - * Disable VMX on all CPUs before rebooting, otherwise we risk hanging - * the machine, because the CPU blocks INIT when it's in VMX root. + * Disable virtualization on all CPUs before rebooting to avoid hanging + * the system, as VMX and SVM block INIT when running in the host. * * We can't take any locks and we may be on an inconsistent state, so - * use NMIs as IPIs to tell the other CPUs to exit VMX root and halt. + * use NMIs as IPIs to tell the other CPUs to disable VMX/SVM and halt. * - * Do the NMI shootdown even if VMX if off on _this_ CPU, as that - * doesn't prevent a different CPU from being in VMX root operation. + * Do the NMI shootdown even if virtualization is off on _this_ CPU, as + * other CPUs may have virtualization enabled. */ - if (cpu_has_vmx()) { - /* Safely force _this_ CPU out of VMX root operation. */ - __cpu_emergency_vmxoff(); + if (cpu_has_vmx() || cpu_has_svm(NULL)) { + /* Safely force _this_ CPU out of VMX/SVM operation. */ + cpu_emergency_disable_virtualization(); - /* Halt and exit VMX root operation on the other CPUs. */ + /* Disable VMX/SVM and halt on other CPUs. */ nmi_shootdown_cpus_on_restart(); } } @@ -587,7 +586,7 @@ static void native_machine_emergency_restart(void) unsigned short mode; if (reboot_emergency) - emergency_vmx_disable_all(); + emergency_reboot_disable_virtualization(); tboot_shutdown(TB_SHUTDOWN_REBOOT); From f75ee95196cecd0375c28f56d1bc713368474c63 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 30 Nov 2022 23:36:50 +0000 Subject: [PATCH 0474/1017] x86/reboot: Disable SVM, not just VMX, when stopping CPUs commit a2b07fa7b93321c059af0c6d492cc9a4f1e390aa upstream. Disable SVM and more importantly force GIF=1 when halting a CPU or rebooting the machine. Similar to VMX, SVM allows software to block INITs via CLGI, and thus can be problematic for a crash/reboot. The window for failure is smaller with SVM as INIT is only blocked while GIF=0, i.e. between CLGI and STGI, but the window does exist. Fixes: fba4f472b33a ("x86/reboot: Turn off KVM when halting a CPU") Cc: stable@vger.kernel.org Reviewed-by: Thomas Gleixner Link: https://lore.kernel.org/r/20221130233650.1404148-5-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/smp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index eff4ce3b10da..95758ae120ba 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include /* * Some notes on x86 processor bugs affecting SMP operation: @@ -122,7 +122,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs) if (raw_smp_processor_id() == atomic_read(&stopping_cpu)) return NMI_HANDLED; - cpu_emergency_vmxoff(); + cpu_emergency_disable_virtualization(); stop_this_cpu(NULL); return NMI_HANDLED; @@ -134,7 +134,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs) DEFINE_IDTENTRY_SYSVEC(sysvec_reboot) { ack_APIC_irq(); - cpu_emergency_vmxoff(); + cpu_emergency_disable_virtualization(); stop_this_cpu(NULL); } From c16e4610d5e5e2698f25280121173292c1c3f805 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Tue, 21 Feb 2023 08:49:16 +0900 Subject: [PATCH 0475/1017] x86/kprobes: Fix __recover_optprobed_insn check optimizing logic commit 868a6fc0ca2407622d2833adefe1c4d284766c4c upstream. Since the following commit: commit f66c0447cca1 ("kprobes: Set unoptimized flag after unoptimizing code") modified the update timing of the KPROBE_FLAG_OPTIMIZED, a optimized_kprobe may be in the optimizing or unoptimizing state when op.kp->flags has KPROBE_FLAG_OPTIMIZED and op->list is not empty. The __recover_optprobed_insn check logic is incorrect, a kprobe in the unoptimizing state may be incorrectly determined as unoptimizing. As a result, incorrect instructions are copied. The optprobe_queued_unopt function needs to be exported for invoking in arch directory. Link: https://lore.kernel.org/all/20230216034247.32348-2-yangjihong1@huawei.com/ Fixes: f66c0447cca1 ("kprobes: Set unoptimized flag after unoptimizing code") Cc: stable@vger.kernel.org Signed-off-by: Yang Jihong Acked-by: Masami Hiramatsu (Google) Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/kprobes/opt.c | 4 ++-- include/linux/kprobes.h | 1 + kernel/kprobes.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 3d6201492006..e81adc1070f3 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -46,8 +46,8 @@ unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr) /* This function only handles jump-optimized kprobe */ if (kp && kprobe_optimized(kp)) { op = container_of(kp, struct optimized_kprobe, kp); - /* If op->list is not empty, op is under optimizing */ - if (list_empty(&op->list)) + /* If op is optimized or under unoptimizing */ + if (list_empty(&op->list) || optprobe_queued_unopt(op)) goto found; } } diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 4dbebd319b6f..0ed50f1a9578 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -342,6 +342,7 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table, size_t *length, loff_t *ppos); #endif extern void wait_for_kprobe_optimizer(void); +bool optprobe_queued_unopt(struct optimized_kprobe *op); #else static inline void wait_for_kprobe_optimizer(void) { } #endif /* CONFIG_OPTPROBES */ diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 75150e755518..80a57d45f5f7 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -652,7 +652,7 @@ void wait_for_kprobe_optimizer(void) mutex_unlock(&kprobe_mutex); } -static bool optprobe_queued_unopt(struct optimized_kprobe *op) +bool optprobe_queued_unopt(struct optimized_kprobe *op) { struct optimized_kprobe *_op; From 5255fd8dfbd2944aecf69c338aa9e9f2a3e38f00 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Tue, 21 Feb 2023 08:49:16 +0900 Subject: [PATCH 0476/1017] x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe range commit f1c97a1b4ef709e3f066f82e3ba3108c3b133ae6 upstream. When arch_prepare_optimized_kprobe calculating jump destination address, it copies original instructions from jmp-optimized kprobe (see __recover_optprobed_insn), and calculated based on length of original instruction. arch_check_optimized_kprobe does not check KPROBE_FLAG_OPTIMATED when checking whether jmp-optimized kprobe exists. As a result, setup_detour_execution may jump to a range that has been overwritten by jump destination address, resulting in an inval opcode error. For example, assume that register two kprobes whose addresses are and in "func" function. The original code of "func" function is as follows: 0xffffffff816cb5e9 <+9>: push %r12 0xffffffff816cb5eb <+11>: xor %r12d,%r12d 0xffffffff816cb5ee <+14>: test %rdi,%rdi 0xffffffff816cb5f1 <+17>: setne %r12b 0xffffffff816cb5f5 <+21>: push %rbp 1.Register the kprobe for , assume that is kp1, corresponding optimized_kprobe is op1. After the optimization, "func" code changes to: 0xffffffff816cc079 <+9>: push %r12 0xffffffff816cc07b <+11>: jmp 0xffffffffa0210000 0xffffffff816cc080 <+16>: incl 0xf(%rcx) 0xffffffff816cc083 <+19>: xchg %eax,%ebp 0xffffffff816cc084 <+20>: (bad) 0xffffffff816cc085 <+21>: push %rbp Now op1->flags == KPROBE_FLAG_OPTIMATED; 2. Register the kprobe for , assume that is kp2, corresponding optimized_kprobe is op2. register_kprobe(kp2) register_aggr_kprobe alloc_aggr_kprobe __prepare_optimized_kprobe arch_prepare_optimized_kprobe __recover_optprobed_insn // copy original bytes from kp1->optinsn.copied_insn, // jump address = 3. disable kp1: disable_kprobe(kp1) __disable_kprobe ... if (p == orig_p || aggr_kprobe_disabled(orig_p)) { ret = disarm_kprobe(orig_p, true) // add op1 in unoptimizing_list, not unoptimized orig_p->flags |= KPROBE_FLAG_DISABLED; // op1->flags == KPROBE_FLAG_OPTIMATED | KPROBE_FLAG_DISABLED ... 4. unregister kp2 __unregister_kprobe_top ... if (!kprobe_disabled(ap) && !kprobes_all_disarmed) { optimize_kprobe(op) ... if (arch_check_optimized_kprobe(op) < 0) // because op1 has KPROBE_FLAG_DISABLED, here not return return; p->kp.flags |= KPROBE_FLAG_OPTIMIZED; // now op2 has KPROBE_FLAG_OPTIMIZED } "func" code now is: 0xffffffff816cc079 <+9>: int3 0xffffffff816cc07a <+10>: push %rsp 0xffffffff816cc07b <+11>: jmp 0xffffffffa0210000 0xffffffff816cc080 <+16>: incl 0xf(%rcx) 0xffffffff816cc083 <+19>: xchg %eax,%ebp 0xffffffff816cc084 <+20>: (bad) 0xffffffff816cc085 <+21>: push %rbp 5. if call "func", int3 handler call setup_detour_execution: if (p->flags & KPROBE_FLAG_OPTIMIZED) { ... regs->ip = (unsigned long)op->optinsn.insn + TMPL_END_IDX; ... } The code for the destination address is 0xffffffffa021072c: push %r12 0xffffffffa021072e: xor %r12d,%r12d 0xffffffffa0210731: jmp 0xffffffff816cb5ee However, is not a valid start instruction address. As a result, an error occurs. Link: https://lore.kernel.org/all/20230216034247.32348-3-yangjihong1@huawei.com/ Fixes: f66c0447cca1 ("kprobes: Set unoptimized flag after unoptimizing code") Signed-off-by: Yang Jihong Cc: stable@vger.kernel.org Acked-by: Masami Hiramatsu (Google) Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/kprobes/opt.c | 2 +- include/linux/kprobes.h | 1 + kernel/kprobes.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index e81adc1070f3..e37e5e82481a 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -346,7 +346,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op) for (i = 1; i < op->optinsn.size; i++) { p = get_kprobe(op->kp.addr + i); - if (p && !kprobe_disabled(p)) + if (p && !kprobe_disarmed(p)) return -EEXIST; } diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 0ed50f1a9578..18b7c40ffb37 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -343,6 +343,7 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table, #endif extern void wait_for_kprobe_optimizer(void); bool optprobe_queued_unopt(struct optimized_kprobe *op); +bool kprobe_disarmed(struct kprobe *p); #else static inline void wait_for_kprobe_optimizer(void) { } #endif /* CONFIG_OPTPROBES */ diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 80a57d45f5f7..86d71c49b495 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -447,8 +447,8 @@ static inline int kprobe_optready(struct kprobe *p) return 0; } -/* Return true(!0) if the kprobe is disarmed. Note: p must be on hash list */ -static inline int kprobe_disarmed(struct kprobe *p) +/* Return true if the kprobe is disarmed. Note: p must be on hash list */ +bool kprobe_disarmed(struct kprobe *p) { struct optimized_kprobe *op; From 0a89768b85f010107b8051285379dc88c002715b Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Tue, 17 Jan 2023 23:59:24 +0100 Subject: [PATCH 0477/1017] x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter commit 2355370cd941cbb20882cc3f34460f9f2b8f9a18 upstream. It is always the BSP. No functional changes. Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230130161709.11615-2-bp@alien8.de Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/microcode/amd.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 234a96f25248..9d0889386a33 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -548,8 +548,7 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax) apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, false); } -static enum ucode_state -load_microcode_amd(bool save, u8 family, const u8 *data, size_t size); +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) { @@ -567,7 +566,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) if (!desc.mc) return -EINVAL; - ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size); + ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); if (ret > UCODE_UPDATED) return -EINVAL; @@ -845,8 +844,7 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, return UCODE_OK; } -static enum ucode_state -load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) { struct ucode_patch *p; enum ucode_state ret; @@ -870,10 +868,6 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) ret = UCODE_NEW; } - /* save BSP's matching patch for early load */ - if (!save) - return ret; - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); @@ -901,12 +895,11 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, { char fw_name[36] = "amd-ucode/microcode_amd.bin"; struct cpuinfo_x86 *c = &cpu_data(cpu); - bool bsp = c->cpu_index == boot_cpu_data.cpu_index; enum ucode_state ret = UCODE_NFOUND; const struct firmware *fw; /* reload ucode container only on the boot cpu */ - if (!refresh_fw || !bsp) + if (!refresh_fw) return UCODE_OK; if (c->x86 >= 0x15) @@ -921,7 +914,7 @@ static enum ucode_state request_microcode_amd(int cpu, struct device *device, if (!verify_container(fw->data, fw->size, false)) goto fw_release; - ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size); + ret = load_microcode_amd(c->x86, fw->data, fw->size); fw_release: release_firmware(fw); From 87cf9bc78c433c005d769111c007adb58d7697a6 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Thu, 26 Jan 2023 00:08:03 +0100 Subject: [PATCH 0478/1017] x86/microcode/AMD: Add a @cpu parameter to the reloading functions commit a5ad92134bd153a9ccdcddf09a95b088f36c3cce upstream. Will be used in a subsequent change. Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230130161709.11615-3-bp@alien8.de Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/microcode.h | 4 ++-- arch/x86/include/asm/microcode_amd.h | 4 ++-- arch/x86/kernel/cpu/microcode/amd.c | 2 +- arch/x86/kernel/cpu/microcode/core.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index f73327397b89..509cc0262fdc 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -131,7 +131,7 @@ static inline unsigned int x86_cpuid_family(void) int __init microcode_init(void); extern void __init load_ucode_bsp(void); extern void load_ucode_ap(void); -void reload_early_microcode(void); +void reload_early_microcode(unsigned int cpu); extern bool get_builtin_firmware(struct cpio_data *cd, const char *name); extern bool initrd_gone; void microcode_bsp_resume(void); @@ -139,7 +139,7 @@ void microcode_bsp_resume(void); static inline int __init microcode_init(void) { return 0; }; static inline void __init load_ucode_bsp(void) { } static inline void load_ucode_ap(void) { } -static inline void reload_early_microcode(void) { } +static inline void reload_early_microcode(unsigned int cpu) { } static inline void microcode_bsp_resume(void) { } static inline bool get_builtin_firmware(struct cpio_data *cd, const char *name) { return false; } diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index 7063b5a43220..a645b25ee442 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h @@ -47,12 +47,12 @@ struct microcode_amd { extern void __init load_ucode_amd_bsp(unsigned int family); extern void load_ucode_amd_ap(unsigned int family); extern int __init save_microcode_in_initrd_amd(unsigned int family); -void reload_ucode_amd(void); +void reload_ucode_amd(unsigned int cpu); #else static inline void __init load_ucode_amd_bsp(unsigned int family) {} static inline void load_ucode_amd_ap(unsigned int family) {} static inline int __init save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; } -static inline void reload_ucode_amd(void) {} +static inline void reload_ucode_amd(unsigned int cpu) {} #endif #endif /* _ASM_X86_MICROCODE_AMD_H */ diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 9d0889386a33..95b398df30bd 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -573,7 +573,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) return 0; } -void reload_ucode_amd(void) +void reload_ucode_amd(unsigned int cpu) { struct microcode_amd *mc; u32 rev, dummy __always_unused; diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 36583bc4b88c..24254d141178 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -315,7 +315,7 @@ struct cpio_data find_microcode_in_initrd(const char *path, bool use_pa) #endif } -void reload_early_microcode(void) +void reload_early_microcode(unsigned int cpu) { int vendor, family; @@ -329,7 +329,7 @@ void reload_early_microcode(void) break; case X86_VENDOR_AMD: if (family >= 0x10) - reload_ucode_amd(); + reload_ucode_amd(cpu); break; default: break; @@ -707,7 +707,7 @@ void microcode_bsp_resume(void) if (uci->valid && uci->mc) microcode_ops->apply_microcode(cpu); else if (!uci->mc) - reload_early_microcode(); + reload_early_microcode(cpu); } static struct syscore_ops mc_syscore_ops = { From 44a44b57e88f311c1415be1f567c50050913c149 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Thu, 26 Jan 2023 16:26:17 +0100 Subject: [PATCH 0479/1017] x86/microcode/AMD: Fix mixed steppings support commit 7ff6edf4fef38ab404ee7861f257e28eaaeed35f upstream. The AMD side of the loader has always claimed to support mixed steppings. But somewhere along the way, it broke that by assuming that the cached patch blob is a single one instead of it being one per *node*. So turn it into a per-node one so that each node can stash the blob relevant for it. [ NB: Fixes tag is not really the exactly correct one but it is good enough. ] Fixes: fe055896c040 ("x86/microcode: Merge the early microcode loader") Signed-off-by: Borislav Petkov (AMD) Cc: # 2355370cd941 ("x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter") Cc: # a5ad92134bd1 ("x86/microcode/AMD: Add a @cpu parameter to the reloading functions") Link: https://lore.kernel.org/r/20230130161709.11615-4-bp@alien8.de Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/microcode/amd.c | 34 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 95b398df30bd..d3bce6d380ed 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -55,7 +55,9 @@ struct cont_desc { }; static u32 ucode_new_rev; -static u8 amd_ucode_patch[PATCH_MAX_SIZE]; + +/* One blob per node. */ +static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE]; /* * Microcode patch container file is prepended to the initrd in cpio @@ -429,7 +431,7 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_p patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch); #else new_rev = &ucode_new_rev; - patch = &amd_ucode_patch; + patch = &amd_ucode_patch[0]; #endif desc.cpuid_1_eax = cpuid_1_eax; @@ -575,10 +577,10 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) void reload_ucode_amd(unsigned int cpu) { - struct microcode_amd *mc; u32 rev, dummy __always_unused; + struct microcode_amd *mc; - mc = (struct microcode_amd *)amd_ucode_patch; + mc = (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)]; rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); @@ -846,6 +848,8 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) { + struct cpuinfo_x86 *c; + unsigned int nid, cpu; struct ucode_patch *p; enum ucode_state ret; @@ -858,18 +862,22 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz return ret; } - p = find_patch(0); - if (!p) { - return ret; - } else { - if (boot_cpu_data.microcode >= p->patch_id) - return ret; + for_each_node(nid) { + cpu = cpumask_first(cpumask_of_node(nid)); + c = &cpu_data(cpu); + + p = find_patch(cpu); + if (!p) + continue; + + if (c->microcode >= p->patch_id) + continue; ret = UCODE_NEW; - } - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); - memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); + memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE); + memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); + } return ret; } From abfed855f05863d292de2d0ebab4656791bab9c8 Mon Sep 17 00:00:00 2001 From: KP Singh Date: Mon, 27 Feb 2023 07:05:40 +0100 Subject: [PATCH 0480/1017] x86/speculation: Allow enabling STIBP with legacy IBRS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6921ed9049bc7457f66c1596c5b78aec0dae4a9d upstream. When plain IBRS is enabled (not enhanced IBRS), the logic in spectre_v2_user_select_mitigation() determines that STIBP is not needed. The IBRS bit implicitly protects against cross-thread branch target injection. However, with legacy IBRS, the IBRS bit is cleared on returning to userspace for performance reasons which leaves userspace threads vulnerable to cross-thread branch target injection against which STIBP protects. Exclude IBRS from the spectre_v2_in_ibrs_mode() check to allow for enabling STIBP (through seccomp/prctl() by default or always-on, if selected by spectre_v2_user kernel cmdline parameter). [ bp: Massage. ] Fixes: 7c693f54c873 ("x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS") Reported-by: José Oliveira Reported-by: Rodrigo Branco Signed-off-by: KP Singh Signed-off-by: Borislav Petkov (AMD) Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230220120127.1975241-1-kpsingh@kernel.org Link: https://lore.kernel.org/r/20230221184908.2349578-1-kpsingh@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/bugs.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c5034986ea44..c81b8b029b68 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1066,14 +1066,18 @@ spectre_v2_parse_user_cmdline(void) return SPECTRE_V2_USER_CMD_AUTO; } -static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) +static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) { - return mode == SPECTRE_V2_IBRS || - mode == SPECTRE_V2_EIBRS || + return mode == SPECTRE_V2_EIBRS || mode == SPECTRE_V2_EIBRS_RETPOLINE || mode == SPECTRE_V2_EIBRS_LFENCE; } +static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) +{ + return spectre_v2_in_eibrs_mode(mode) || mode == SPECTRE_V2_IBRS; +} + static void __init spectre_v2_user_select_mitigation(void) { @@ -1136,12 +1140,19 @@ spectre_v2_user_select_mitigation(void) } /* - * If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible, - * STIBP is not required. + * If no STIBP, enhanced IBRS is enabled, or SMT impossible, STIBP + * is not required. + * + * Enhanced IBRS also protects against cross-thread branch target + * injection in user-mode as the IBRS bit remains always set which + * implicitly enables cross-thread protections. However, in legacy IBRS + * mode, the IBRS bit is set only on kernel entry and cleared on return + * to userspace. This disables the implicit cross-thread protection, + * so allow for STIBP to be selected in that case. */ if (!boot_cpu_has(X86_FEATURE_STIBP) || !smt_possible || - spectre_v2_in_ibrs_mode(spectre_v2_enabled)) + spectre_v2_in_eibrs_mode(spectre_v2_enabled)) return; /* @@ -2235,7 +2246,7 @@ static ssize_t mmio_stale_data_show_state(char *buf) static char *stibp_state(void) { - if (spectre_v2_in_ibrs_mode(spectre_v2_enabled)) + if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) return ""; switch (spectre_v2_user_stibp) { From 3326ef84cdbe13a3872a6ac9e428cd60ed243f70 Mon Sep 17 00:00:00 2001 From: KP Singh Date: Mon, 27 Feb 2023 07:05:41 +0100 Subject: [PATCH 0481/1017] Documentation/hw-vuln: Document the interaction between IBRS and STIBP commit e02b50ca442e88122e1302d4dbc1b71a4808c13f upstream. Explain why STIBP is needed with legacy IBRS as currently implemented (KERNEL_IBRS) and why STIBP is not needed when enhanced IBRS is enabled. Fixes: 7c693f54c873 ("x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS") Signed-off-by: KP Singh Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230227060541.1939092-2-kpsingh@kernel.org Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/hw-vuln/spectre.rst | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst index 7e061ed449aa..0fba3758d0da 100644 --- a/Documentation/admin-guide/hw-vuln/spectre.rst +++ b/Documentation/admin-guide/hw-vuln/spectre.rst @@ -479,8 +479,16 @@ Spectre variant 2 On Intel Skylake-era systems the mitigation covers most, but not all, cases. See :ref:`[3] ` for more details. - On CPUs with hardware mitigation for Spectre variant 2 (e.g. Enhanced - IBRS on x86), retpoline is automatically disabled at run time. + On CPUs with hardware mitigation for Spectre variant 2 (e.g. IBRS + or enhanced IBRS on x86), retpoline is automatically disabled at run time. + + Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at + boot, by setting the IBRS bit, and they're automatically protected against + Spectre v2 variant attacks, including cross-thread branch target injections + on SMT systems (STIBP). In other words, eIBRS enables STIBP too. + + Legacy IBRS systems clear the IBRS bit on exit to userspace and + therefore explicitly enable STIBP for that The retpoline mitigation is turned on by default on vulnerable CPUs. It can be forced on or off by the administrator @@ -504,9 +512,12 @@ Spectre variant 2 For Spectre variant 2 mitigation, individual user programs can be compiled with return trampolines for indirect branches. This protects them from consuming poisoned entries in the branch - target buffer left by malicious software. Alternatively, the - programs can disable their indirect branch speculation via prctl() - (See :ref:`Documentation/userspace-api/spec_ctrl.rst `). + target buffer left by malicious software. + + On legacy IBRS systems, at return to userspace, implicit STIBP is disabled + because the kernel clears the IBRS bit. In this case, the userspace programs + can disable indirect branch speculation via prctl() (See + :ref:`Documentation/userspace-api/spec_ctrl.rst `). On x86, this will turn on STIBP to guard against attacks from the sibling thread when the user program is running, and use IBPB to flush the branch target buffer when switching to/from the program. From c1aa96927b242acfd25457b73cf9d175b58ede7a Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 16 Feb 2023 07:57:32 -0700 Subject: [PATCH 0482/1017] brd: return 0/-error from brd_insert_page() commit db0ccc44a20b4bb3039c0f6885a1f9c3323c7673 upstream. It currently returns a page, but callers just check for NULL/page to gauge success. Clean this up and return the appropriate error directly instead. Cc: stable@vger.kernel.org # 5.10+ Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/brd.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index cc49a921339f..11078e166368 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -80,11 +80,9 @@ static struct page *brd_lookup_page(struct brd_device *brd, sector_t sector) } /* - * Look up and return a brd's page for a given sector. - * If one does not exist, allocate an empty page, and insert that. Then - * return it. + * Insert a new page for a given sector, if one does not already exist. */ -static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) +static int brd_insert_page(struct brd_device *brd, sector_t sector) { pgoff_t idx; struct page *page; @@ -92,7 +90,7 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) page = brd_lookup_page(brd, sector); if (page) - return page; + return 0; /* * Must use NOIO because we don't want to recurse back into the @@ -101,11 +99,11 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM; page = alloc_page(gfp_flags); if (!page) - return NULL; + return -ENOMEM; if (radix_tree_preload(GFP_NOIO)) { __free_page(page); - return NULL; + return -ENOMEM; } spin_lock(&brd->brd_lock); @@ -120,8 +118,7 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) spin_unlock(&brd->brd_lock); radix_tree_preload_end(); - - return page; + return 0; } /* @@ -174,16 +171,17 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n) { unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; size_t copy; + int ret; copy = min_t(size_t, n, PAGE_SIZE - offset); - if (!brd_insert_page(brd, sector)) - return -ENOSPC; + ret = brd_insert_page(brd, sector); + if (ret) + return ret; if (copy < n) { sector += copy >> SECTOR_SHIFT; - if (!brd_insert_page(brd, sector)) - return -ENOSPC; + ret = brd_insert_page(brd, sector); } - return 0; + return ret; } /* From 8c64acd24aedf723e5f289d35220467d7cfdc637 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Tue, 31 Jan 2023 18:42:43 +0100 Subject: [PATCH 0483/1017] ima: Align ima_file_mmap() parameters with mmap_file LSM hook commit 4971c268b85e1c7a734a61622fc0813c86e2362e upstream. Commit 98de59bfe4b2f ("take calculation of final prot in security_mmap_file() into a helper") moved the code to update prot, to be the actual protections applied to the kernel, to a new helper called mmap_prot(). However, while without the helper ima_file_mmap() was getting the updated prot, with the helper ima_file_mmap() gets the original prot, which contains the protections requested by the application. A possible consequence of this change is that, if an application calls mmap() with only PROT_READ, and the kernel applies PROT_EXEC in addition, that application would have access to executable memory without having this event recorded in the IMA measurement list. This situation would occur for example if the application, before mmap(), calls the personality() system call with READ_IMPLIES_EXEC as the first argument. Align ima_file_mmap() parameters with those of the mmap_file LSM hook, so that IMA can receive both the requested prot and the final prot. Since the requested protections are stored in a new variable, and the final protections are stored in the existing variable, this effectively restores the original behavior of the MMAP_CHECK hook. Cc: stable@vger.kernel.org Fixes: 98de59bfe4b2 ("take calculation of final prot in security_mmap_file() into a helper") Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Signed-off-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- include/linux/ima.h | 6 ++++-- security/integrity/ima/ima_main.c | 7 +++++-- security/security.c | 7 ++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 8fa7bcfb2da2..cd8483fa703e 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -18,7 +18,8 @@ extern int ima_bprm_check(struct linux_binprm *bprm); extern int ima_file_check(struct file *file, int mask); extern void ima_post_create_tmpfile(struct inode *inode); extern void ima_file_free(struct file *file); -extern int ima_file_mmap(struct file *file, unsigned long prot); +extern int ima_file_mmap(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags); extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot); extern int ima_load_data(enum kernel_load_data_id id, bool contents); extern int ima_post_load_data(char *buf, loff_t size, @@ -70,7 +71,8 @@ static inline void ima_file_free(struct file *file) return; } -static inline int ima_file_mmap(struct file *file, unsigned long prot) +static inline int ima_file_mmap(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) { return 0; } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 600b97677085..dd4b28b11ebe 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -378,7 +378,9 @@ out: /** * ima_file_mmap - based on policy, collect/store measurement. * @file: pointer to the file to be measured (May be NULL) - * @prot: contains the protection that will be applied by the kernel. + * @reqprot: protection requested by the application + * @prot: protection that will be applied by the kernel + * @flags: operational flags * * Measure files being mmapped executable based on the ima_must_measure() * policy decision. @@ -386,7 +388,8 @@ out: * On success return 0. On integrity appraisal error, assuming the file * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. */ -int ima_file_mmap(struct file *file, unsigned long prot) +int ima_file_mmap(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) { u32 secid; diff --git a/security/security.c b/security/security.c index 8ea826ea6167..f9157d5023c6 100644 --- a/security/security.c +++ b/security/security.c @@ -1534,12 +1534,13 @@ static inline unsigned long mmap_prot(struct file *file, unsigned long prot) int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) { + unsigned long prot_adj = mmap_prot(file, prot); int ret; - ret = call_int_hook(mmap_file, 0, file, prot, - mmap_prot(file, prot), flags); + + ret = call_int_hook(mmap_file, 0, file, prot, prot_adj, flags); if (ret) return ret; - return ima_file_mmap(file, prot); + return ima_file_mmap(file, prot, prot_adj, flags); } int security_mmap_addr(unsigned long addr) From 6b24bd85ae5c86e54f05874f2edd35ffd2496522 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Feb 2023 11:42:43 +0100 Subject: [PATCH 0484/1017] irqdomain: Fix association race commit b06730a571a9ff1ba5bd6b20bf9e50e5a12f1ec6 upstream. The sanity check for an already mapped virq is done outside of the irq_domain_mutex-protected section which means that an (unlikely) racing association may not be detected. Fix this by factoring out the association implementation, which will also be used in a follow-on change to fix a shared-interrupt mapping race. Fixes: ddaf144c61da ("irqdomain: Refactor irq_domain_associate_many()") Cc: stable@vger.kernel.org # 3.11 Tested-by: Hsin-Yi Wang Tested-by: Mark-PK Tsai Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-2-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/irq/irqdomain.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index c6b419db68ef..3cd67b062501 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -516,8 +516,8 @@ void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) irq_domain_clear_mapping(domain, hwirq); } -int irq_domain_associate(struct irq_domain *domain, unsigned int virq, - irq_hw_number_t hwirq) +static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) { struct irq_data *irq_data = irq_get_irq_data(virq); int ret; @@ -530,7 +530,6 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq, if (WARN(irq_data->domain, "error: virq%i is already associated", virq)) return -EINVAL; - mutex_lock(&irq_domain_mutex); irq_data->hwirq = hwirq; irq_data->domain = domain; if (domain->ops->map) { @@ -547,7 +546,6 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq, } irq_data->domain = NULL; irq_data->hwirq = 0; - mutex_unlock(&irq_domain_mutex); return ret; } @@ -558,12 +556,23 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq, domain->mapcount++; irq_domain_set_mapping(domain, hwirq, irq_data); - mutex_unlock(&irq_domain_mutex); irq_clear_status_flags(virq, IRQ_NOREQUEST); return 0; } + +int irq_domain_associate(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) +{ + int ret; + + mutex_lock(&irq_domain_mutex); + ret = irq_domain_associate_locked(domain, virq, hwirq); + mutex_unlock(&irq_domain_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(irq_domain_associate); void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base, From e0538aa7e099d494cf523958a84bfbedc5b56d02 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Feb 2023 11:42:44 +0100 Subject: [PATCH 0485/1017] irqdomain: Fix disassociation race commit 3f883c38f5628f46b30bccf090faec054088e262 upstream. The global irq_domain_mutex is held when mapping interrupts from non-hierarchical domains but currently not when disposing them. This specifically means that updates of the domain mapcount is racy (currently only used for statistics in debugfs). Make sure to hold the global irq_domain_mutex also when disposing mappings from non-hierarchical domains. Fixes: 9dc6be3d4193 ("genirq/irqdomain: Add map counter") Cc: stable@vger.kernel.org # 4.13 Tested-by: Hsin-Yi Wang Tested-by: Mark-PK Tsai Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-3-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/irq/irqdomain.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 3cd67b062501..e9b3d2028a58 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -495,6 +495,9 @@ void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) return; hwirq = irq_data->hwirq; + + mutex_lock(&irq_domain_mutex); + irq_set_status_flags(irq, IRQ_NOREQUEST); /* remove chip and handler */ @@ -514,6 +517,8 @@ void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq) /* Clear reverse map for this hwirq */ irq_domain_clear_mapping(domain, hwirq); + + mutex_unlock(&irq_domain_mutex); } static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq, From 306c8b49b5666856dfe74d032e2dc5ac17d3784e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Feb 2023 11:42:45 +0100 Subject: [PATCH 0486/1017] irqdomain: Drop bogus fwspec-mapping error handling commit e3b7ab025e931accdc2c12acf9b75c6197f1c062 upstream. In case a newly allocated IRQ ever ends up not having any associated struct irq_data it would not even be possible to dispose the mapping. Replace the bogus disposal with a WARN_ON(). This will also be used to fix a shared-interrupt mapping race, hence the CC-stable tag. Fixes: 1e2a7d78499e ("irqdomain: Don't set type when mapping an IRQ") Cc: stable@vger.kernel.org # 4.8 Tested-by: Hsin-Yi Wang Tested-by: Mark-PK Tsai Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-4-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/irq/irqdomain.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index e9b3d2028a58..1720998933f8 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -837,13 +837,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) } irq_data = irq_get_irq_data(virq); - if (!irq_data) { - if (irq_domain_is_hierarchy(domain)) - irq_domain_free_irqs(virq, 1); - else - irq_dispose_mapping(virq); + if (WARN_ON(!irq_data)) return 0; - } /* Store trigger type */ irqd_set_trigger_type(irq_data, type); From 3f32f8492e10ec740552c051a1b0a331490f356b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 6 Mar 2023 13:15:06 -0700 Subject: [PATCH 0487/1017] io_uring: handle TIF_NOTIFY_RESUME when checking for task_work commit b5d3ae202fbfe055aa2a8ae8524531ee1dcab717 upstream. If TIF_NOTIFY_RESUME is set, then we need to call resume_user_mode_work() for PF_IO_WORKER threads. They never return to usermode, hence never get a chance to process any items that are marked by this flag. Most notably this includes the final put of files, but also any throttling markers set by block cgroups. Cc: stable@vger.kernel.org # 5.10+ Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index cf6f8aeb450d..67e820798d25 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2460,6 +2460,13 @@ static inline unsigned int io_put_rw_kbuf(struct io_kiocb *req) static inline bool io_run_task_work(void) { + /* + * PF_IO_WORKER never returns to userspace, so check here if we have + * notify work that needs processing. + */ + if (current->flags & PF_IO_WORKER && + test_thread_flag(TIF_NOTIFY_RESUME)) + tracehook_notify_resume(NULL); if (test_thread_flag(TIF_NOTIFY_SIGNAL) || current->task_works) { __set_current_state(TASK_RUNNING); tracehook_notify_signal(); From 3d1f9533a39d16f18ed7e630ecb07c0c2181b2cd Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 6 Mar 2023 13:16:38 -0700 Subject: [PATCH 0488/1017] io_uring: mark task TASK_RUNNING before handling resume/task work commit 2f2bb1ffc9983e227424d0787289da5483b0c74f upstream. Just like for task_work, set the task mode to TASK_RUNNING before doing potential resume work. We're not holding any locks at this point, but we may have already set the task state to TASK_INTERRUPTIBLE in preparation for going to sleep waiting for events. Ensure that we set it back to TASK_RUNNING if we have work to process, to avoid warnings on calling blocking operations with !TASK_RUNNING. Fixes: b5d3ae202fbf ("io_uring: handle TIF_NOTIFY_RESUME when checking for task_work") Reported-by: kernel test robot Link: https://lore.kernel.org/oe-lkp/202302062208.24d3e563-oliver.sang@intel.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 67e820798d25..af3d5517c710 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2465,8 +2465,10 @@ static inline bool io_run_task_work(void) * notify work that needs processing. */ if (current->flags & PF_IO_WORKER && - test_thread_flag(TIF_NOTIFY_RESUME)) + test_thread_flag(TIF_NOTIFY_RESUME)) { + __set_current_state(TASK_RUNNING); tracehook_notify_resume(NULL); + } if (test_thread_flag(TIF_NOTIFY_SIGNAL) || current->task_works) { __set_current_state(TASK_RUNNING); tracehook_notify_signal(); From a442f12e47aa866d09d442522eea14d5280e3a18 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 6 Mar 2023 13:18:27 -0700 Subject: [PATCH 0489/1017] io_uring: add a conditional reschedule to the IOPOLL cancelation loop commit fcc926bb857949dbfa51a7d95f3f5ebc657f198c upstream. If the kernel is configured with CONFIG_PREEMPT_NONE, we could be sitting in a tight loop reaping events but not giving them a chance to finish. This results in a trace ala: rcu: INFO: rcu_sched self-detected stall on CPU rcu: 2-...!: (5249 ticks this GP) idle=935c/1/0x4000000000000000 softirq=4265/4274 fqs=1 (t=5251 jiffies g=465 q=4135 ncpus=4) rcu: rcu_sched kthread starved for 5249 jiffies! g465 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=0 rcu: Unless rcu_sched kthread gets sufficient CPU time, OOM is now expected behavior. rcu: RCU grace-period kthread stack dump: task:rcu_sched state:R running task stack:0 pid:12 ppid:2 flags:0x00000008 Call trace: __switch_to+0xb0/0xc8 __schedule+0x43c/0x520 schedule+0x4c/0x98 schedule_timeout+0xbc/0xdc rcu_gp_fqs_loop+0x308/0x344 rcu_gp_kthread+0xd8/0xf0 kthread+0xb8/0xc8 ret_from_fork+0x10/0x20 rcu: Stack dump where RCU GP kthread last ran: Task dump for CPU 0: task:kworker/u8:10 state:R running task stack:0 pid:89 ppid:2 flags:0x0000000a Workqueue: events_unbound io_ring_exit_work Call trace: __switch_to+0xb0/0xc8 0xffff0000c8fefd28 CPU: 2 PID: 95 Comm: kworker/u8:13 Not tainted 6.2.0-rc5-00042-g40316e337c80-dirty #2759 Hardware name: linux,dummy-virt (DT) Workqueue: events_unbound io_ring_exit_work pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) pc : io_do_iopoll+0x344/0x360 lr : io_do_iopoll+0xb8/0x360 sp : ffff800009bebc60 x29: ffff800009bebc60 x28: 0000000000000000 x27: 0000000000000000 x26: ffff0000c0f67d48 x25: ffff0000c0f67840 x24: ffff800008950024 x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000c27d3200 x20: ffff0000c0f67840 x19: ffff0000c0f67800 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000001 x13: 0000000000000001 x12: 0000000000000000 x11: 0000000000000179 x10: 0000000000000870 x9 : ffff800009bebd60 x8 : ffff0000c27d3ad0 x7 : fefefefefefefeff x6 : 0000646e756f626e x5 : ffff0000c0f67840 x4 : 0000000000000000 x3 : ffff0000c2398000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: io_do_iopoll+0x344/0x360 io_uring_try_cancel_requests+0x21c/0x334 io_ring_exit_work+0x90/0x40c process_one_work+0x1a4/0x254 worker_thread+0x1ec/0x258 kthread+0xb8/0xc8 ret_from_fork+0x10/0x20 Add a cond_resched() in the cancelation IOPOLL loop to fix this. Cc: stable@vger.kernel.org # 5.10+ Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 1 + 1 file changed, 1 insertion(+) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index af3d5517c710..200cd28679ab 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -9690,6 +9690,7 @@ static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, while (!list_empty_careful(&ctx->iopoll_list)) { io_iopoll_try_reap_events(ctx); ret = true; + cond_resched(); } } From 72783d2af89b622282f7d83b166052292b70c87b Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Mon, 6 Mar 2023 13:21:40 -0700 Subject: [PATCH 0490/1017] io_uring/rsrc: disallow multi-source reg buffers commit edd478269640b360c6f301f2baa04abdda563ef3 upstream. If two or more mappings go back to back to each other they can be passed into io_uring to be registered as a single registered buffer. That would even work if mappings came from different sources, e.g. it's possible to mix in this way anon pages and pages from shmem or hugetlb. That is not a problem but it'd rather be less prone if we forbid such mixing. Cc: Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 200cd28679ab..5d07e0e9aadf 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -9057,14 +9057,17 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov, pret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM, pages, vmas); if (pret == nr_pages) { + struct file *file = vmas[0]->vm_file; + /* don't support file backed memory */ for (i = 0; i < nr_pages; i++) { - struct vm_area_struct *vma = vmas[i]; - - if (vma_is_shmem(vma)) + if (vmas[i]->vm_file != file) { + ret = -EINVAL; + break; + } + if (!file) continue; - if (vma->vm_file && - !is_file_hugepages(vma->vm_file)) { + if (!vma_is_shmem(vmas[i]) && !is_file_hugepages(file)) { ret = -EOPNOTSUPP; break; } From 7f3d13241574663c33c7ecda72ff1978a82a4db5 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 6 Mar 2023 13:23:06 -0700 Subject: [PATCH 0491/1017] io_uring: remove MSG_NOSIGNAL from recvmsg commit 7605c43d67face310b4b87dee1a28bc0c8cd8c0f upstream. MSG_NOSIGNAL is not applicable for the receiving side, SIGPIPE is generated when trying to write to a "broken pipe". AF_PACKET's packet_recvmsg() does enforce this, giving back EINVAL when MSG_NOSIGNAL is set - making it unuseable in io_uring's recvmsg. Remove MSG_NOSIGNAL from io_recvmsg_prep(). Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: David Lamparter Cc: Eric Dumazet Cc: Jens Axboe Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20230224150123.128346-1-equinox@diac24.net Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 5d07e0e9aadf..1016cf13a02a 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -4995,7 +4995,7 @@ static int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr)); sr->len = READ_ONCE(sqe->len); sr->bgid = READ_ONCE(sqe->buf_group); - sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL; + sr->msg_flags = READ_ONCE(sqe->msg_flags); if (sr->msg_flags & MSG_DONTWAIT) req->flags |= REQ_F_NOWAIT; From 246f26664b2ec47b4d6ba41b5c2b779550bda61d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 6 Mar 2023 13:28:57 -0700 Subject: [PATCH 0492/1017] io_uring/poll: allow some retries for poll triggering spuriously commit c16bda37594f83147b167d381d54c010024efecf upstream. If we get woken spuriously when polling and fail the operation with -EAGAIN again, then we generally only allow polling again if data had been transferred at some point. This is indicated with REQ_F_PARTIAL_IO. However, if the spurious poll triggers when the socket was originally empty, then we haven't transferred data yet and we will fail the poll re-arm. This either punts the socket to io-wq if it's blocking, or it fails the request with -EAGAIN if not. Neither condition is desirable, as the former will slow things down, while the latter will make the application confused. We want to ensure that a repeated poll trigger doesn't lead to infinite work making no progress, that's what the REQ_F_PARTIAL_IO check was for. But it doesn't protect against a loop post the first receive, and it's unnecessarily strict if we started out with an empty socket. Add a somewhat random retry count, just to put an upper limit on the potential number of retries that will be done. This should be high enough that we won't really hit it in practice, unless something needs to be aborted anyway. Cc: stable@vger.kernel.org # v5.10+ Link: https://github.com/axboe/liburing/issues/364 Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 1016cf13a02a..445afda927f4 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -486,6 +486,7 @@ struct io_poll_iocb { struct file *file; struct wait_queue_head *head; __poll_t events; + int retries; struct wait_queue_entry wait; }; @@ -5749,6 +5750,14 @@ enum { IO_APOLL_READY }; +/* + * We can't reliably detect loops in repeated poll triggers and issue + * subsequently failing. But rather than fail these immediately, allow a + * certain amount of retries before we give up. Given that this condition + * should _rarely_ trigger even once, we should be fine with a larger value. + */ +#define APOLL_MAX_RETRY 128 + static int io_arm_poll_handler(struct io_kiocb *req) { const struct io_op_def *def = &io_op_defs[req->opcode]; @@ -5760,8 +5769,6 @@ static int io_arm_poll_handler(struct io_kiocb *req) if (!req->file || !file_can_poll(req->file)) return IO_APOLL_ABORTED; - if ((req->flags & (REQ_F_POLLED|REQ_F_PARTIAL_IO)) == REQ_F_POLLED) - return IO_APOLL_ABORTED; if (!def->pollin && !def->pollout) return IO_APOLL_ABORTED; @@ -5779,8 +5786,13 @@ static int io_arm_poll_handler(struct io_kiocb *req) if (req->flags & REQ_F_POLLED) { apoll = req->apoll; kfree(apoll->double_poll); + if (unlikely(!--apoll->poll.retries)) { + apoll->double_poll = NULL; + return IO_APOLL_ABORTED; + } } else { apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC); + apoll->poll.retries = APOLL_MAX_RETRY; } if (unlikely(!apoll)) return IO_APOLL_ABORTED; From ae2340769ed3c2a3d3de0fab64b667db6df27744 Mon Sep 17 00:00:00 2001 From: Dmitry Fomin Date: Sat, 25 Feb 2023 21:43:21 +0300 Subject: [PATCH 0493/1017] ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls() commit 951606a14a8901e3551fe4d8d3cedd73fe954ce1 upstream. If snd_ctl_add() fails in aureon_add_controls(), it immediately returns and leaves ice->gpio_mutex locked. ice->gpio_mutex locks in snd_ice1712_save_gpio_status and unlocks in snd_ice1712_restore_gpio_status(ice). It seems that the mutex is required only for aureon_cs8415_get(), so snd_ice1712_restore_gpio_status(ice) can be placed just after that. Compile tested only. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Dmitry Fomin Cc: Link: https://lore.kernel.org/r/20230225184322.6286-1-fomindmitriyfoma@mail.ru Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/ice1712/aureon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 9a30f6d35d13..40a0e0095030 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -1892,6 +1892,7 @@ static int aureon_add_controls(struct snd_ice1712 *ice) unsigned char id; snd_ice1712_save_gpio_status(ice); id = aureon_cs8415_get(ice, CS8415_ID); + snd_ice1712_restore_gpio_status(ice); if (id != 0x41) dev_info(ice->card->dev, "No CS8415 chip. Skipping CS8415 controls.\n"); @@ -1909,7 +1910,6 @@ static int aureon_add_controls(struct snd_ice1712 *ice) kctl->id.device = ice->pcm->device; } } - snd_ice1712_restore_gpio_status(ice); } return 0; From a9cd89463ea44606b68c149da1b27e1c1ee704de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= Date: Thu, 23 Feb 2023 08:47:48 +0100 Subject: [PATCH 0494/1017] ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ea24b9953bcd3889f77a66e7f1d7e86e995dd9c3 upstream. HP EliteDesk 800 G6 Tower PC (103c:870c) requires a quirk for enabling headset-mic. Signed-off-by: Łukasz Stelmach Cc: Link: https://bugzilla.kernel.org/show_bug.cgi?id=217008 Link: https://lore.kernel.org/r/20230223074749.1026060-1-l.stelmach@samsung.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fffa681313b6..f2ef75c8de42 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11153,6 +11153,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), + SND_PCI_QUIRK(0x103c, 0x870c, "HP", ALC897_FIXUP_HP_HSMIC_VERB), SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB), SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2), SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2), From ab22799f11e378a37d1c8c4e47e796f84be97a60 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 10 Jan 2023 09:53:27 +0800 Subject: [PATCH 0495/1017] jbd2: fix data missing when reusing bh which is ready to be checkpointed commit e6b9bd7290d334451ce054e98e752abc055e0034 upstream. Following process will make data lost and could lead to a filesystem corrupted problem: 1. jh(bh) is inserted into T1->t_checkpoint_list, bh is dirty, and jh->b_transaction = NULL 2. T1 is added into journal->j_checkpoint_transactions. 3. Get bh prepare to write while doing checkpoing: PA PB do_get_write_access jbd2_log_do_checkpoint spin_lock(&jh->b_state_lock) if (buffer_dirty(bh)) clear_buffer_dirty(bh) // clear buffer dirty set_buffer_jbddirty(bh) transaction = journal->j_checkpoint_transactions jh = transaction->t_checkpoint_list if (!buffer_dirty(bh)) __jbd2_journal_remove_checkpoint(jh) // bh won't be flushed jbd2_cleanup_journal_tail __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved) 4. Aborting journal/Power-cut before writing latest bh on journal area. In this way we get a corrupted filesystem with bh's data lost. Fix it by moving the clearing of buffer_dirty bit just before the call to __jbd2_journal_file_buffer(), both bit clearing and jh->b_transaction assignment are under journal->j_list_lock locked, so that jbd2_log_do_checkpoint() will wait until jh's new transaction fininshed even bh is currently not dirty. And journal_shrink_one_cp_list() won't remove jh from checkpoint list if the buffer head is reused in do_get_write_access(). Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216898 Cc: Signed-off-by: Zhihao Cheng Signed-off-by: zhanchengbin Suggested-by: Jan Kara Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230110015327.1181863-1-chengzhihao1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/transaction.c | 50 +++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 86472212cce1..1923528154b5 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -984,36 +984,28 @@ repeat: * ie. locked but not dirty) or tune2fs (which may actually have * the buffer dirtied, ugh.) */ - if (buffer_dirty(bh)) { + if (buffer_dirty(bh) && jh->b_transaction) { + warn_dirty_buffer(bh); /* - * First question: is this buffer already part of the current - * transaction or the existing committing transaction? - */ - if (jh->b_transaction) { - J_ASSERT_JH(jh, - jh->b_transaction == transaction || - jh->b_transaction == - journal->j_committing_transaction); - if (jh->b_next_transaction) - J_ASSERT_JH(jh, jh->b_next_transaction == - transaction); - warn_dirty_buffer(bh); - } - /* - * In any case we need to clean the dirty flag and we must - * do it under the buffer lock to be sure we don't race - * with running write-out. + * We need to clean the dirty flag and we must do it under the + * buffer lock to be sure we don't race with running write-out. */ JBUFFER_TRACE(jh, "Journalling dirty buffer"); clear_buffer_dirty(bh); + /* + * The buffer is going to be added to BJ_Reserved list now and + * nothing guarantees jbd2_journal_dirty_metadata() will be + * ever called for it. So we need to set jbddirty bit here to + * make sure the buffer is dirtied and written out when the + * journaling machinery is done with it. + */ set_buffer_jbddirty(bh); } - unlock_buffer(bh); - error = -EROFS; if (is_handle_aborted(handle)) { spin_unlock(&jh->b_state_lock); + unlock_buffer(bh); goto out; } error = 0; @@ -1023,8 +1015,10 @@ repeat: * b_next_transaction points to it */ if (jh->b_transaction == transaction || - jh->b_next_transaction == transaction) + jh->b_next_transaction == transaction) { + unlock_buffer(bh); goto done; + } /* * this is the first time this transaction is touching this buffer, @@ -1048,10 +1042,24 @@ repeat: */ smp_wmb(); spin_lock(&journal->j_list_lock); + if (test_clear_buffer_dirty(bh)) { + /* + * Execute buffer dirty clearing and jh->b_transaction + * assignment under journal->j_list_lock locked to + * prevent bh being removed from checkpoint list if + * the buffer is in an intermediate state (not dirty + * and jh->b_transaction is NULL). + */ + JBUFFER_TRACE(jh, "Journalling dirty buffer"); + set_buffer_jbddirty(bh); + } __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); spin_unlock(&journal->j_list_lock); + unlock_buffer(bh); goto done; } + unlock_buffer(bh); + /* * If there is already a copy-out version of this buffer, then we don't * need to make another one From d738789ae9ec47d3458a008788f3cdc862ebf0cb Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Tue, 3 Jan 2023 09:45:16 +0800 Subject: [PATCH 0496/1017] ext4: optimize ea_inode block expansion commit 1e9d62d252812575ded7c620d8fc67c32ff06c16 upstream. Copy ea data from inode entry when expanding ea block if possible. Then remove the ea entry if expansion success. Thus memcpy to a temporary buffer may be avoided. If the expansion fails, we do not need to recovery the removed ea entry neither in this way. Reported-by: syzbot+2dacb8f015bf1420155f@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=3613786cb88c93aa1c6a279b1df6a7b201347d08 Link: https://lore.kernel.org/r/20230103014517.495275-2-jun.nie@linaro.org Cc: stable@kernel.org Signed-off-by: Jun Nie Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/xattr.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 6bf1c62eff04..bd073bfe03df 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2564,9 +2564,8 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS); - buffer = kvmalloc(value_size, GFP_NOFS); b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS); - if (!is || !bs || !buffer || !b_entry_name) { + if (!is || !bs || !b_entry_name) { error = -ENOMEM; goto out; } @@ -2578,12 +2577,18 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, /* Save the entry name and the entry value */ if (entry->e_value_inum) { + buffer = kvmalloc(value_size, GFP_NOFS); + if (!buffer) { + error = -ENOMEM; + goto out; + } + error = ext4_xattr_inode_get(inode, entry, buffer, value_size); if (error) goto out; } else { size_t value_offs = le16_to_cpu(entry->e_value_offs); - memcpy(buffer, (void *)IFIRST(header) + value_offs, value_size); + buffer = (void *)IFIRST(header) + value_offs; } memcpy(b_entry_name, entry->e_name, entry->e_name_len); @@ -2598,25 +2603,26 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, if (error) goto out; - /* Remove the chosen entry from the inode */ - error = ext4_xattr_ibody_set(handle, inode, &i, is); - if (error) - goto out; - i.value = buffer; i.value_len = value_size; error = ext4_xattr_block_find(inode, &i, bs); if (error) goto out; - /* Add entry which was removed from the inode into the block */ + /* Move ea entry from the inode into the block */ error = ext4_xattr_block_set(handle, inode, &i, bs); if (error) goto out; - error = 0; + + /* Remove the chosen entry from the inode */ + i.value = NULL; + i.value_len = 0; + error = ext4_xattr_ibody_set(handle, inode, &i, is); + out: kfree(b_entry_name); - kvfree(buffer); + if (entry->e_value_inum && buffer) + kvfree(buffer); if (is) brelse(is->iloc.bh); if (bs) From 0dc0fa313bb4e86382a3e7125429710d44383196 Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Tue, 3 Jan 2023 09:45:17 +0800 Subject: [PATCH 0497/1017] ext4: refuse to create ea block when umounted commit f31173c19901a96bb2ebf6bcfec8a08df7095c91 upstream. The ea block expansion need to access s_root while it is already set as NULL when umount is triggered. Refuse this request to avoid panic. Reported-by: syzbot+2dacb8f015bf1420155f@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=3613786cb88c93aa1c6a279b1df6a7b201347d08 Link: https://lore.kernel.org/r/20230103014517.495275-3-jun.nie@linaro.org Cc: stable@kernel.org Signed-off-by: Jun Nie Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/xattr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index bd073bfe03df..b80ad5a7b05c 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1415,6 +1415,13 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle, uid_t owner[2] = { i_uid_read(inode), i_gid_read(inode) }; int err; + if (inode->i_sb->s_root == NULL) { + ext4_warning(inode->i_sb, + "refuse to create EA inode when umounting"); + WARN_ON(1); + return ERR_PTR(-EINVAL); + } + /* * Let the next inode be the goal, so we try and allocate the EA inode * in the same group, or nearby one. From e6409208c13f7c56adc12dd795abf4141e3d5e64 Mon Sep 17 00:00:00 2001 From: Louis Rannou Date: Fri, 3 Feb 2023 09:07:54 +0200 Subject: [PATCH 0498/1017] mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type commit f0f0cfdc3a024e21161714f2e05f0df3b84d42ad upstream. spi_nor_set_erase_type() was used either to set or to mask out an erase type. When we used it to mask out an erase type a shift-out-of-bounds was hit: UBSAN: shift-out-of-bounds in drivers/mtd/spi-nor/core.c:2237:24 shift exponent 4294967295 is too large for 32-bit type 'int' The setting of the size_{shift, mask} and of the opcode are unnecessary when the erase size is zero, as throughout the code just the erase size is considered to determine whether an erase type is supported or not. Setting the opcode to 0xFF was wrong too as nobody guarantees that 0xFF is an unused opcode. Thus when masking out an erase type, just set the erase size to zero. This will fix the shift-out-of-bounds. Fixes: 5390a8df769e ("mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories") Cc: stable@vger.kernel.org Reported-by: Alexander Stein Signed-off-by: Louis Rannou Tested-by: Alexander Stein Link: https://lore.kernel.org/r/20230203070754.50677-1-tudor.ambarus@linaro.org [ta: refine changes, new commit message, fix compilation error] Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/spi-nor/core.c | 9 +++++++++ drivers/mtd/spi-nor/core.h | 1 + drivers/mtd/spi-nor/sfdp.c | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 2c256d455c9f..342215231932 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2424,6 +2424,15 @@ void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size, erase->size_mask = (1 << erase->size_shift) - 1; } +/** + * spi_nor_mask_erase_type() - mask out a SPI NOR erase type + * @erase: pointer to a structure that describes a SPI NOR erase type + */ +void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase) +{ + erase->size = 0; +} + /** * spi_nor_init_uniform_erase_map() - Initialize uniform erase map * @map: the erase map of the SPI NOR diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 6f62ee861231..788775bb6795 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -424,6 +424,7 @@ void spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, u8 opcode, void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size, u8 opcode); +void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase); struct spi_nor_erase_region * spi_nor_region_next(struct spi_nor_erase_region *region); void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map, diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 08de2a2b4452..9dc0528ea884 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -852,7 +852,7 @@ spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, */ for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) if (!(regions_erase_type & BIT(erase[i].idx))) - spi_nor_set_erase_type(&erase[i], 0, 0xFF); + spi_nor_mask_erase_type(&erase[i]); return 0; } @@ -1063,7 +1063,7 @@ static int spi_nor_parse_4bait(struct spi_nor *nor, erase_type[i].opcode = (dwords[1] >> erase_type[i].idx * 8) & 0xFF; else - spi_nor_set_erase_type(&erase_type[i], 0u, 0xFF); + spi_nor_mask_erase_type(&erase_type[i]); } /* From 3383f79d6b0a0641f767052fda3952dd1805d2d6 Mon Sep 17 00:00:00 2001 From: Pingfan Liu Date: Wed, 15 Feb 2023 19:23:40 +0800 Subject: [PATCH 0499/1017] dm: add cond_resched() to dm_wq_work() commit 0ca44fcef241768fd25ee763b3d203b9852f269b upstream. Otherwise the while() loop in dm_wq_work() can result in a "dead loop" on systems that have preemption disabled. This is particularly problematic on single cpu systems. Cc: stable@vger.kernel.org Signed-off-by: Pingfan Liu Acked-by: Ming Lei Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 7163ecc4d53f..c60febd14be1 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2393,6 +2393,7 @@ static void dm_wq_work(struct work_struct *work) break; submit_bio_noacct(bio); + cond_resched(); } } From 73090cebe3f3f4c5a13d2e76b5da4761fb15186b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 8 Jan 2023 17:08:16 +0200 Subject: [PATCH 0500/1017] wifi: rtl8xxxu: Use a longer retry limit of 48 commit 2a86aa9a1892d60ef2e3f310f5b42b8b05546d65 upstream. The Realtek rate control algorithm goes back and forth a lot between the highest and the lowest rate it's allowed to use. This is due to a lot of frames being dropped because the retry limits set by IEEE80211_CONF_CHANGE_RETRY_LIMITS are too low. (Experimentally, they are 4 for long frames and 7 for short frames.) The vendor drivers hardcode the value 48 for both retry limits (for station mode), which makes dropped frames very rare and thus the rate control is more stable. Because most Realtek chips handle the rate control in the firmware, which can't be modified, ignore the limits set by IEEE80211_CONF_CHANGE_RETRY_LIMITS and use the value 48 (set during chip initialisation), same as the vendor drivers. Cc: stable@vger.kernel.org Signed-off-by: Bitterblue Smith Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/477d745b-6bac-111d-403c-487fc19aa30d@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 376782b7aba8..deef1c09de31 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -5908,7 +5908,6 @@ static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed) { struct rtl8xxxu_priv *priv = hw->priv; struct device *dev = &priv->udev->dev; - u16 val16; int ret = 0, channel; bool ht40; @@ -5918,14 +5917,6 @@ static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed) __func__, hw->conf.chandef.chan->hw_value, changed, hw->conf.chandef.width); - if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - val16 = ((hw->conf.long_frame_max_tx_count << - RETRY_LIMIT_LONG_SHIFT) & RETRY_LIMIT_LONG_MASK) | - ((hw->conf.short_frame_max_tx_count << - RETRY_LIMIT_SHORT_SHIFT) & RETRY_LIMIT_SHORT_MASK); - rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16); - } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { switch (hw->conf.chandef.width) { case NL80211_CHAN_WIDTH_20_NOHT: From 2cfe78619b0de6d2da773978bc2d22797212eaa7 Mon Sep 17 00:00:00 2001 From: Alexander Wetzel Date: Tue, 24 Jan 2023 15:18:56 +0100 Subject: [PATCH 0501/1017] wifi: cfg80211: Fix use after free for wext commit 015b8cc5e7c4d7bb671f1984d7b7338c310b185b upstream. Key information in wext.connect is not reset on (re)connect and can hold data from a previous connection. Reset key data to avoid that drivers or mac80211 incorrectly detect a WEP connection request and access the freed or already reused memory. Additionally optimize cfg80211_sme_connect() and avoid an useless schedule of conn_work. Fixes: fffd0934b939 ("cfg80211: rework key operation") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230124141856.356646-1-alexander@wetzel-home.de Signed-off-by: Alexander Wetzel Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/wireless/sme.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 060e365c8259..f4d98ed8fa31 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -269,6 +269,15 @@ void cfg80211_conn_work(struct work_struct *work) rtnl_unlock(); } +static void cfg80211_step_auth_next(struct cfg80211_conn *conn, + struct cfg80211_bss *bss) +{ + memcpy(conn->bssid, bss->bssid, ETH_ALEN); + conn->params.bssid = conn->bssid; + conn->params.channel = bss->channel; + conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; +} + /* Returned bss is reference counted and must be cleaned up appropriately. */ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) { @@ -286,10 +295,7 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) if (!bss) return NULL; - memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN); - wdev->conn->params.bssid = wdev->conn->bssid; - wdev->conn->params.channel = bss->channel; - wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; + cfg80211_step_auth_next(wdev->conn, bss); schedule_work(&rdev->conn_work); return bss; @@ -568,7 +574,12 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, wdev->conn->params.ssid_len = wdev->ssid_len; /* see if we have the bss already */ - bss = cfg80211_get_conn_bss(wdev); + bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, + wdev->conn->params.bssid, + wdev->conn->params.ssid, + wdev->conn->params.ssid_len, + wdev->conn_bss_type, + IEEE80211_PRIVACY(wdev->conn->params.privacy)); if (prev_bssid) { memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN); @@ -579,6 +590,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, if (bss) { enum nl80211_timeout_reason treason; + cfg80211_step_auth_next(wdev->conn, bss); err = cfg80211_conn_do_work(wdev, &treason); cfg80211_put_bss(wdev->wiphy, bss); } else { @@ -1245,6 +1257,15 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, } else { if (WARN_ON(connkeys)) return -EINVAL; + + /* connect can point to wdev->wext.connect which + * can hold key data from a previous connection + */ + connect->key = NULL; + connect->key_len = 0; + connect->key_idx = 0; + connect->crypto.cipher_group = 0; + connect->crypto.n_ciphers_pairwise = 0; } wdev->connect_keys = connkeys; From 17f81b127712afb47060941a0290db9114b2f83a Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 1 Feb 2023 12:39:41 -0800 Subject: [PATCH 0502/1017] thermal: intel: powerclamp: Fix cur_state for multi package system commit 8e47363588377e1bdb65e2b020b409cfb44dd260 upstream. The powerclamp cooling device cur_state shows actual idle observed by package C-state idle counters. But the implementation is not sufficient for multi package or multi die system. The cur_state value is incorrect. On these systems, these counters must be read from each package/die and somehow aggregate them. But there is no good method for aggregation. It was not a problem when explicit CPU model addition was required to enable intel powerclamp. In this way certain CPU models could have been avoided. But with the removal of CPU model check with the availability of Package C-state counters, the driver is loaded on most of the recent systems. For multi package/die systems, just show the actual target idle state, the system is trying to achieve. In powerclamp this is the user set state minus one. Also there is no use of starting a worker thread for polling package C-state counters and applying any compensation for multiple package or multiple die systems. Fixes: b721ca0d1927 ("thermal/powerclamp: remove cpu whitelist") Signed-off-by: Srinivas Pandruvada Cc: 4.14+ # 4.14+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/intel/intel_powerclamp.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index fb04470d7d4b..6e7c230d308f 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -57,6 +57,7 @@ static unsigned int target_mwait; static struct dentry *debug_dir; +static bool poll_pkg_cstate_enable; /* user selected target */ static unsigned int set_target_ratio; @@ -262,6 +263,9 @@ static unsigned int get_compensation(int ratio) { unsigned int comp = 0; + if (!poll_pkg_cstate_enable) + return 0; + /* we only use compensation if all adjacent ones are good */ if (ratio == 1 && cal_data[ratio].confidence >= CONFIDENCE_OK && @@ -534,7 +538,8 @@ static int start_power_clamp(void) control_cpu = cpumask_first(cpu_online_mask); clamping = true; - schedule_delayed_work(&poll_pkg_cstate_work, 0); + if (poll_pkg_cstate_enable) + schedule_delayed_work(&poll_pkg_cstate_work, 0); /* start one kthread worker per online cpu */ for_each_online_cpu(cpu) { @@ -603,11 +608,15 @@ static int powerclamp_get_max_state(struct thermal_cooling_device *cdev, static int powerclamp_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { - if (true == clamping) - *state = pkg_cstate_ratio_cur; - else + if (clamping) { + if (poll_pkg_cstate_enable) + *state = pkg_cstate_ratio_cur; + else + *state = set_target_ratio; + } else { /* to save power, do not poll idle ratio while not clamping */ *state = -1; /* indicates invalid state */ + } return 0; } @@ -732,6 +741,9 @@ static int __init powerclamp_init(void) goto exit_unregister; } + if (topology_max_packages() == 1 && topology_max_die_per_package() == 1) + poll_pkg_cstate_enable = true; + cooling_dev = thermal_cooling_device_register("intel_powerclamp", NULL, &powerclamp_cooling_ops); if (IS_ERR(cooling_dev)) { From 07e375c18af0d661c128937a88c54c332d04bc95 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sun, 22 Jan 2023 14:03:56 -0500 Subject: [PATCH 0503/1017] dm flakey: fix logic when corrupting a bio commit aa56b9b75996ff4c76a0a4181c2fa0206c3d91cc upstream. If "corrupt_bio_byte" is set to corrupt reads and corrupt_bio_flags is used, dm-flakey would erroneously return all writes as errors. Likewise, if "corrupt_bio_byte" is set to corrupt writes, dm-flakey would return errors for all reads. Fix the logic so that if fc->corrupt_bio_byte is non-zero, dm-flakey will not abort reads on writes with an error. Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Reviewed-by: Sweet Tea Dorminy Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-flakey.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index a2cc9e45cbba..e4d52caf816f 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -359,9 +359,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) /* * Corrupt matching writes. */ - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) { - if (all_corrupt_bio_flags_match(bio, fc)) - corrupt_bio_data(bio, fc); + if (fc->corrupt_bio_byte) { + if (fc->corrupt_bio_rw == WRITE) { + if (all_corrupt_bio_flags_match(bio, fc)) + corrupt_bio_data(bio, fc); + } goto map_bio; } @@ -387,13 +389,14 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, return DM_ENDIO_DONE; if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && - all_corrupt_bio_flags_match(bio, fc)) { - /* - * Corrupt successful matching READs while in down state. - */ - corrupt_bio_data(bio, fc); - + if (fc->corrupt_bio_byte) { + if ((fc->corrupt_bio_rw == READ) && + all_corrupt_bio_flags_match(bio, fc)) { + /* + * Corrupt successful matching READs while in down state. + */ + corrupt_bio_data(bio, fc); + } } else if (!test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) { /* From f2b478228bfdd11e358c5bc197561331f5d5c394 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Sun, 22 Jan 2023 14:02:57 -0500 Subject: [PATCH 0504/1017] dm flakey: don't corrupt the zero page commit f50714b57aecb6b3dc81d578e295f86d9c73f078 upstream. When we need to zero some range on a block device, the function __blkdev_issue_zero_pages submits a write bio with the bio vector pointing to the zero page. If we use dm-flakey with corrupt bio writes option, it will corrupt the content of the zero page which results in crashes of various userspace programs. Glibc assumes that memory returned by mmap is zeroed and it uses it for calloc implementation; if the newly mapped memory is not zeroed, calloc will return non-zeroed memory. Fix this bug by testing if the page is equal to ZERO_PAGE(0) and avoiding the corruption in this case. Cc: stable@vger.kernel.org Fixes: a00f5276e266 ("dm flakey: Properly corrupt multi-page bios.") Signed-off-by: Mikulas Patocka Reviewed-by: Sweet Tea Dorminy Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-flakey.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index e4d52caf816f..36a4ef51ecaa 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -301,8 +301,11 @@ static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc) */ bio_for_each_segment(bvec, bio, iter) { if (bio_iter_len(bio, iter) > corrupt_bio_byte) { - char *segment = (page_address(bio_iter_page(bio, iter)) - + bio_iter_offset(bio, iter)); + char *segment; + struct page *page = bio_iter_page(bio, iter); + if (unlikely(page == ZERO_PAGE(0))) + break; + segment = (page_address(page) + bio_iter_offset(bio, iter)); segment[corrupt_bio_byte] = fc->corrupt_bio_value; DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n", From aaa2d2249c90b3ec91dc98b5a93958cdee2f685f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 9 Feb 2023 11:58:37 +0100 Subject: [PATCH 0505/1017] ARM: dts: exynos: correct TMU phandle in Exynos4210 commit 408ab6786dbf6dd696488054c9559681112ef994 upstream. TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. Since thermal-sensors property is already defined in included exynos4-cpu-thermal.dtsi, drop it from exynos4210.dtsi to fix the error and remoev redundancy. Fixes: 9843a2236003 ("ARM: dts: Provide dt bindings identical for Exynos TMU") Cc: Link: https://lore.kernel.org/r/20230209105841.779596-2-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos4210.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index fddc661ded28..448e1b153a01 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -382,7 +382,6 @@ &cpu_thermal { polling-delay-passive = <0>; polling-delay = <0>; - thermal-sensors = <&tmu 0>; }; &gic { From 135e968d6a86e6091a9c68851d39d9d5e8bab19c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 9 Feb 2023 11:58:36 +0100 Subject: [PATCH 0506/1017] ARM: dts: exynos: correct TMU phandle in Exynos4 commit 8e4505e617a80f601e2f53a917611777f128f925 upstream. TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. Fixes: 328829a6ad70 ("ARM: dts: define default thermal-zones for exynos4") Cc: Link: https://lore.kernel.org/r/20230209105841.779596-1-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos4-cpu-thermal.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi index 021d9fc1b492..27a1a8952665 100644 --- a/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi +++ b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi @@ -10,7 +10,7 @@ / { thermal-zones { cpu_thermal: cpu-thermal { - thermal-sensors = <&tmu 0>; + thermal-sensors = <&tmu>; polling-delay-passive = <0>; polling-delay = <0>; trips { From 136d6f3c5dc96d5bc67e63cd607f343158f7b7ba Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 9 Feb 2023 11:58:41 +0100 Subject: [PATCH 0507/1017] ARM: dts: exynos: correct TMU phandle in Odroid XU3 family commit a3583e92d188ec6c58c7f603ac5e72dd8a11c21a upstream. TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. This was not critical before, but since rework of thermal Devicetree initialization in the commit 3fd6d6e2b4e8 ("thermal/of: Rework the thermal device tree initialization"), this leads to errors registering thermal zones other than first one: thermal_sys: cpu0-thermal: Failed to read thermal-sensors cells: -2 thermal_sys: Failed to find thermal zone for tmu id=0 exynos-tmu 10064000.tmu: Failed to register sensor: -2 exynos-tmu: probe of 10064000.tmu failed with error -2 Fixes: f1722d7dd8b8 ("ARM: dts: Define default thermal-zones for exynos5422") Cc: Link: https://lore.kernel.org/r/20230209105841.779596-6-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 5da2d81e3be2..099ed4384be8 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -50,7 +50,7 @@ thermal-zones { cpu0_thermal: cpu0-thermal { - thermal-sensors = <&tmu_cpu0 0>; + thermal-sensors = <&tmu_cpu0>; polling-delay-passive = <250>; polling-delay = <0>; trips { @@ -139,7 +139,7 @@ }; }; cpu1_thermal: cpu1-thermal { - thermal-sensors = <&tmu_cpu1 0>; + thermal-sensors = <&tmu_cpu1>; polling-delay-passive = <250>; polling-delay = <0>; trips { @@ -212,7 +212,7 @@ }; }; cpu2_thermal: cpu2-thermal { - thermal-sensors = <&tmu_cpu2 0>; + thermal-sensors = <&tmu_cpu2>; polling-delay-passive = <250>; polling-delay = <0>; trips { @@ -285,7 +285,7 @@ }; }; cpu3_thermal: cpu3-thermal { - thermal-sensors = <&tmu_cpu3 0>; + thermal-sensors = <&tmu_cpu3>; polling-delay-passive = <250>; polling-delay = <0>; trips { @@ -358,7 +358,7 @@ }; }; gpu_thermal: gpu-thermal { - thermal-sensors = <&tmu_gpu 0>; + thermal-sensors = <&tmu_gpu>; polling-delay-passive = <250>; polling-delay = <0>; trips { From d1887cca652603076ae814c16935c8a956d6aa28 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 9 Feb 2023 11:58:38 +0100 Subject: [PATCH 0508/1017] ARM: dts: exynos: correct TMU phandle in Exynos5250 commit 33e2c595e2e4016991ead44933a29d1ef93d5f26 upstream. TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. Cc: Fixes: 9843a2236003 ("ARM: dts: Provide dt bindings identical for Exynos TMU") Link: https://lore.kernel.org/r/20230209105841.779596-3-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos5250.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index bd2d8835dd36..62051e600b32 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -1109,7 +1109,7 @@ &cpu_thermal { polling-delay-passive = <0>; polling-delay = <0>; - thermal-sensors = <&tmu 0>; + thermal-sensors = <&tmu>; cooling-maps { map0 { From 7dd9de2e2f7b040c31dbf3695b102ad0398dfeb6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 9 Feb 2023 11:58:39 +0100 Subject: [PATCH 0509/1017] ARM: dts: exynos: correct TMU phandle in Odroid XU commit 9372eca505e7a19934d750b4b4c89a3652738e66 upstream. TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. Since thermal-sensors property is already defined in included exynosi5410.dtsi, drop it from exynos5410-odroidxu.dts to fix the error and remoev redundancy. Fixes: 88644b4c750b ("ARM: dts: exynos: Configure PWM, usb3503, PMIC and thermal on Odroid XU board") Cc: Link: https://lore.kernel.org/r/20230209105841.779596-4-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos5410-odroidxu.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts index bd1d8499a108..147c077e8855 100644 --- a/arch/arm/boot/dts/exynos5410-odroidxu.dts +++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts @@ -116,7 +116,6 @@ }; &cpu0_thermal { - thermal-sensors = <&tmu_cpu0 0>; polling-delay-passive = <0>; polling-delay = <0>; From 0f2fd21b5b54530f14f75ef11cc62dc7f52dab1b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 9 Feb 2023 11:58:40 +0100 Subject: [PATCH 0510/1017] ARM: dts: exynos: correct TMU phandle in Odroid HC1 commit 2e3d0e20d8456f876607a8af61fdb83dfbf98cb6 upstream. TMU node uses 0 as thermal-sensor-cells, thus thermal zone referencing it must not have an argument to phandle. This was not critical before, but since rework of thermal Devicetree initialization in the commit 3fd6d6e2b4e8 ("thermal/of: Rework the thermal device tree initialization"), this leads to errors registering thermal zones other than first one: thermal_sys: cpu0-thermal: Failed to read thermal-sensors cells: -2 thermal_sys: Failed to find thermal zone for tmu id=0 exynos-tmu 10064000.tmu: Failed to register sensor: -2 exynos-tmu: probe of 10064000.tmu failed with error -2 Fixes: 1ac49427b566 ("ARM: dts: exynos: Add support for Hardkernel's Odroid HC1 board") Cc: Link: https://lore.kernel.org/r/20230209105841.779596-5-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos5422-odroidhc1.dts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/exynos5422-odroidhc1.dts b/arch/arm/boot/dts/exynos5422-odroidhc1.dts index 88f5c150a30a..a1871d4a0f2a 100644 --- a/arch/arm/boot/dts/exynos5422-odroidhc1.dts +++ b/arch/arm/boot/dts/exynos5422-odroidhc1.dts @@ -29,7 +29,7 @@ thermal-zones { cpu0_thermal: cpu0-thermal { - thermal-sensors = <&tmu_cpu0 0>; + thermal-sensors = <&tmu_cpu0>; trips { cpu0_alert0: cpu-alert-0 { temperature = <70000>; /* millicelsius */ @@ -84,7 +84,7 @@ }; }; cpu1_thermal: cpu1-thermal { - thermal-sensors = <&tmu_cpu1 0>; + thermal-sensors = <&tmu_cpu1>; trips { cpu1_alert0: cpu-alert-0 { temperature = <70000>; @@ -128,7 +128,7 @@ }; }; cpu2_thermal: cpu2-thermal { - thermal-sensors = <&tmu_cpu2 0>; + thermal-sensors = <&tmu_cpu2>; trips { cpu2_alert0: cpu-alert-0 { temperature = <70000>; @@ -172,7 +172,7 @@ }; }; cpu3_thermal: cpu3-thermal { - thermal-sensors = <&tmu_cpu3 0>; + thermal-sensors = <&tmu_cpu3>; trips { cpu3_alert0: cpu-alert-0 { temperature = <70000>; @@ -216,7 +216,7 @@ }; }; gpu_thermal: gpu-thermal { - thermal-sensors = <&tmu_gpu 0>; + thermal-sensors = <&tmu_gpu>; trips { gpu_alert0: gpu-alert-0 { temperature = <70000>; From ae16346078b1189aee934afd872d9f3d0a682c33 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Fri, 24 Feb 2023 18:48:54 +0100 Subject: [PATCH 0511/1017] rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails commit f7c4d9b133c7a04ca619355574e96b6abf209fba upstream. If getting an ID or setting up a work queue in rbd_dev_create() fails, use-after-free on rbd_dev->rbd_client, rbd_dev->spec and rbd_dev->opts is triggered in do_rbd_add(). The root cause is that the ownership of these structures is transfered to rbd_dev prematurely and they all end up getting freed when rbd_dev_create() calls rbd_dev_free() prior to returning to do_rbd_add(). Found by Linux Verification Center (linuxtesting.org) with SVACE, an incomplete patch submitted by Natalia Petrova . Cc: stable@vger.kernel.org Fixes: 1643dfa4c2c8 ("rbd: introduce a per-device ordered workqueue") Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman --- drivers/block/rbd.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 340b1df365f7..932d4bb8e403 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -5369,8 +5369,7 @@ static void rbd_dev_release(struct device *dev) module_put(THIS_MODULE); } -static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc, - struct rbd_spec *spec) +static struct rbd_device *__rbd_dev_create(struct rbd_spec *spec) { struct rbd_device *rbd_dev; @@ -5415,9 +5414,6 @@ static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc, rbd_dev->dev.parent = &rbd_root_dev; device_initialize(&rbd_dev->dev); - rbd_dev->rbd_client = rbdc; - rbd_dev->spec = spec; - return rbd_dev; } @@ -5430,12 +5426,10 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, { struct rbd_device *rbd_dev; - rbd_dev = __rbd_dev_create(rbdc, spec); + rbd_dev = __rbd_dev_create(spec); if (!rbd_dev) return NULL; - rbd_dev->opts = opts; - /* get an id and fill in device name */ rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, minor_to_rbd_dev_id(1 << MINORBITS), @@ -5452,6 +5446,10 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, /* we have a ref from do_rbd_add() */ __module_get(THIS_MODULE); + rbd_dev->rbd_client = rbdc; + rbd_dev->spec = spec; + rbd_dev->opts = opts; + dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id); return rbd_dev; @@ -6812,7 +6810,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) goto out_err; } - parent = __rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec); + parent = __rbd_dev_create(rbd_dev->parent_spec); if (!parent) { ret = -ENOMEM; goto out_err; @@ -6822,8 +6820,8 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) * Images related by parent/child relationships always share * rbd_client and spec/parent_spec, so bump their refcounts. */ - __rbd_get_client(rbd_dev->rbd_client); - rbd_spec_get(rbd_dev->parent_spec); + parent->rbd_client = __rbd_get_client(rbd_dev->rbd_client); + parent->spec = rbd_spec_get(rbd_dev->parent_spec); __set_bit(RBD_DEV_FLAG_READONLY, &parent->flags); From 241e893df474c18340bea83eef3fd35fc4bb1d0e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 6 Jan 2023 19:25:59 -0500 Subject: [PATCH 0512/1017] alpha: fix FEN fault handling commit 977a3009547dad4a5bc95d91be4a58c9f7eedac0 upstream. Type 3 instruction fault (FPU insn with FPU disabled) is handled by quietly enabling FPU and returning. Which is fine, except that we need to do that both for fault in userland and in the kernel; the latter *can* legitimately happen - all it takes is this: .global _start _start: call_pal 0xae lda $0, 0 ldq $0, 0($0) - call_pal CLRFEN to clear "FPU enabled" flag and arrange for a signal delivery (SIGSEGV in this case). Fixed by moving the handling of type 3 into the common part of do_entIF(), before we check for kernel vs. user mode. Incidentally, the check for kernel mode is unidiomatic; the normal way to do that is !user_mode(regs). The difference is that the open-coded variant treats any of bits 63..3 of regs->ps being set as "it's user mode" while the normal approach is to check just the bit 3. PS is a 4-bit register and regs->ps always will have bits 63..4 clear, so the open-coded variant here is actually equivalent to !user_mode(regs). Harder to follow, though... Cc: stable@vger.kernel.org Reviewed-by: Richard Henderson Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/traps.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 8b0f81a58b94..751d3197ca76 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -235,7 +235,21 @@ do_entIF(unsigned long type, struct pt_regs *regs) { int signo, code; - if ((regs->ps & ~IPL_MAX) == 0) { + if (type == 3) { /* FEN fault */ + /* Irritating users can call PAL_clrfen to disable the + FPU for the process. The kernel will then trap in + do_switch_stack and undo_switch_stack when we try + to save and restore the FP registers. + + Given that GCC by default generates code that uses the + FP registers, PAL_clrfen is not useful except for DoS + attacks. So turn the bleeding FPU back on and be done + with it. */ + current_thread_info()->pcb.flags |= 1; + __reload_thread(¤t_thread_info()->pcb); + return; + } + if (!user_mode(regs)) { if (type == 1) { const unsigned int *data = (const unsigned int *) regs->pc; @@ -368,20 +382,6 @@ do_entIF(unsigned long type, struct pt_regs *regs) } break; - case 3: /* FEN fault */ - /* Irritating users can call PAL_clrfen to disable the - FPU for the process. The kernel will then trap in - do_switch_stack and undo_switch_stack when we try - to save and restore the FP registers. - - Given that GCC by default generates code that uses the - FP registers, PAL_clrfen is not useful except for DoS - attacks. So turn the bleeding FPU back on and be done - with it. */ - current_thread_info()->pcb.flags |= 1; - __reload_thread(¤t_thread_info()->pcb); - return; - case 5: /* illoc */ default: /* unexpected instruction-fault type */ ; From cd4d3eab231006f6c174a2630f3158ee25c3fceb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 16 Feb 2023 00:36:02 -0800 Subject: [PATCH 0513/1017] dax/kmem: Fix leak of memory-hotplug resources commit e686c32590f40bffc45f105c04c836ffad3e531a upstream. While experimenting with CXL region removal the following corruption of /proc/iomem appeared. Before: f010000000-f04fffffff : CXL Window 0 f010000000-f02fffffff : region4 f010000000-f02fffffff : dax4.0 f010000000-f02fffffff : System RAM (kmem) After (modprobe -r cxl_test): f010000000-f02fffffff : **redacted binary garbage** f010000000-f02fffffff : System RAM (kmem) ...and testing further the same is visible with persistent memory assigned to kmem: Before: 480000000-243fffffff : Persistent Memory 480000000-57e1fffff : namespace3.0 580000000-243fffffff : dax3.0 580000000-243fffffff : System RAM (kmem) After (ndctl disable-region all): 480000000-243fffffff : Persistent Memory 580000000-243fffffff : ***redacted binary garbage*** 580000000-243fffffff : System RAM (kmem) The corrupted data is from a use-after-free of the "dax4.0" and "dax3.0" resources, and it also shows that the "System RAM (kmem)" resource is not being removed. The bug does not appear after "modprobe -r kmem", it requires the parent of "dax4.0" and "dax3.0" to be removed which re-parents the leaked "System RAM (kmem)" instances. Those in turn reference the freed resource as a parent. First up for the fix is release_mem_region_adjustable() needs to reliably delete the resource inserted by add_memory_driver_managed(). That is thwarted by a check for IORESOURCE_SYSRAM that predates the dax/kmem driver, from commit: 65c78784135f ("kernel, resource: check for IORESOURCE_SYSRAM in release_mem_region_adjustable") That appears to be working around the behavior of HMM's "MEMORY_DEVICE_PUBLIC" facility that has since been deleted. With that check removed the "System RAM (kmem)" resource gets removed, but corruption still occurs occasionally because the "dax" resource is not reliably removed. The dax range information is freed before the device is unregistered, so the driver can not reliably recall (another use after free) what it is meant to release. Lastly if that use after free got lucky, the driver was covering up the leak of "System RAM (kmem)" due to its use of release_resource() which detaches, but does not free, child resources. The switch to remove_resource() forces remove_memory() to be responsible for the deletion of the resource added by add_memory_driver_managed(). Fixes: c2f3011ee697 ("device-dax: add an allocation interface for device-dax instances") Cc: Cc: Oscar Salvador Cc: David Hildenbrand Cc: Pavel Tatashin Reviewed-by: Vishal Verma Reviewed-by: Pasha Tatashin Reviewed-by: Dave Jiang Link: https://lore.kernel.org/r/167653656244.3147810.5705900882794040229.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/dax/bus.c | 2 +- drivers/dax/kmem.c | 4 ++-- kernel/resource.c | 14 -------------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index c1d379bd7af3..a02777c93c07 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -398,8 +398,8 @@ static void unregister_dev_dax(void *dev) dev_dbg(dev, "%s\n", __func__); kill_dev_dax(dev_dax); - free_dev_dax_ranges(dev_dax); device_del(dev); + free_dev_dax_ranges(dev_dax); put_device(dev); } diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c index b4368c5b6a0c..27d669f8b5f3 100644 --- a/drivers/dax/kmem.c +++ b/drivers/dax/kmem.c @@ -114,7 +114,7 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) if (rc) { dev_warn(dev, "mapping%d: %#llx-%#llx memory add failed\n", i, range.start, range.end); - release_resource(res); + remove_resource(res); kfree(res); data->res[i] = NULL; if (mapped) @@ -159,7 +159,7 @@ static int dev_dax_kmem_remove(struct dev_dax *dev_dax) rc = remove_memory(dev_dax->target_node, range.start, range_len(&range)); if (rc == 0) { - release_resource(data->res[i]); + remove_resource(data->res[i]); kfree(data->res[i]); data->res[i] = NULL; success++; diff --git a/kernel/resource.c b/kernel/resource.c index 817545ff80b9..100253d4909c 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -1293,20 +1293,6 @@ retry: continue; } - /* - * All memory regions added from memory-hotplug path have the - * flag IORESOURCE_SYSTEM_RAM. If the resource does not have - * this flag, we know that we are dealing with a resource coming - * from HMM/devm. HMM/devm use another mechanism to add/release - * a resource. This goes via devm_request_mem_region and - * devm_release_mem_region. - * HMM/devm take care to release their resources when they want, - * so if we are dealing with them, let us just back off here. - */ - if (!(res->flags & IORESOURCE_SYSRAM)) { - break; - } - if (!(res->flags & IORESOURCE_MEM)) break; From 6c96c0b2e32661b2da11d4eab9c895336b2e9680 Mon Sep 17 00:00:00 2001 From: Elvira Khabirova Date: Sat, 18 Feb 2023 23:43:59 +0100 Subject: [PATCH 0514/1017] mips: fix syscall_get_nr commit 85cc91e2ba4262a602ec65e2b76c4391a9e60d3d upstream. The implementation of syscall_get_nr on mips used to ignore the task argument and return the syscall number of the calling thread instead of the target thread. The bug was exposed to user space by commit 201766a20e30f ("ptrace: add PTRACE_GET_SYSCALL_INFO request") and detected by strace test suite. Link: https://github.com/strace/strace/issues/235 Fixes: c2d9f1775731 ("MIPS: Fix syscall_get_nr for the syscall exit tracing.") Cc: # v3.19+ Co-developed-by: Dmitry V. Levin Signed-off-by: Dmitry V. Levin Signed-off-by: Elvira Khabirova Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman --- arch/mips/include/asm/syscall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 25fa651c937d..ebdf4d910af2 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -38,7 +38,7 @@ static inline bool mips_syscall_is_indirect(struct task_struct *task, static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return current_thread_info()->syscall; + return task_thread_info(task)->syscall; } static inline void mips_syscall_update_nr(struct task_struct *task, From 3b78c2482bbe1889bc8c441e113c666ff6b6b329 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 21 Dec 2022 09:30:11 +0100 Subject: [PATCH 0515/1017] media: ipu3-cio2: Fix PM runtime usage_count in driver unbind commit 909d3096ac99fa2289f9b8945a3eab2269947a0a upstream. Get the PM runtime usage_count and forbid PM runtime at driver unbind. The opposite is being done in probe() already. Fixes: commit c2a6a07afe4a ("media: intel-ipu3: cio2: add new MIPI-CSI2 driver") Cc: stable@vger.kernel.org # for >= 4.16 Signed-off-by: Sakari Ailus Reviewed-by: Bingbu Cao Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 2fe4a0bd0284..d6838c8ebd7e 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -1831,6 +1831,9 @@ static void cio2_pci_remove(struct pci_dev *pci_dev) v4l2_device_unregister(&cio2->v4l2_dev); media_device_cleanup(&cio2->media_dev); mutex_destroy(&cio2->lock); + + pm_runtime_forbid(&pci_dev->dev); + pm_runtime_get_noresume(&pci_dev->dev); } static int __maybe_unused cio2_runtime_suspend(struct device *dev) From 6814e8e4202f3507a5b51c80a3c38f6e7a3973fb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 4 Jan 2023 16:31:10 +0800 Subject: [PATCH 0516/1017] remoteproc/mtk_scp: Move clk ops outside send_lock commit e46ceea3148163166ef9b7bcac578e72dd30c064 upstream. Clocks are properly reference counted and do not need to be inside the lock range. Right now this triggers a false-positive lockdep warning on MT8192 based Chromebooks, through a combination of mtk-scp that has a cros-ec-rpmsg sub-device, the (actual) cros-ec I2C adapter registration, I2C client (not on cros-ec) probe doing i2c transfers and enabling clocks. This is a false positive because the cros-ec-rpmsg under mtk-scp does not have an I2C adapter, and also each I2C adapter and cros-ec instance have their own mutex. Move the clk operations outside of the send_lock range. Fixes: 63c13d61eafe ("remoteproc/mediatek: add SCP support for mt8183") Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230104083110.736377-1-wenst@chromium.org [Fixed "Fixes:" tag line] Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/remoteproc/mtk_scp_ipi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/remoteproc/mtk_scp_ipi.c b/drivers/remoteproc/mtk_scp_ipi.c index 6dc955ecab80..968128b78e59 100644 --- a/drivers/remoteproc/mtk_scp_ipi.c +++ b/drivers/remoteproc/mtk_scp_ipi.c @@ -164,21 +164,21 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf)) return -EINVAL; - mutex_lock(&scp->send_lock); - ret = clk_prepare_enable(scp->clk); if (ret) { dev_err(scp->dev, "failed to enable clock\n"); - goto unlock_mutex; + return ret; } + mutex_lock(&scp->send_lock); + /* Wait until SCP receives the last command */ timeout = jiffies + msecs_to_jiffies(2000); do { if (time_after(jiffies, timeout)) { dev_err(scp->dev, "%s: IPI timeout!\n", __func__); ret = -ETIMEDOUT; - goto clock_disable; + goto unlock_mutex; } } while (readl(scp->reg_base + scp->data->host_to_scp_reg)); @@ -205,10 +205,9 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, ret = 0; } -clock_disable: - clk_disable_unprepare(scp->clk); unlock_mutex: mutex_unlock(&scp->send_lock); + clk_disable_unprepare(scp->clk); return ret; } From f1f6c87d82248b59904889538fff1b8063800af4 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Thu, 29 Dec 2022 14:49:39 +0106 Subject: [PATCH 0517/1017] docs: gdbmacros: print newest record commit f2e4cca2f670c8e52fbb551a295f2afc9aa2bd72 upstream. @head_id points to the newest record, but the printing loop exits when it increments to this value (before printing). Exit the printing loop after the newest record has been printed. The python-based function in scripts/gdb/linux/dmesg.py already does this correctly. Fixes: e60768311af8 ("scripts/gdb: update for lockless printk ringbuffer") Cc: stable@vger.kernel.org Signed-off-by: John Ogness Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20221229134339.197627-1-john.ogness@linutronix.de Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/kdump/gdbmacros.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/admin-guide/kdump/gdbmacros.txt b/Documentation/admin-guide/kdump/gdbmacros.txt index 82aecdcae8a6..030de95e3e6b 100644 --- a/Documentation/admin-guide/kdump/gdbmacros.txt +++ b/Documentation/admin-guide/kdump/gdbmacros.txt @@ -312,10 +312,10 @@ define dmesg set var $prev_flags = $info->flags end - set var $id = ($id + 1) & $id_mask if ($id == $end_id) loop_break end + set var $id = ($id + 1) & $id_mask end end document dmesg From e6d20325f422b3252aff2d42d8d09b2ebb434892 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Wed, 7 Dec 2022 14:00:39 +0100 Subject: [PATCH 0518/1017] mm: memcontrol: deprecate charge moving commit da34a8484d162585e22ed8c1e4114aa2f60e3567 upstream. Charge moving mode in cgroup1 allows memory to follow tasks as they migrate between cgroups. This is, and always has been, a questionable thing to do - for several reasons. First, it's expensive. Pages need to be identified, locked and isolated from various MM operations, and reassigned, one by one. Second, it's unreliable. Once pages are charged to a cgroup, there isn't always a clear owner task anymore. Cache isn't moved at all, for example. Mapped memory is moved - but if trylocking or isolating a page fails, it's arbitrarily left behind. Frequent moving between domains may leave a task's memory scattered all over the place. Third, it isn't really needed. Launcher tasks can kick off workload tasks directly in their target cgroup. Using dedicated per-workload groups allows fine-grained policy adjustments - no need to move tasks and their physical pages between control domains. The feature was never forward-ported to cgroup2, and it hasn't been missed. Despite it being a niche usecase, the maintenance overhead of supporting it is enormous. Because pages are moved while they are live and subject to various MM operations, the synchronization rules are complicated. There are lock_page_memcg() in MM and FS code, which non-cgroup people don't understand. In some cases we've been able to shift code and cgroup API calls around such that we can rely on native locking as much as possible. But that's fragile, and sometimes we need to hold MM locks for longer than we otherwise would (pte lock e.g.). Mark the feature deprecated. Hopefully we can remove it soon. And backport into -stable kernels so that people who develop against earlier kernels are warned about this deprecation as early as possible. [akpm@linux-foundation.org: fix memory.rst underlining] Link: https://lkml.kernel.org/r/Y5COd+qXwk/S+n8N@cmpxchg.org Signed-off-by: Johannes Weiner Acked-by: Shakeel Butt Acked-by: Hugh Dickins Acked-by: Michal Hocko Cc: Muchun Song Cc: Roman Gushchin Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/cgroup-v1/memory.rst | 13 +++++++++++-- mm/memcontrol.c | 4 ++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/cgroup-v1/memory.rst b/Documentation/admin-guide/cgroup-v1/memory.rst index 12757e63b26c..7882037aca67 100644 --- a/Documentation/admin-guide/cgroup-v1/memory.rst +++ b/Documentation/admin-guide/cgroup-v1/memory.rst @@ -82,6 +82,8 @@ Brief summary of control files. memory.swappiness set/show swappiness parameter of vmscan (See sysctl's vm.swappiness) memory.move_charge_at_immigrate set/show controls of moving charges + This knob is deprecated and shouldn't be + used. memory.oom_control set/show oom controls. memory.numa_stat show the number of memory usage per numa node @@ -740,8 +742,15 @@ NOTE2: It is recommended to set the soft limit always below the hard limit, otherwise the hard limit will take precedence. -8. Move charges at task migration -================================= +8. Move charges at task migration (DEPRECATED!) +=============================================== + +THIS IS DEPRECATED! + +It's expensive and unreliable! It's better practice to launch workload +tasks directly from inside their target cgroup. Use dedicated workload +cgroups to allow fine-grained policy adjustments without having to +move physical pages between control domains. Users can move charges associated with a task along with task migration, that is, uncharge task's pages from the old cgroup and charge them to the new cgroup. diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c62d997c8ca1..751e3670d7b0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3930,6 +3930,10 @@ static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css, { struct mem_cgroup *memcg = mem_cgroup_from_css(css); + pr_warn_once("Cgroup memory moving (move_charge_at_immigrate) is deprecated. " + "Please report your usecase to linux-mm@kvack.org if you " + "depend on this functionality.\n"); + if (val & ~MOVE_MASK) return -EINVAL; From ed77831e69ee85a09ff3e8c179bc01c06cb76e3d Mon Sep 17 00:00:00 2001 From: Yin Fengwei Date: Fri, 23 Dec 2022 21:52:07 +0800 Subject: [PATCH 0519/1017] mm/thp: check and bail out if page in deferred queue already commit 81e506bec9be1eceaf5a2c654e28ba5176ef48d8 upstream. Kernel build regression with LLVM was reported here: https://lore.kernel.org/all/Y1GCYXGtEVZbcv%2F5@dev-arch.thelio-3990X/ with commit f35b5d7d676e ("mm: align larger anonymous mappings on THP boundaries"). And the commit f35b5d7d676e was reverted. It turned out the regression is related with madvise(MADV_DONTNEED) was used by ld.lld. But with none PMD_SIZE aligned parameter len. trace-bpfcc captured: 531607 531732 ld.lld do_madvise.part.0 start: 0x7feca9000000, len: 0x7fb000, behavior: 0x4 531607 531793 ld.lld do_madvise.part.0 start: 0x7fec86a00000, len: 0x7fb000, behavior: 0x4 If the underneath physical page is THP, the madvise(MADV_DONTNEED) can trigger split_queue_lock contention raised significantly. perf showed following data: 14.85% 0.00% ld.lld [kernel.kallsyms] [k] entry_SYSCALL_64_after_hwframe 11.52% entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_madvise do_madvise.part.0 zap_page_range unmap_single_vma unmap_page_range page_remove_rmap deferred_split_huge_page __lock_text_start native_queued_spin_lock_slowpath If THP can't be removed from rmap as whole THP, partial THP will be removed from rmap by removing sub-pages from rmap. Even the THP head page is added to deferred queue already, the split_queue_lock will be acquired and check whether the THP head page is in the queue already. Thus, the contention of split_queue_lock is raised. Before acquire split_queue_lock, check and bail out early if the THP head page is in the queue already. The checking without holding split_queue_lock could race with deferred_split_scan, but it doesn't impact the correctness here. Test result of building kernel with ld.lld: commit 7b5a0b664ebe (parent commit of f35b5d7d676e): time -f "\t%E real,\t%U user,\t%S sys" make LD=ld.lld -skj96 allmodconfig all 6:07.99 real, 26367.77 user, 5063.35 sys commit f35b5d7d676e: time -f "\t%E real,\t%U user,\t%S sys" make LD=ld.lld -skj96 allmodconfig all 7:22.15 real, 26235.03 user, 12504.55 sys commit f35b5d7d676e with the fixing patch: time -f "\t%E real,\t%U user,\t%S sys" make LD=ld.lld -skj96 allmodconfig all 6:08.49 real, 26520.15 user, 5047.91 sys Link: https://lkml.kernel.org/r/20221223135207.2275317-1-fengwei.yin@intel.com Signed-off-by: Yin Fengwei Tested-by: Nathan Chancellor Acked-by: David Rientjes Reviewed-by: "Huang, Ying" Cc: Feng Tang Cc: Matthew Wilcox Cc: Rik van Riel Cc: Xing Zhengjun Cc: Yang Shi Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/huge_memory.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index cb7b0aead709..9b15760e0541 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2803,6 +2803,9 @@ void deferred_split_huge_page(struct page *page) if (PageSwapCache(page)) return; + if (!list_empty(page_deferred_list(page))) + return; + spin_lock_irqsave(&ds_queue->split_queue_lock, flags); if (list_empty(page_deferred_list(page))) { count_vm_event(THP_DEFERRED_SPLIT_PAGE); From 0dfb3f4588bc03d344e4ca4a70a06f24cf0cf6ec Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Jan 2023 16:32:13 -0500 Subject: [PATCH 0520/1017] ktest.pl: Give back console on Ctrt^C on monitor commit 83d29d439cd3ef23041570d55841f814af2ecac0 upstream. When monitoring the console output, the stdout is being redirected to do so. If Ctrl^C is hit during this mode, the stdout is not back to the console, the user does not see anything they type (no echo). Add "end_monitor" to the SIGINT interrupt handler to give back the console on Ctrl^C. Cc: stable@vger.kernel.org Fixes: 9f2cdcbbb90e7 ("ktest: Give console process a dedicated tty") Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- tools/testing/ktest/ktest.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 8b1e3ae8fe50..a9fb5a48751e 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -4283,6 +4283,9 @@ sub send_email { } sub cancel_test { + if ($monitor_cnt) { + end_monitor; + } if ($email_when_canceled) { my $name = get_test_name; send_email("KTEST: Your [$name] test was cancelled", From 39255e4788fb5a27dd6957540a62b037aa7841ea Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Jan 2023 11:31:25 -0500 Subject: [PATCH 0521/1017] ktest.pl: Fix missing "end_monitor" when machine check fails commit e8bf9b98d40dbdf4e39362e3b85a70c61da68cb7 upstream. In the "reboot" command, it does a check of the machine to see if it is still alive with a simple "ssh echo" command. If it fails, it will assume that a normal "ssh reboot" is not possible and force a power cycle. In this case, the "start_monitor" is executed, but the "end_monitor" is not, and this causes the screen will not be given back to the console. That is, after the test, a "reset" command needs to be performed, as "echo" is turned off. Cc: stable@vger.kernel.org Fixes: 6474ace999edd ("ktest.pl: Powercycle the box on reboot if no connection can be made") Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- tools/testing/ktest/ktest.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index a9fb5a48751e..2b2061a70b78 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1433,7 +1433,8 @@ sub reboot { # Still need to wait for the reboot to finish wait_for_monitor($time, $reboot_success_line); - + } + if ($powercycle || $time) { end_monitor; } } From 1693f3bc1f2566718993747166b9afe98c572fec Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Jan 2023 16:37:25 -0500 Subject: [PATCH 0522/1017] ktest.pl: Add RUN_TIMEOUT option with default unlimited commit 4e7d2a8f0b52abf23b1dc13b3d88bc0923383cd5 upstream. There is a disconnect between the run_command function and the wait_for_input. The wait_for_input has a default timeout of 2 minutes. But if that happens, the run_command loop will exit out to the waitpid() of the executing command. This fails in that it no longer monitors the command, and also, the ssh to the test box can hang when its finished, as it's waiting for the pipe it's writing to to flush, but the loop that reads that pipe has already exited, leaving the command stuck, and the test hangs. Instead, make the default "wait_for_input" of the run_command infinite, and allow the user to override it if they want with a default timeout option "RUN_TIMEOUT". But this fixes the hang that happens when the pipe is full and the ssh session never exits. Cc: stable@vger.kernel.org Fixes: 6e98d1b4415fe ("ktest: Add timeout to ssh command") Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- tools/testing/ktest/ktest.pl | 20 ++++++++++++++++---- tools/testing/ktest/sample.conf | 5 +++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 2b2061a70b78..ea26f2b0c1bc 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -178,6 +178,7 @@ my $store_failures; my $store_successes; my $test_name; my $timeout; +my $run_timeout; my $connect_timeout; my $config_bisect_exec; my $booted_timeout; @@ -340,6 +341,7 @@ my %option_map = ( "STORE_SUCCESSES" => \$store_successes, "TEST_NAME" => \$test_name, "TIMEOUT" => \$timeout, + "RUN_TIMEOUT" => \$run_timeout, "CONNECT_TIMEOUT" => \$connect_timeout, "CONFIG_BISECT_EXEC" => \$config_bisect_exec, "BOOTED_TIMEOUT" => \$booted_timeout, @@ -1800,6 +1802,14 @@ sub run_command { $command =~ s/\$SSH_USER/$ssh_user/g; $command =~ s/\$MACHINE/$machine/g; + if (!defined($timeout)) { + $timeout = $run_timeout; + } + + if (!defined($timeout)) { + $timeout = -1; # tell wait_for_input to wait indefinitely + } + doprint("$command ... "); $start_time = time; @@ -1826,13 +1836,10 @@ sub run_command { while (1) { my $fp = \*CMD; - if (defined($timeout)) { - doprint "timeout = $timeout\n"; - } my $line = wait_for_input($fp, $timeout); if (!defined($line)) { my $now = time; - if (defined($timeout) && (($now - $start_time) >= $timeout)) { + if ($timeout >= 0 && (($now - $start_time) >= $timeout)) { doprint "Hit timeout of $timeout, killing process\n"; $hit_timeout = 1; kill 9, $pid; @@ -2005,6 +2012,11 @@ sub wait_for_input $time = $timeout; } + if ($time < 0) { + # Negative number means wait indefinitely + undef $time; + } + $rin = ''; vec($rin, fileno($fp), 1) = 1; vec($rin, fileno(\*STDIN), 1) = 1; diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 5e7d1d729752..65957a9803b5 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -809,6 +809,11 @@ # is issued instead of a reboot. # CONNECT_TIMEOUT = 25 +# The timeout in seconds for how long to wait for any running command +# to timeout. If not defined, it will let it go indefinitely. +# (default undefined) +#RUN_TIMEOUT = 600 + # In between tests, a reboot of the box may occur, and this # is the time to wait for the console after it stops producing # output. Some machines may not produce a large lag on reboot From 6e02a43acd0691791df79ce538f2dd497a6c9b76 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 14 Feb 2023 17:36:43 +0530 Subject: [PATCH 0523/1017] ring-buffer: Handle race between rb_move_tail and rb_check_pages commit 8843e06f67b14f71c044bf6267b2387784c7e198 upstream. It seems a data race between ring_buffer writing and integrity check. That is, RB_FLAG of head_page is been updating, while at same time RB_FLAG was cleared when doing integrity check rb_check_pages(): rb_check_pages() rb_handle_head_page(): -------- -------- rb_head_page_deactivate() rb_head_page_set_normal() rb_head_page_activate() We do intergrity test of the list to check if the list is corrupted and it is still worth doing it. So, let's refactor rb_check_pages() such that we no longer clear and set flag during the list sanity checking. [1] and [2] are the test to reproduce and the crash report respectively. 1: ``` read_trace.sh while true; do # the "trace" file is closed after read head -1 /sys/kernel/tracing/trace > /dev/null done ``` ``` repro.sh sysctl -w kernel.panic_on_warn=1 # function tracer will writing enough data into ring_buffer echo function > /sys/kernel/tracing/current_tracer ./read_trace.sh & ./read_trace.sh & ./read_trace.sh & ./read_trace.sh & ./read_trace.sh & ./read_trace.sh & ./read_trace.sh & ./read_trace.sh & ``` 2: ------------[ cut here ]------------ WARNING: CPU: 9 PID: 62 at kernel/trace/ring_buffer.c:2653 rb_move_tail+0x450/0x470 Modules linked in: CPU: 9 PID: 62 Comm: ksoftirqd/9 Tainted: G W 6.2.0-rc6+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:rb_move_tail+0x450/0x470 Code: ff ff 4c 89 c8 f0 4d 0f b1 02 48 89 c2 48 83 e2 fc 49 39 d0 75 24 83 e0 03 83 f8 02 0f 84 e1 fb ff ff 48 8b 57 10 f0 ff 42 08 <0f> 0b 83 f8 02 0f 84 ce fb ff ff e9 db RSP: 0018:ffffb5564089bd00 EFLAGS: 00000203 RAX: 0000000000000000 RBX: ffff9db385a2bf81 RCX: ffffb5564089bd18 RDX: ffff9db281110100 RSI: 0000000000000fe4 RDI: ffff9db380145400 RBP: ffff9db385a2bf80 R08: ffff9db385a2bfc0 R09: ffff9db385a2bfc2 R10: ffff9db385a6c000 R11: ffff9db385a2bf80 R12: 0000000000000000 R13: 00000000000003e8 R14: ffff9db281110100 R15: ffffffffbb006108 FS: 0000000000000000(0000) GS:ffff9db3bdcc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005602323024c8 CR3: 0000000022e0c000 CR4: 00000000000006e0 Call Trace: ring_buffer_lock_reserve+0x136/0x360 ? __do_softirq+0x287/0x2df ? __pfx_rcu_softirq_qs+0x10/0x10 trace_function+0x21/0x110 ? __pfx_rcu_softirq_qs+0x10/0x10 ? __do_softirq+0x287/0x2df function_trace_call+0xf6/0x120 0xffffffffc038f097 ? rcu_softirq_qs+0x5/0x140 rcu_softirq_qs+0x5/0x140 __do_softirq+0x287/0x2df run_ksoftirqd+0x2a/0x30 smpboot_thread_fn+0x188/0x220 ? __pfx_smpboot_thread_fn+0x10/0x10 kthread+0xe7/0x110 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2c/0x50 ---[ end trace 0000000000000000 ]--- [ crash report and test reproducer credit goes to Zheng Yejian] Link: https://lore.kernel.org/linux-trace-kernel/1676376403-16462-1-git-send-email-quic_mojha@quicinc.com Cc: Cc: stable@vger.kernel.org Fixes: 1039221cc278 ("ring-buffer: Do not disable recording when there is an iterator") Reported-by: Zheng Yejian Signed-off-by: Mukesh Ojha Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 42 +++++++++----------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 49ebb8c66268..c00463613eab 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1449,19 +1449,6 @@ static int rb_check_bpage(struct ring_buffer_per_cpu *cpu_buffer, return 0; } -/** - * rb_check_list - make sure a pointer to a list has the last bits zero - */ -static int rb_check_list(struct ring_buffer_per_cpu *cpu_buffer, - struct list_head *list) -{ - if (RB_WARN_ON(cpu_buffer, rb_list_head(list->prev) != list->prev)) - return 1; - if (RB_WARN_ON(cpu_buffer, rb_list_head(list->next) != list->next)) - return 1; - return 0; -} - /** * rb_check_pages - integrity check of buffer pages * @cpu_buffer: CPU buffer with pages to test @@ -1471,36 +1458,27 @@ static int rb_check_list(struct ring_buffer_per_cpu *cpu_buffer, */ static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) { - struct list_head *head = cpu_buffer->pages; - struct buffer_page *bpage, *tmp; + struct list_head *head = rb_list_head(cpu_buffer->pages); + struct list_head *tmp; - /* Reset the head page if it exists */ - if (cpu_buffer->head_page) - rb_set_head_page(cpu_buffer); - - rb_head_page_deactivate(cpu_buffer); - - if (RB_WARN_ON(cpu_buffer, head->next->prev != head)) - return -1; - if (RB_WARN_ON(cpu_buffer, head->prev->next != head)) + if (RB_WARN_ON(cpu_buffer, + rb_list_head(rb_list_head(head->next)->prev) != head)) return -1; - if (rb_check_list(cpu_buffer, head)) + if (RB_WARN_ON(cpu_buffer, + rb_list_head(rb_list_head(head->prev)->next) != head)) return -1; - list_for_each_entry_safe(bpage, tmp, head, list) { + for (tmp = rb_list_head(head->next); tmp != head; tmp = rb_list_head(tmp->next)) { if (RB_WARN_ON(cpu_buffer, - bpage->list.next->prev != &bpage->list)) + rb_list_head(rb_list_head(tmp->next)->prev) != tmp)) return -1; + if (RB_WARN_ON(cpu_buffer, - bpage->list.prev->next != &bpage->list)) - return -1; - if (rb_check_list(cpu_buffer, &bpage->list)) + rb_list_head(rb_list_head(tmp->prev)->next) != tmp)) return -1; } - rb_head_page_activate(cpu_buffer); - return 0; } From 40bedbf10d562d3702b3dde88e9e501058d287f1 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 19 Dec 2022 03:07:39 -0800 Subject: [PATCH 0524/1017] scsi: qla2xxx: Fix link failure in NPIV environment commit b1ae65c082f74536ec292b15766f2846f0238373 upstream. User experienced symptoms of adapter failure in NPIV environment. NPIV hosts were allowed to trigger chip reset back to back due to NPIV link state being slow to come online. Fix link failure in NPIV environment by removing NPIV host from directly being able to perform chip reset. kernel: qla2xxx [0000:04:00.1]-6009:261: Loop down - aborting ISP. kernel: qla2xxx [0000:04:00.1]-6009:262: Loop down - aborting ISP. kernel: qla2xxx [0000:04:00.1]-6009:281: Loop down - aborting ISP. kernel: qla2xxx [0000:04:00.1]-6009:285: Loop down - aborting ISP Fixes: 0d6e61bc6a4f ("[SCSI] qla2xxx: Correct various NPIV issues.") Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 419156121cb5..bc6a7cf488ba 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7145,7 +7145,7 @@ qla2x00_timer(struct timer_list *t) /* if the loop has been down for 4 minutes, reinit adapter */ if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { - if (!(vha->device_flags & DFLG_NO_CABLE)) { + if (!(vha->device_flags & DFLG_NO_CABLE) && !vha->vp_idx) { ql_log(ql_log_warn, vha, 0x6009, "Loop down - aborting ISP.\n"); From e596253113b69b4018818260bd5da40c201bee73 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 19 Dec 2022 03:07:40 -0800 Subject: [PATCH 0525/1017] scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests commit c75e6aef5039830cce5d4cf764dd204522f89e6b upstream. The following message and call trace was seen with debug kernels: DMA-API: qla2xxx 0000:41:00.0: device driver failed to check map error [device address=0x00000002a3ff38d8] [size=1024 bytes] [mapped as single] WARNING: CPU: 0 PID: 2930 at kernel/dma/debug.c:1017 check_unmap+0xf42/0x1990 Call Trace: debug_dma_unmap_page+0xc9/0x100 qla_nvme_ls_unmap+0x141/0x210 [qla2xxx] Remove DMA mapping from the driver altogether, as it is already done by FC layer. This prevents the warning. Fixes: c85ab7d9e27a ("scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests") Cc: stable@vger.kernel.org Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_nvme.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index d63ccdf6e988..695dd89be330 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -165,18 +165,6 @@ out: qla2xxx_rel_qpair_sp(sp->qpair, sp); } -static void qla_nvme_ls_unmap(struct srb *sp, struct nvmefc_ls_req *fd) -{ - if (sp->flags & SRB_DMA_VALID) { - struct srb_iocb *nvme = &sp->u.iocb_cmd; - struct qla_hw_data *ha = sp->fcport->vha->hw; - - dma_unmap_single(&ha->pdev->dev, nvme->u.nvme.cmd_dma, - fd->rqstlen, DMA_TO_DEVICE); - sp->flags &= ~SRB_DMA_VALID; - } -} - static void qla_nvme_release_ls_cmd_kref(struct kref *kref) { struct srb *sp = container_of(kref, struct srb, cmd_kref); @@ -194,7 +182,6 @@ static void qla_nvme_release_ls_cmd_kref(struct kref *kref) fd = priv->fd; - qla_nvme_ls_unmap(sp, fd); fd->done(fd, priv->comp_status); out: qla2x00_rel_sp(sp); @@ -336,13 +323,10 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, nvme->u.nvme.rsp_len = fd->rsplen; nvme->u.nvme.rsp_dma = fd->rspdma; nvme->u.nvme.timeout_sec = fd->timeout; - nvme->u.nvme.cmd_dma = dma_map_single(&ha->pdev->dev, fd->rqstaddr, - fd->rqstlen, DMA_TO_DEVICE); + nvme->u.nvme.cmd_dma = fd->rqstdma; dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma, fd->rqstlen, DMA_TO_DEVICE); - sp->flags |= SRB_DMA_VALID; - rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x700e, @@ -350,7 +334,6 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, wake_up(&sp->nvme_ls_waitq); sp->priv = NULL; priv->sp = NULL; - qla_nvme_ls_unmap(sp, fd); qla2x00_rel_sp(sp); return rval; } From 0d14ace68dd5b58365bca8991cd72f40975fe0df Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 19 Dec 2022 03:07:45 -0800 Subject: [PATCH 0526/1017] scsi: qla2xxx: Fix erroneous link down commit 3fbc74feb642deb688cc97f76d40b7287ddd4cb1 upstream. If after an adapter reset the appearance of link is not recovered, the devices are not rediscovered. This is result of a race condition between adapter reset (abort_isp) and the topology scan. During adapter reset, the ABORT_ISP_ACTIVE flag is set. Topology scan usually occurred after adapter reset. In this case, the topology scan came earlier than usual where it ran into problem due to ABORT_ISP_ACTIVE flag was still set. kernel: qla2xxx [0000:13:00.0]-1005:1: Cmd 0x6a aborted with timeout since ISP Abort is pending kernel: qla2xxx [0000:13:00.0]-28a0:1: MBX_GET_PORT_NAME failed, No FL Port. kernel: qla2xxx [0000:13:00.0]-286b:1: qla2x00_configure_loop: exiting normally. local port wwpn 51402ec0123d9a80 id 012300) kernel: qla2xxx [0000:13:00.0]-8017:1: ADAPTER RESET SUCCEEDED nexus=1:0:15. Allow adapter reset to complete before any scan can start. Cc: stable@vger.kernel.org Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_os.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index bc6a7cf488ba..e1132970f189 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -6899,9 +6899,12 @@ qla2x00_do_dpc(void *data) } } loop_resync_check: - if (test_and_clear_bit(LOOP_RESYNC_NEEDED, + if (!qla2x00_reset_active(base_vha) && + test_and_clear_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags)) { - + /* + * Allow abort_isp to complete before moving on to scanning. + */ ql_dbg(ql_dbg_dpc, base_vha, 0x400f, "Loop resync scheduled.\n"); From d68937dfc73ee7f61cf3424fa3225be93cacaa00 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 28 Nov 2020 15:27:21 -0800 Subject: [PATCH 0527/1017] scsi: ses: Don't attach if enclosure has no components commit 3fe97ff3d94934649abb0652028dd7296170c8d0 upstream. An enclosure with no components can't usefully be operated by the driver (since effectively it has nothing to manage), so report the problem and don't attach. Not attaching also fixes an oops which could occur if the driver tries to manage a zero component enclosure. [mkp: Switched to KERN_WARNING since this scenario is common] Link: https://lore.kernel.org/r/c5deac044ac409e32d9ad9968ce0dcbc996bfc7a.camel@linux.ibm.com Cc: stable@vger.kernel.org Reported-by: Ding Hui Signed-off-by: James Bottomley Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ses.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 0a1734f34587..b61d7e490606 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -704,6 +704,12 @@ static int ses_intf_add(struct device *cdev, type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) components += type_ptr[1]; } + + if (components == 0) { + sdev_printk(KERN_WARNING, sdev, "enclosure has no enumerated components\n"); + goto err_free; + } + ses_dev->page1 = buf; ses_dev->page1_len = len; buf = NULL; From e4dd25da784b2e07dbfbf04509afa4c5a1375227 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Thu, 2 Feb 2023 17:24:48 +0100 Subject: [PATCH 0528/1017] scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process() commit 9b4f5028e493cb353a5c8f5c45073eeea0303abd upstream. A fix for: BUG: KASAN: slab-out-of-bounds in ses_enclosure_data_process+0x949/0xe30 [ses] Read of size 1 at addr ffff88a1b043a451 by task systemd-udevd/3271 Checking after (and before in next loop) addl_desc_ptr[1] is sufficient, we expect the size to be sanitized before first access to addl_desc_ptr[1]. Make sure we don't walk beyond end of page. Link: https://lore.kernel.org/r/20230202162451.15346-2-thenzl@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Tomas Henzl Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ses.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index b61d7e490606..4739c03b4e1d 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -603,9 +603,11 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, /* these elements are optional */ type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT || type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT || - type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) + type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) { addl_desc_ptr += addl_desc_ptr[1] + 2; - + if (addl_desc_ptr + 1 >= ses_dev->page10 + ses_dev->page10_len) + addl_desc_ptr = NULL; + } } } kfree(buf); From 2ecd344173a5663d523433819da0484cb268b186 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Thu, 2 Feb 2023 17:24:49 +0100 Subject: [PATCH 0529/1017] scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses commit db95d4df71cb55506425b6e4a5f8d68e3a765b63 upstream. Sanitize possible addl_desc_ptr out-of-bounds accesses in ses_enclosure_data_process(). Link: https://lore.kernel.org/r/20230202162451.15346-3-thenzl@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Tomas Henzl Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ses.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 4739c03b4e1d..4b66f9aec0f4 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -433,8 +433,8 @@ int ses_match_host(struct enclosure_device *edev, void *data) } #endif /* 0 */ -static void ses_process_descriptor(struct enclosure_component *ecomp, - unsigned char *desc) +static int ses_process_descriptor(struct enclosure_component *ecomp, + unsigned char *desc, int max_desc_len) { int eip = desc[0] & 0x10; int invalid = desc[0] & 0x80; @@ -445,22 +445,32 @@ static void ses_process_descriptor(struct enclosure_component *ecomp, unsigned char *d; if (invalid) - return; + return 0; switch (proto) { case SCSI_PROTOCOL_FCP: if (eip) { + if (max_desc_len <= 7) + return 1; d = desc + 4; slot = d[3]; } break; case SCSI_PROTOCOL_SAS: + if (eip) { + if (max_desc_len <= 27) + return 1; d = desc + 4; slot = d[3]; d = desc + 8; - } else + } else { + if (max_desc_len <= 23) + return 1; d = desc + 4; + } + + /* only take the phy0 addr */ addr = (u64)d[12] << 56 | (u64)d[13] << 48 | @@ -477,6 +487,8 @@ static void ses_process_descriptor(struct enclosure_component *ecomp, } ecomp->slot = slot; scomp->addr = addr; + + return 0; } struct efd { @@ -549,7 +561,7 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, /* skip past overall descriptor */ desc_ptr += len + 4; } - if (ses_dev->page10) + if (ses_dev->page10 && ses_dev->page10_len > 9) addl_desc_ptr = ses_dev->page10 + 8; type_ptr = ses_dev->page1_types; components = 0; @@ -557,6 +569,7 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, for (j = 0; j < type_ptr[1]; j++) { char *name = NULL; struct enclosure_component *ecomp; + int max_desc_len; if (desc_ptr) { if (desc_ptr >= buf + page7_len) { @@ -583,10 +596,14 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, ecomp = &edev->component[components++]; if (!IS_ERR(ecomp)) { - if (addl_desc_ptr) - ses_process_descriptor( - ecomp, - addl_desc_ptr); + if (addl_desc_ptr) { + max_desc_len = ses_dev->page10_len - + (addl_desc_ptr - ses_dev->page10); + if (ses_process_descriptor(ecomp, + addl_desc_ptr, + max_desc_len)) + addl_desc_ptr = NULL; + } if (create) enclosure_component_register( ecomp); From c315560e3ef77c1d822249f1743e647dc9c9912a Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Thu, 2 Feb 2023 17:24:50 +0100 Subject: [PATCH 0530/1017] scsi: ses: Fix possible desc_ptr out-of-bounds accesses commit 801ab13d50cf3d26170ee073ea8bb4eececb76ab upstream. Sanitize possible desc_ptr out-of-bounds accesses in ses_enclosure_data_process(). Link: https://lore.kernel.org/r/20230202162451.15346-4-thenzl@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Tomas Henzl Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ses.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 4b66f9aec0f4..77f4322e2f71 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -572,15 +572,19 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, int max_desc_len; if (desc_ptr) { - if (desc_ptr >= buf + page7_len) { + if (desc_ptr + 3 >= buf + page7_len) { desc_ptr = NULL; } else { len = (desc_ptr[2] << 8) + desc_ptr[3]; desc_ptr += 4; - /* Add trailing zero - pushes into - * reserved space */ - desc_ptr[len] = '\0'; - name = desc_ptr; + if (desc_ptr + len > buf + page7_len) + desc_ptr = NULL; + else { + /* Add trailing zero - pushes into + * reserved space */ + desc_ptr[len] = '\0'; + name = desc_ptr; + } } } if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || From 8f9542cad6c27297c8391de3a659f0b7948495d0 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Thu, 2 Feb 2023 17:24:51 +0100 Subject: [PATCH 0531/1017] scsi: ses: Fix slab-out-of-bounds in ses_intf_remove() commit 578797f0c8cbc2e3ec5fc0dab87087b4c7073686 upstream. A fix for: BUG: KASAN: slab-out-of-bounds in ses_intf_remove+0x23f/0x270 [ses] Read of size 8 at addr ffff88a10d32e5d8 by task rmmod/12013 When edev->components is zero, accessing edev->component[0] members is wrong. Link: https://lore.kernel.org/r/20230202162451.15346-5-thenzl@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Tomas Henzl Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ses.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 77f4322e2f71..1707d6d144d2 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -856,7 +856,8 @@ static void ses_intf_remove_enclosure(struct scsi_device *sdev) kfree(ses_dev->page2); kfree(ses_dev); - kfree(edev->component[0].scratch); + if (edev->components) + kfree(edev->component[0].scratch); put_device(&edev->edev); enclosure_unregister(edev); From 285d8390d98e2a3e44d79f391e09cc7047a50579 Mon Sep 17 00:00:00 2001 From: Andy Chiu Date: Mon, 6 Feb 2023 04:04:40 -0500 Subject: [PATCH 0532/1017] riscv: jump_label: Fixup unaligned arch_static_branch function commit 9ddfc3cd806081ce1f6c9c2f988cbb031f35d28f upstream. Runtime code patching must be done at a naturally aligned address, or we may execute on a partial instruction. We have encountered problems traced back to static jump functions during the test. We switched the tracer randomly for every 1~5 seconds on a dual-core QEMU setup and found the kernel sucking at a static branch where it jumps to itself. The reason is that the static branch was 2-byte but not 4-byte aligned. Then, the kernel would patch the instruction, either J or NOP, with two half-word stores if the machine does not have efficient unaligned accesses. Thus, moments exist where half of the NOP mixes with the other half of the J when transitioning the branch. In our particular case, on a little-endian machine, the upper half of the NOP was mixed with the lower part of the J when enabling the branch, resulting in a jump that jumped to itself. Conversely, it would result in a HINT instruction when disabling the branch, but it might not be observable. ARM64 does not have this problem since all instructions must be 4-byte aligned. Fixes: ebc00dde8a97 ("riscv: Add jump-label implementation") Link: https://lore.kernel.org/linux-riscv/20220913094252.3555240-6-andy.chiu@sifive.com/ Reviewed-by: Greentime Hu Signed-off-by: Andy Chiu Signed-off-by: Guo Ren Link: https://lore.kernel.org/r/20230206090440.1255001-1-guoren@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Greg Kroah-Hartman --- arch/riscv/include/asm/jump_label.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/riscv/include/asm/jump_label.h b/arch/riscv/include/asm/jump_label.h index 38af2ec7b9bf..729991e8f782 100644 --- a/arch/riscv/include/asm/jump_label.h +++ b/arch/riscv/include/asm/jump_label.h @@ -18,6 +18,7 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { asm_volatile_goto( + " .align 2 \n\t" " .option push \n\t" " .option norelax \n\t" " .option norvc \n\t" @@ -39,6 +40,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) { asm_volatile_goto( + " .align 2 \n\t" " .option push \n\t" " .option norelax \n\t" " .option norvc \n\t" From d219b19e1f26997a4c864ad2d0931fd859967e44 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 15 Jan 2023 09:20:31 +0100 Subject: [PATCH 0533/1017] PCI/PM: Observe reset delay irrespective of bridge_d3 commit 8ef0217227b42e2c34a18de316cee3da16c9bf1e upstream. If a PCI bridge is suspended to D3cold upon entering system sleep, resuming it entails a Fundamental Reset per PCIe r6.0 sec 5.8. The delay prescribed after a Fundamental Reset in PCIe r6.0 sec 6.6.1 is sought to be observed by: pci_pm_resume_noirq() pci_pm_bridge_power_up_actions() pci_bridge_wait_for_secondary_bus() However, pci_bridge_wait_for_secondary_bus() bails out if the bridge_d3 flag is not set. That flag indicates whether a bridge is allowed to suspend to D3cold at *runtime*. Hence *no* delay is observed on resume from system sleep if runtime D3cold is forbidden. That doesn't make any sense, so drop the bridge_d3 check from pci_bridge_wait_for_secondary_bus(). The purpose of the bridge_d3 check was probably to avoid delays if a bridge remained in D0 during suspend. However the sole caller of pci_bridge_wait_for_secondary_bus(), pci_pm_bridge_power_up_actions(), is only invoked if the previous power state was D3cold. Hence the additional bridge_d3 check seems superfluous. Fixes: ad9001f2f411 ("PCI/PM: Add missing link delays required by the PCIe spec") Link: https://lore.kernel.org/r/eb37fa345285ec8bacabbf06b020b803f77bdd3d.1673769517.git.lukas@wunner.de Tested-by: Ravi Kishore Koppuravuri Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg Reviewed-by: Kuppuswamy Sathyanarayanan Cc: stable@vger.kernel.org # v5.5+ Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 262577c81d30..845851e23352 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4808,7 +4808,7 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) if (pci_dev_is_disconnected(dev)) return; - if (!pci_is_bridge(dev) || !dev->bridge_d3) + if (!pci_is_bridge(dev)) return; down_read(&pci_bus_sem); From 88b51c6a6d57f90638d54e28e58dca3f73c31bca Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Fri, 20 Jan 2023 10:19:02 +0100 Subject: [PATCH 0534/1017] PCI: hotplug: Allow marking devices as disconnected during bind/unbind commit 74ff8864cc842be994853095dba6db48e716400a upstream. On surprise removal, pciehp_unconfigure_device() and acpiphp's trim_stale_devices() call pci_dev_set_disconnected() to mark removed devices as permanently offline. Thereby, the PCI core and drivers know to skip device accesses. However pci_dev_set_disconnected() takes the device_lock and thus waits for a concurrent driver bind or unbind to complete. As a result, the driver's ->probe and ->remove hooks have no chance to learn that the device is gone. That doesn't make any sense, so drop the device_lock and instead use atomic xchg() and cmpxchg() operations to update the device state. As a byproduct, an AB-BA deadlock reported by Anatoli is fixed which occurs on surprise removal with AER concurrently performing a bus reset. AER bus reset: INFO: task irq/26-aerdrv:95 blocked for more than 120 seconds. Tainted: G W 6.2.0-rc3-custom-norework-jan11+ schedule rwsem_down_write_slowpath down_write_nested pciehp_reset_slot # acquires reset_lock pci_reset_hotplug_slot pci_slot_reset # acquires device_lock pci_bus_error_reset aer_root_reset pcie_do_recovery aer_process_err_devices aer_isr pciehp surprise removal: INFO: task irq/26-pciehp:96 blocked for more than 120 seconds. Tainted: G W 6.2.0-rc3-custom-norework-jan11+ schedule_preempt_disabled __mutex_lock mutex_lock_nested pci_dev_set_disconnected # acquires device_lock pci_walk_bus pciehp_unconfigure_device pciehp_disable_slot pciehp_handle_presence_or_link_change pciehp_ist # acquires reset_lock Link: https://bugzilla.kernel.org/show_bug.cgi?id=215590 Fixes: a6bd101b8f84 ("PCI: Unify device inaccessible") Link: https://lore.kernel.org/r/3dc88ea82bdc0e37d9000e413d5ebce481cbd629.1674205689.git.lukas@wunner.de Reported-by: Anatoli Antonovitch Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v4.20+ Cc: Keith Busch Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.h | 43 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0039460c6ab0..9197d7362731 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -351,53 +351,36 @@ struct pci_sriov { * @dev - pci device to set new error_state * @new - the state we want dev to be in * - * Must be called with device_lock held. + * If the device is experiencing perm_failure, it has to remain in that state. + * Any other transition is allowed. * * Returns true if state has been changed to the requested state. */ static inline bool pci_dev_set_io_state(struct pci_dev *dev, pci_channel_state_t new) { - bool changed = false; + pci_channel_state_t old; - device_lock_assert(&dev->dev); switch (new) { case pci_channel_io_perm_failure: - switch (dev->error_state) { - case pci_channel_io_frozen: - case pci_channel_io_normal: - case pci_channel_io_perm_failure: - changed = true; - break; - } - break; + xchg(&dev->error_state, pci_channel_io_perm_failure); + return true; case pci_channel_io_frozen: - switch (dev->error_state) { - case pci_channel_io_frozen: - case pci_channel_io_normal: - changed = true; - break; - } - break; + old = cmpxchg(&dev->error_state, pci_channel_io_normal, + pci_channel_io_frozen); + return old != pci_channel_io_perm_failure; case pci_channel_io_normal: - switch (dev->error_state) { - case pci_channel_io_frozen: - case pci_channel_io_normal: - changed = true; - break; - } - break; + old = cmpxchg(&dev->error_state, pci_channel_io_frozen, + pci_channel_io_normal); + return old != pci_channel_io_perm_failure; + default: + return false; } - if (changed) - dev->error_state = new; - return changed; } static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused) { - device_lock(&dev->dev); pci_dev_set_io_state(dev, pci_channel_io_perm_failure); - device_unlock(&dev->dev); return 0; } From 691a8e26de7809fe15284713c2338c93ffe0345c Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Sat, 28 Jan 2023 10:39:51 +0900 Subject: [PATCH 0535/1017] PCI: Avoid FLR for AMD FCH AHCI adapters commit 63ba51db24ed1b8f8088a897290eb6c036c5435d upstream. PCI passthrough to VMs does not work with AMD FCH AHCI adapters: the guest OS fails to correctly probe devices attached to the controller due to FIS communication failures: ata4: softreset failed (1st FIS failed) ... ata4.00: qc timeout after 5000 msecs (cmd 0xec) ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4) Forcing the "bus" reset method before unbinding & binding the adapter to the vfio-pci driver solves this issue, e.g.: echo "bus" > /sys/bus/pci/devices//reset_method gives a working guest OS, indicating that the default FLR reset method doesn't work correctly. Apply quirk_no_flr() to AMD FCH AHCI devices to work around this issue. Link: https://lore.kernel.org/r/20230128013951.523247-1-damien.lemoal@opensource.wdc.com Reported-by: Niklas Cassel Signed-off-by: Damien Le Moal Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index fb2e52fd01b3..f30c42f0ac31 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5302,6 +5302,7 @@ static void quirk_no_flr(struct pci_dev *dev) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1487, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x148c, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x149c, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x7901, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_no_flr); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_no_flr); From 5a271242716846cc016736fb76be2b40ee49b0c3 Mon Sep 17 00:00:00 2001 From: Steve Sistare Date: Tue, 31 Jan 2023 08:58:04 -0800 Subject: [PATCH 0536/1017] vfio/type1: prevent underflow of locked_vm via exec() commit 046eca5018f8a5dd1dc2cedf87fb5843b9ea3026 upstream. When a vfio container is preserved across exec, the task does not change, but it gets a new mm with locked_vm=0, and loses the count from existing dma mappings. If the user later unmaps a dma mapping, locked_vm underflows to a large unsigned value, and a subsequent dma map request fails with ENOMEM in __account_locked_vm. To avoid underflow, grab and save the mm at the time a dma is mapped. Use that mm when adjusting locked_vm, rather than re-acquiring the saved task's mm, which may have changed. If the saved mm is dead, do nothing. locked_vm is incremented for existing mappings in a subsequent patch. Fixes: 73fa0d10d077 ("vfio: Type1 IOMMU implementation") Cc: stable@vger.kernel.org Signed-off-by: Steve Sistare Reviewed-by: Kevin Tian Reviewed-by: Jason Gunthorpe Link: https://lore.kernel.org/r/1675184289-267876-3-git-send-email-steven.sistare@oracle.com Signed-off-by: Alex Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/vfio_iommu_type1.c | 41 +++++++++++---------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index ce50ca9a320c..ec1428dbdf9d 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -96,6 +96,7 @@ struct vfio_dma { struct task_struct *task; struct rb_root pfn_list; /* Ex-user pinned pfn list */ unsigned long *bitmap; + struct mm_struct *mm; }; struct vfio_batch { @@ -391,8 +392,8 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async) if (!npage) return 0; - mm = async ? get_task_mm(dma->task) : dma->task->mm; - if (!mm) + mm = dma->mm; + if (async && !mmget_not_zero(mm)) return -ESRCH; /* process exited */ ret = mmap_write_lock_killable(mm); @@ -666,8 +667,8 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr, struct mm_struct *mm; int ret; - mm = get_task_mm(dma->task); - if (!mm) + mm = dma->mm; + if (!mmget_not_zero(mm)) return -ENODEV; ret = vaddr_get_pfns(mm, vaddr, 1, dma->prot, pfn_base, pages); @@ -677,7 +678,7 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr, ret = 0; if (do_accounting && !is_invalid_reserved_pfn(*pfn_base)) { - ret = vfio_lock_acct(dma, 1, true); + ret = vfio_lock_acct(dma, 1, false); if (ret) { put_pfn(*pfn_base, dma->prot); if (ret == -ENOMEM) @@ -1031,6 +1032,7 @@ static void vfio_remove_dma(struct vfio_iommu *iommu, struct vfio_dma *dma) vfio_unmap_unpin(iommu, dma, true); vfio_unlink_dma(iommu, dma); put_task_struct(dma->task); + mmdrop(dma->mm); vfio_dma_bitmap_free(dma); kfree(dma); iommu->dma_avail++; @@ -1452,29 +1454,15 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, * against the locked memory limit and we need to be able to do both * outside of this call path as pinning can be asynchronous via the * external interfaces for mdev devices. RLIMIT_MEMLOCK requires a - * task_struct and VM locked pages requires an mm_struct, however - * holding an indefinite mm reference is not recommended, therefore we - * only hold a reference to a task. We could hold a reference to - * current, however QEMU uses this call path through vCPU threads, - * which can be killed resulting in a NULL mm and failure in the unmap - * path when called via a different thread. Avoid this problem by - * using the group_leader as threads within the same group require - * both CLONE_THREAD and CLONE_VM and will therefore use the same - * mm_struct. - * - * Previously we also used the task for testing CAP_IPC_LOCK at the - * time of pinning and accounting, however has_capability() makes use - * of real_cred, a copy-on-write field, so we can't guarantee that it - * matches group_leader, or in fact that it might not change by the - * time it's evaluated. If a process were to call MAP_DMA with - * CAP_IPC_LOCK but later drop it, it doesn't make sense that they - * possibly see different results for an iommu_mapped vfio_dma vs - * externally mapped. Therefore track CAP_IPC_LOCK in vfio_dma at the - * time of calling MAP_DMA. + * task_struct. Save the group_leader so that all DMA tracking uses + * the same task, to make debugging easier. VM locked pages requires + * an mm_struct, so grab the mm in case the task dies. */ get_task_struct(current->group_leader); dma->task = current->group_leader; dma->lock_cap = capable(CAP_IPC_LOCK); + dma->mm = current->mm; + mmgrab(dma->mm); dma->pfn_list = RB_ROOT; @@ -2998,9 +2986,8 @@ static int vfio_iommu_type1_dma_rw_chunk(struct vfio_iommu *iommu, !(dma->prot & IOMMU_READ)) return -EPERM; - mm = get_task_mm(dma->task); - - if (!mm) + mm = dma->mm; + if (!mmget_not_zero(mm)) return -EPERM; if (kthread) From 266864c1e0edb4034f6346b5309f0e68494bcfb3 Mon Sep 17 00:00:00 2001 From: Mavroudis Chatzilaridis Date: Wed, 1 Feb 2023 18:51:25 +0000 Subject: [PATCH 0537/1017] drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv commit 5e438bf7f9a1705ebcae5fa89cdbfbc6932a7871 upstream. This laptop uses inverted backlight PWM. Thus, without this quirk, backlight brightness decreases as the brightness value increases and vice versa. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8013 Cc: stable@vger.kernel.org Signed-off-by: Mavroudis Chatzilaridis Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230201184947.8835-1-mavchatz@protonmail.com (cherry picked from commit 83e7d6fd330d413cb2064e680ffea91b0512a520) Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/display/intel_quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c index 8eb1842f14ce..b4e74c86fae7 100644 --- a/drivers/gpu/drm/i915/display/intel_quirks.c +++ b/drivers/gpu/drm/i915/display/intel_quirks.c @@ -159,6 +159,8 @@ static struct intel_quirk intel_quirks[] = { /* ECS Liva Q2 */ { 0x3185, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time }, { 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time }, + /* HP Notebook - 14-r206nv */ + { 0x0f31, 0x103c, 0x220f, quirk_invert_brightness }, }; void intel_init_quirks(struct drm_i915_private *i915) From 1f064aaa81af466ea5da53181debe9c82aeed4be Mon Sep 17 00:00:00 2001 From: Mark Hawrylak Date: Sun, 19 Feb 2023 16:02:00 +1100 Subject: [PATCH 0538/1017] drm/radeon: Fix eDP for single-display iMac11,2 commit 05eacc198c68cbb35a7281ce4011f8899ee1cfb8 upstream. Apple iMac11,2 (mid 2010) also with Radeon HD-4670 that has the same issue as iMac10,1 (late 2009) where the internal eDP panel stays dark on driver load. This patch treats iMac11,2 the same as iMac10,1, so the eDP panel stays active. Additional steps: Kernel boot parameter radeon.nomodeset=0 required to keep the eDP panel active. This patch is an extension of commit 564d8a2cf3ab ("drm/radeon: Fix eDP for single-display iMac10,1 (v2)") Link: https://lore.kernel.org/all/lsq.1507553064.833262317@decadent.org.uk/ Signed-off-by: Mark Hawrylak Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/atombios_encoders.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 12aa7877a625..8cca58f25c0f 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -2191,11 +2191,12 @@ int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder, int fe_idx) /* * On DCE32 any encoder can drive any block so usually just use crtc id, - * but Apple thinks different at least on iMac10,1, so there use linkb, + * but Apple thinks different at least on iMac10,1 and iMac11,2, so there use linkb, * otherwise the internal eDP panel will stay dark. */ if (ASIC_IS_DCE32(rdev)) { - if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1")) + if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1") || + dmi_match(DMI_PRODUCT_NAME, "iMac11,2")) enc_idx = (dig->linkb) ? 1 : 0; else enc_idx = radeon_crtc->crtc_id; From 64a99c0ac6f8b714960a71d34a91a54acb4117e4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 4 Jan 2023 12:05:16 +0200 Subject: [PATCH 0539/1017] drm/edid: fix AVI infoframe aspect ratio handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1cbc1f0d324ba6c4d1b10ac6362b5e0b029f63d5 upstream. We try to avoid sending VICs defined in the later specs in AVI infoframes to sinks that conform to the earlier specs, to not upset them, and use 0 for the VIC instead. However, we do this detection and conversion to 0 too early, as we'll need the actual VIC to figure out the aspect ratio. In particular, for a mode with 64:27 aspect ratio, 0 for VIC fails the AVI infoframe generation altogether with -EINVAL. Separate the VIC lookup from the "filtering", and postpone the filtering, to use the proper VIC for aspect ratio handling, and the 0 VIC for the infoframe video code as needed. Reported-by: William Tseng Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/6153 References: https://lore.kernel.org/r/20220920062316.43162-1-william.tseng@intel.com Cc: Cc: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/c3e78cc6d01ed237f71ad0038826b08d83d75eef.1672826282.git.jani.nikula@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_edid.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 4334e466b4e0..39eb39e78d7a 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -5560,8 +5560,6 @@ static u8 drm_mode_hdmi_vic(const struct drm_connector *connector, static u8 drm_mode_cea_vic(const struct drm_connector *connector, const struct drm_display_mode *mode) { - u8 vic; - /* * HDMI spec says if a mode is found in HDMI 1.4b 4K modes * we should send its VIC in vendor infoframes, else send the @@ -5571,13 +5569,18 @@ static u8 drm_mode_cea_vic(const struct drm_connector *connector, if (drm_mode_hdmi_vic(connector, mode)) return 0; - vic = drm_match_cea_mode(mode); + return drm_match_cea_mode(mode); +} - /* - * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but - * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we - * have to make sure we dont break HDMI 1.4 sinks. - */ +/* + * Avoid sending VICs defined in HDMI 2.0 in AVI infoframes to sinks that + * conform to HDMI 1.4. + * + * HDMI 1.4 (CTA-861-D) VIC range: [1..64] + * HDMI 2.0 (CTA-861-F) VIC range: [1..107] + */ +static u8 vic_for_avi_infoframe(const struct drm_connector *connector, u8 vic) +{ if (!is_hdmi2_sink(connector) && vic > 64) return 0; @@ -5653,7 +5656,7 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, picture_aspect = HDMI_PICTURE_ASPECT_NONE; } - frame->video_code = vic; + frame->video_code = vic_for_avi_infoframe(connector, vic); frame->picture_aspect = picture_aspect; frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN; From a2a1e3f4ed5bf698b41f0aeddfdb931bb0718168 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 13 Jan 2023 17:44:41 +0100 Subject: [PATCH 0540/1017] arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY commit 100d9c94ccf15b02742c326cd04f422ab729153b upstream. Serdes register space sizes are incorrect, update them to match the actual sizes from downstream QCA 5.4 kernel. Fixes: 942bcd33ed45 ("arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes") Signed-off-by: Robert Marko Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230113164449.906002-1-robimarko@gmail.com Signed-off-by: Greg Kroah-Hartman --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index 25f78c71e010..e191a7bc532b 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -213,9 +213,9 @@ status = "disabled"; pcie_phy1: phy@8e200 { - reg = <0x8e200 0x16c>, + reg = <0x8e200 0x130>, <0x8e400 0x200>, - <0x8e800 0x4f4>; + <0x8e800 0x1f8>; #phy-cells = <0>; #clock-cells = <0>; clocks = <&gcc GCC_PCIE1_PIPE_CLK>; From 844da3901304d6946c42edc89b793cc07981683b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 15 Dec 2022 17:55:42 +0100 Subject: [PATCH 0541/1017] wifi: ath9k: use proper statements in conditionals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b7dc753fe33a707379e2254317794a4dad6c0fe2 upstream. A previous cleanup patch accidentally broke some conditional expressions by replacing the safe "do {} while (0)" constructs with empty macros. gcc points this out when extra warnings are enabled: drivers/net/wireless/ath/ath9k/hif_usb.c: In function 'ath9k_skb_queue_complete': drivers/net/wireless/ath/ath9k/hif_usb.c:251:57: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body] 251 | TX_STAT_INC(hif_dev, skb_failed); Make both sets of macros proper expressions again. Fixes: d7fc76039b74 ("ath9k: htc: clean up statistics macros") Signed-off-by: Arnd Bergmann Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20221215165553.1950307-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/htc.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 30f0765fb9fd..237f4ec2cffd 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -327,9 +327,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) } #ifdef CONFIG_ATH9K_HTC_DEBUGFS -#define __STAT_SAFE(hif_dev, expr) ((hif_dev)->htc_handle->drv_priv ? (expr) : 0) -#define CAB_STAT_INC(priv) ((priv)->debug.tx_stats.cab_queued++) -#define TX_QSTAT_INC(priv, q) ((priv)->debug.tx_stats.queue_stats[q]++) +#define __STAT_SAFE(hif_dev, expr) do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0) +#define CAB_STAT_INC(priv) do { ((priv)->debug.tx_stats.cab_queued++); } while (0) +#define TX_QSTAT_INC(priv, q) do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0) #define TX_STAT_INC(hif_dev, c) \ __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++) @@ -378,10 +378,10 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw, struct ethtool_stats *stats, u64 *data); #else -#define TX_STAT_INC(hif_dev, c) -#define TX_STAT_ADD(hif_dev, c, a) -#define RX_STAT_INC(hif_dev, c) -#define RX_STAT_ADD(hif_dev, c, a) +#define TX_STAT_INC(hif_dev, c) do { } while (0) +#define TX_STAT_ADD(hif_dev, c, a) do { } while (0) +#define RX_STAT_INC(hif_dev, c) do { } while (0) +#define RX_STAT_ADD(hif_dev, c, a) do { } while (0) #define CAB_STAT_INC(priv) #define TX_QSTAT_INC(priv, c) From 50afcd5316f263d42fdef0b25c2104a2609eb535 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 10 Jan 2023 08:46:53 +0000 Subject: [PATCH 0542/1017] pinctrl: rockchip: fix mux route data for rk3568 commit 431d1531466033909d2e8c754a7dc3704b70843f upstream. IO mux selection is configured in PMU_GRF_SOC_CON4 and GRF_IOFUNC_SEL0-5 regs on RK3568. pwm0-2 is configured in PMU_GRF reg and the rest is configured in GRF_IOFUNC regs according to TRM [1]. Update mux route data to reflect this and use proper detection pin for UART1 IO mux M1. This fixes HDMITX IO mux M1 selection and makes it possible to enable HDMI CEC on my Radxa ROCK 3 Model A v1.31 board. [1] http://opensource.rock-chips.com/images/2/26/Rockchip_RK3568_TRM_Part1_V1.3-20220930P.PDF Fixes: c0dadc0e47a8 ("pinctrl: rockchip: add support for rk3568") Signed-off-by: Jonas Karlman Link: https://lore.kernel.org/r/20230110084636.1141740-1-jonas@kwiboo.se Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/pinctrl-rockchip.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 764c96ddfc76..11791afeaf82 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -954,19 +954,19 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ - RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ - RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ @@ -992,7 +992,7 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ @@ -1001,8 +1001,8 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ - RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 4, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ @@ -1032,13 +1032,13 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ - RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ - RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ - RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ }; From f8ac5467e1f3f773326454bea793172ed7cff5be Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 10 Jan 2023 17:29:58 +0000 Subject: [PATCH 0543/1017] pinctrl: rockchip: fix reading pull type on rk3568 commit 31b62a98de42cf65d76e4dcfb571af067d27d83a upstream. When reading pinconf-pins from debugfs it fails to get the configured pull type on RK3568, "unsupported pinctrl type" error messages is also reported. Fix this by adding support for RK3568 in rockchip_get_pull, including a reverse of the pull-up value swap applied in rockchip_set_pull so that pull-up is correctly reported in pinconf-pins. Also update the workaround comment to reflect affected pins, GPIO0_D3-D6. Fixes: c0dadc0e47a8 ("pinctrl: rockchip: add support for rk3568") Signed-off-by: Jonas Karlman Reviewed-by: Heiko Stuebner Reviewed-by: Jianqun Xu Link: https://lore.kernel.org/r/20230110172955.1258840-1-jonas@kwiboo.se Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/pinctrl-rockchip.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 11791afeaf82..2a454098eaaa 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2045,9 +2045,18 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) case RK3308: case RK3368: case RK3399: + case RK3568: pull_type = bank->pull_type[pin_num / 8]; data >>= bit; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; + /* + * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6, + * where that pull up value becomes 3. + */ + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { + if (data == 3) + data = 1; + } return rockchip_pull_list[pull_type][data]; default: @@ -2101,7 +2110,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, } } /* - * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, + * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6, * where that pull up value becomes 3. */ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { From 322df540ba0590103839f94f441818f5696b8b00 Mon Sep 17 00:00:00 2001 From: Dmitry Goncharov Date: Mon, 5 Dec 2022 16:48:19 -0500 Subject: [PATCH 0544/1017] kbuild: Port silent mode detection to future gnu make. commit 4bf73588165ba7d32131a043775557a54b6e1db5 upstream. Port silent mode detection to the future (post make-4.4) versions of gnu make. Makefile contains the following piece of make code to detect if option -s is specified on the command line. ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) This code is executed by make at parse time and assumes that MAKEFLAGS does not contain command line variable definitions. Currently if the user defines a=s on the command line, then at build only time MAKEFLAGS contains " -- a=s". However, starting with commit dc2d963989b96161472b2cd38cef5d1f4851ea34 MAKEFLAGS contains command line definitions at both parse time and build time. This '-s' detection code then confuses a command line variable definition which contains letter 's' with option -s. $ # old make $ make net/wireless/ocb.o a=s CALL scripts/checksyscalls.sh DESCEND objtool $ # this a new make which defines makeflags at parse time $ ~/src/gmake/make/l64/make net/wireless/ocb.o a=s $ We can see here that the letter 's' from 'a=s' was confused with -s. This patch checks for presence of -s using a method recommended by the make manual here https://www.gnu.org/software/make/manual/make.html#Testing-Flags. Link: https://lists.gnu.org/archive/html/bug-make/2022-11/msg00190.html Reported-by: Jan Palus Signed-off-by: Dmitry Goncharov Signed-off-by: Masahiro Yamada Signed-off-by: Greg Kroah-Hartman --- Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 447ed158d6bc..5ca862041b71 100644 --- a/Makefile +++ b/Makefile @@ -93,9 +93,16 @@ endif # If the user is running make -s (silent mode), suppress echoing of # commands +# make-4.0 (and later) keep single letter options in the 1st word of MAKEFLAGS. -ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) - quiet=silent_ +ifeq ($(filter 3.%,$(MAKE_VERSION)),) +silence:=$(findstring s,$(firstword -$(MAKEFLAGS))) +else +silence:=$(findstring s,$(filter-out --%,$(MAKEFLAGS))) +endif + +ifeq ($(silence),s) +quiet=silent_ endif export quiet Q KBUILD_VERBOSE From 18c3fa7a7fdbb4d21dafc8a7710ae2c1680930f6 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Tue, 14 Feb 2023 08:49:14 -0500 Subject: [PATCH 0545/1017] net/sched: Retire tcindex classifier commit 8c710f75256bb3cf05ac7b1672c82b92c43f3d28 upstream. The tcindex classifier has served us well for about a quarter of a century but has not been getting much TLC due to lack of known users. Most recently it has become easy prey to syzkaller. For this reason, we are retiring it. Signed-off-by: Jamal Hadi Salim Acked-by: Jiri Pirko Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- net/sched/Kconfig | 11 - net/sched/Makefile | 1 - net/sched/cls_tcindex.c | 756 ---------------------------------------- 3 files changed, 768 deletions(-) delete mode 100644 net/sched/cls_tcindex.c diff --git a/net/sched/Kconfig b/net/sched/Kconfig index bc4e5da76fa6..697522371914 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -503,17 +503,6 @@ config NET_CLS_BASIC To compile this code as a module, choose M here: the module will be called cls_basic. -config NET_CLS_TCINDEX - tristate "Traffic-Control Index (TCINDEX)" - select NET_CLS - help - Say Y here if you want to be able to classify packets based on - traffic control indices. You will want this feature if you want - to implement Differentiated Services together with DSMARK. - - To compile this code as a module, choose M here: the - module will be called cls_tcindex. - config NET_CLS_ROUTE4 tristate "Routing decision (ROUTE)" depends on INET diff --git a/net/sched/Makefile b/net/sched/Makefile index 66bbf9a98f9e..4311fdb21119 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -69,7 +69,6 @@ obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o obj-$(CONFIG_NET_CLS_FW) += cls_fw.o obj-$(CONFIG_NET_CLS_RSVP) += cls_rsvp.o -obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o obj-$(CONFIG_NET_CLS_BASIC) += cls_basic.o obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c deleted file mode 100644 index 2c0c95204cb5..000000000000 --- a/net/sched/cls_tcindex.c +++ /dev/null @@ -1,756 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * net/sched/cls_tcindex.c Packet classifier for skb->tc_index - * - * Written 1998,1999 by Werner Almesberger, EPFL ICA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Passing parameters to the root seems to be done more awkwardly than really - * necessary. At least, u32 doesn't seem to use such dirty hacks. To be - * verified. FIXME. - */ - -#define PERFECT_HASH_THRESHOLD 64 /* use perfect hash if not bigger */ -#define DEFAULT_HASH_SIZE 64 /* optimized for diffserv */ - - -struct tcindex_data; - -struct tcindex_filter_result { - struct tcf_exts exts; - struct tcf_result res; - struct tcindex_data *p; - struct rcu_work rwork; -}; - -struct tcindex_filter { - u16 key; - struct tcindex_filter_result result; - struct tcindex_filter __rcu *next; - struct rcu_work rwork; -}; - - -struct tcindex_data { - struct tcindex_filter_result *perfect; /* perfect hash; NULL if none */ - struct tcindex_filter __rcu **h; /* imperfect hash; */ - struct tcf_proto *tp; - u16 mask; /* AND key with mask */ - u32 shift; /* shift ANDed key to the right */ - u32 hash; /* hash table size; 0 if undefined */ - u32 alloc_hash; /* allocated size */ - u32 fall_through; /* 0: only classify if explicit match */ - refcount_t refcnt; /* a temporary refcnt for perfect hash */ - struct rcu_work rwork; -}; - -static inline int tcindex_filter_is_set(struct tcindex_filter_result *r) -{ - return tcf_exts_has_actions(&r->exts) || r->res.classid; -} - -static void tcindex_data_get(struct tcindex_data *p) -{ - refcount_inc(&p->refcnt); -} - -static void tcindex_data_put(struct tcindex_data *p) -{ - if (refcount_dec_and_test(&p->refcnt)) { - kfree(p->perfect); - kfree(p->h); - kfree(p); - } -} - -static struct tcindex_filter_result *tcindex_lookup(struct tcindex_data *p, - u16 key) -{ - if (p->perfect) { - struct tcindex_filter_result *f = p->perfect + key; - - return tcindex_filter_is_set(f) ? f : NULL; - } else if (p->h) { - struct tcindex_filter __rcu **fp; - struct tcindex_filter *f; - - fp = &p->h[key % p->hash]; - for (f = rcu_dereference_bh_rtnl(*fp); - f; - fp = &f->next, f = rcu_dereference_bh_rtnl(*fp)) - if (f->key == key) - return &f->result; - } - - return NULL; -} - - -static int tcindex_classify(struct sk_buff *skb, const struct tcf_proto *tp, - struct tcf_result *res) -{ - struct tcindex_data *p = rcu_dereference_bh(tp->root); - struct tcindex_filter_result *f; - int key = (skb->tc_index & p->mask) >> p->shift; - - pr_debug("tcindex_classify(skb %p,tp %p,res %p),p %p\n", - skb, tp, res, p); - - f = tcindex_lookup(p, key); - if (!f) { - struct Qdisc *q = tcf_block_q(tp->chain->block); - - if (!p->fall_through) - return -1; - res->classid = TC_H_MAKE(TC_H_MAJ(q->handle), key); - res->class = 0; - pr_debug("alg 0x%x\n", res->classid); - return 0; - } - *res = f->res; - pr_debug("map 0x%x\n", res->classid); - - return tcf_exts_exec(skb, &f->exts, res); -} - - -static void *tcindex_get(struct tcf_proto *tp, u32 handle) -{ - struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r; - - pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle); - if (p->perfect && handle >= p->alloc_hash) - return NULL; - r = tcindex_lookup(p, handle); - return r && tcindex_filter_is_set(r) ? r : NULL; -} - -static int tcindex_init(struct tcf_proto *tp) -{ - struct tcindex_data *p; - - pr_debug("tcindex_init(tp %p)\n", tp); - p = kzalloc(sizeof(struct tcindex_data), GFP_KERNEL); - if (!p) - return -ENOMEM; - - p->mask = 0xffff; - p->hash = DEFAULT_HASH_SIZE; - p->fall_through = 1; - refcount_set(&p->refcnt, 1); /* Paired with tcindex_destroy_work() */ - - rcu_assign_pointer(tp->root, p); - return 0; -} - -static void __tcindex_destroy_rexts(struct tcindex_filter_result *r) -{ - tcf_exts_destroy(&r->exts); - tcf_exts_put_net(&r->exts); - tcindex_data_put(r->p); -} - -static void tcindex_destroy_rexts_work(struct work_struct *work) -{ - struct tcindex_filter_result *r; - - r = container_of(to_rcu_work(work), - struct tcindex_filter_result, - rwork); - rtnl_lock(); - __tcindex_destroy_rexts(r); - rtnl_unlock(); -} - -static void __tcindex_destroy_fexts(struct tcindex_filter *f) -{ - tcf_exts_destroy(&f->result.exts); - tcf_exts_put_net(&f->result.exts); - kfree(f); -} - -static void tcindex_destroy_fexts_work(struct work_struct *work) -{ - struct tcindex_filter *f = container_of(to_rcu_work(work), - struct tcindex_filter, - rwork); - - rtnl_lock(); - __tcindex_destroy_fexts(f); - rtnl_unlock(); -} - -static int tcindex_delete(struct tcf_proto *tp, void *arg, bool *last, - bool rtnl_held, struct netlink_ext_ack *extack) -{ - struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r = arg; - struct tcindex_filter __rcu **walk; - struct tcindex_filter *f = NULL; - - pr_debug("tcindex_delete(tp %p,arg %p),p %p\n", tp, arg, p); - if (p->perfect) { - if (!r->res.class) - return -ENOENT; - } else { - int i; - - for (i = 0; i < p->hash; i++) { - walk = p->h + i; - for (f = rtnl_dereference(*walk); f; - walk = &f->next, f = rtnl_dereference(*walk)) { - if (&f->result == r) - goto found; - } - } - return -ENOENT; - -found: - rcu_assign_pointer(*walk, rtnl_dereference(f->next)); - } - tcf_unbind_filter(tp, &r->res); - /* all classifiers are required to call tcf_exts_destroy() after rcu - * grace period, since converted-to-rcu actions are relying on that - * in cleanup() callback - */ - if (f) { - if (tcf_exts_get_net(&f->result.exts)) - tcf_queue_work(&f->rwork, tcindex_destroy_fexts_work); - else - __tcindex_destroy_fexts(f); - } else { - tcindex_data_get(p); - - if (tcf_exts_get_net(&r->exts)) - tcf_queue_work(&r->rwork, tcindex_destroy_rexts_work); - else - __tcindex_destroy_rexts(r); - } - - *last = false; - return 0; -} - -static void tcindex_destroy_work(struct work_struct *work) -{ - struct tcindex_data *p = container_of(to_rcu_work(work), - struct tcindex_data, - rwork); - - tcindex_data_put(p); -} - -static inline int -valid_perfect_hash(struct tcindex_data *p) -{ - return p->hash > (p->mask >> p->shift); -} - -static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = { - [TCA_TCINDEX_HASH] = { .type = NLA_U32 }, - [TCA_TCINDEX_MASK] = { .type = NLA_U16 }, - [TCA_TCINDEX_SHIFT] = { .type = NLA_U32 }, - [TCA_TCINDEX_FALL_THROUGH] = { .type = NLA_U32 }, - [TCA_TCINDEX_CLASSID] = { .type = NLA_U32 }, -}; - -static int tcindex_filter_result_init(struct tcindex_filter_result *r, - struct tcindex_data *p, - struct net *net) -{ - memset(r, 0, sizeof(*r)); - r->p = p; - return tcf_exts_init(&r->exts, net, TCA_TCINDEX_ACT, - TCA_TCINDEX_POLICE); -} - -static void tcindex_free_perfect_hash(struct tcindex_data *cp); - -static void tcindex_partial_destroy_work(struct work_struct *work) -{ - struct tcindex_data *p = container_of(to_rcu_work(work), - struct tcindex_data, - rwork); - - rtnl_lock(); - if (p->perfect) - tcindex_free_perfect_hash(p); - kfree(p); - rtnl_unlock(); -} - -static void tcindex_free_perfect_hash(struct tcindex_data *cp) -{ - int i; - - for (i = 0; i < cp->hash; i++) - tcf_exts_destroy(&cp->perfect[i].exts); - kfree(cp->perfect); -} - -static int tcindex_alloc_perfect_hash(struct net *net, struct tcindex_data *cp) -{ - int i, err = 0; - - cp->perfect = kcalloc(cp->hash, sizeof(struct tcindex_filter_result), - GFP_KERNEL | __GFP_NOWARN); - if (!cp->perfect) - return -ENOMEM; - - for (i = 0; i < cp->hash; i++) { - err = tcf_exts_init(&cp->perfect[i].exts, net, - TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); - if (err < 0) - goto errout; - cp->perfect[i].p = cp; - } - - return 0; - -errout: - tcindex_free_perfect_hash(cp); - return err; -} - -static int -tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base, - u32 handle, struct tcindex_data *p, - struct tcindex_filter_result *r, struct nlattr **tb, - struct nlattr *est, bool ovr, struct netlink_ext_ack *extack) -{ - struct tcindex_filter_result new_filter_result; - struct tcindex_data *cp = NULL, *oldp; - struct tcindex_filter *f = NULL; /* make gcc behave */ - struct tcf_result cr = {}; - int err, balloc = 0; - struct tcf_exts e; - bool update_h = false; - - err = tcf_exts_init(&e, net, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE); - if (err < 0) - return err; - err = tcf_exts_validate(net, tp, tb, est, &e, ovr, true, extack); - if (err < 0) - goto errout; - - err = -ENOMEM; - /* tcindex_data attributes must look atomic to classifier/lookup so - * allocate new tcindex data and RCU assign it onto root. Keeping - * perfect hash and hash pointers from old data. - */ - cp = kzalloc(sizeof(*cp), GFP_KERNEL); - if (!cp) - goto errout; - - cp->mask = p->mask; - cp->shift = p->shift; - cp->hash = p->hash; - cp->alloc_hash = p->alloc_hash; - cp->fall_through = p->fall_through; - cp->tp = tp; - refcount_set(&cp->refcnt, 1); /* Paired with tcindex_destroy_work() */ - - if (tb[TCA_TCINDEX_HASH]) - cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); - - if (tb[TCA_TCINDEX_MASK]) - cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]); - - if (tb[TCA_TCINDEX_SHIFT]) { - cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]); - if (cp->shift > 16) { - err = -EINVAL; - goto errout; - } - } - if (!cp->hash) { - /* Hash not specified, use perfect hash if the upper limit - * of the hashing index is below the threshold. - */ - if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD) - cp->hash = (cp->mask >> cp->shift) + 1; - else - cp->hash = DEFAULT_HASH_SIZE; - } - - if (p->perfect) { - int i; - - if (tcindex_alloc_perfect_hash(net, cp) < 0) - goto errout; - cp->alloc_hash = cp->hash; - for (i = 0; i < min(cp->hash, p->hash); i++) - cp->perfect[i].res = p->perfect[i].res; - balloc = 1; - } - cp->h = p->h; - - err = tcindex_filter_result_init(&new_filter_result, cp, net); - if (err < 0) - goto errout_alloc; - if (r) - cr = r->res; - - err = -EBUSY; - - /* Hash already allocated, make sure that we still meet the - * requirements for the allocated hash. - */ - if (cp->perfect) { - if (!valid_perfect_hash(cp) || - cp->hash > cp->alloc_hash) - goto errout_alloc; - } else if (cp->h && cp->hash != cp->alloc_hash) { - goto errout_alloc; - } - - err = -EINVAL; - if (tb[TCA_TCINDEX_FALL_THROUGH]) - cp->fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]); - - if (!cp->perfect && !cp->h) - cp->alloc_hash = cp->hash; - - /* Note: this could be as restrictive as if (handle & ~(mask >> shift)) - * but then, we'd fail handles that may become valid after some future - * mask change. While this is extremely unlikely to ever matter, - * the check below is safer (and also more backwards-compatible). - */ - if (cp->perfect || valid_perfect_hash(cp)) - if (handle >= cp->alloc_hash) - goto errout_alloc; - - - err = -ENOMEM; - if (!cp->perfect && !cp->h) { - if (valid_perfect_hash(cp)) { - if (tcindex_alloc_perfect_hash(net, cp) < 0) - goto errout_alloc; - balloc = 1; - } else { - struct tcindex_filter __rcu **hash; - - hash = kcalloc(cp->hash, - sizeof(struct tcindex_filter *), - GFP_KERNEL); - - if (!hash) - goto errout_alloc; - - cp->h = hash; - balloc = 2; - } - } - - if (cp->perfect) { - r = cp->perfect + handle; - } else { - /* imperfect area is updated in-place using rcu */ - update_h = !!tcindex_lookup(cp, handle); - r = &new_filter_result; - } - - if (r == &new_filter_result) { - f = kzalloc(sizeof(*f), GFP_KERNEL); - if (!f) - goto errout_alloc; - f->key = handle; - f->next = NULL; - err = tcindex_filter_result_init(&f->result, cp, net); - if (err < 0) { - kfree(f); - goto errout_alloc; - } - } - - if (tb[TCA_TCINDEX_CLASSID]) { - cr.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]); - tcf_bind_filter(tp, &cr, base); - } - - oldp = p; - r->res = cr; - tcf_exts_change(&r->exts, &e); - - rcu_assign_pointer(tp->root, cp); - - if (update_h) { - struct tcindex_filter __rcu **fp; - struct tcindex_filter *cf; - - f->result.res = r->res; - tcf_exts_change(&f->result.exts, &r->exts); - - /* imperfect area bucket */ - fp = cp->h + (handle % cp->hash); - - /* lookup the filter, guaranteed to exist */ - for (cf = rcu_dereference_bh_rtnl(*fp); cf; - fp = &cf->next, cf = rcu_dereference_bh_rtnl(*fp)) - if (cf->key == (u16)handle) - break; - - f->next = cf->next; - - cf = rcu_replace_pointer(*fp, f, 1); - tcf_exts_get_net(&cf->result.exts); - tcf_queue_work(&cf->rwork, tcindex_destroy_fexts_work); - } else if (r == &new_filter_result) { - struct tcindex_filter *nfp; - struct tcindex_filter __rcu **fp; - - f->result.res = r->res; - tcf_exts_change(&f->result.exts, &r->exts); - - fp = cp->h + (handle % cp->hash); - for (nfp = rtnl_dereference(*fp); - nfp; - fp = &nfp->next, nfp = rtnl_dereference(*fp)) - ; /* nothing */ - - rcu_assign_pointer(*fp, f); - } else { - tcf_exts_destroy(&new_filter_result.exts); - } - - if (oldp) - tcf_queue_work(&oldp->rwork, tcindex_partial_destroy_work); - return 0; - -errout_alloc: - if (balloc == 1) - tcindex_free_perfect_hash(cp); - else if (balloc == 2) - kfree(cp->h); - tcf_exts_destroy(&new_filter_result.exts); -errout: - kfree(cp); - tcf_exts_destroy(&e); - return err; -} - -static int -tcindex_change(struct net *net, struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, u32 handle, - struct nlattr **tca, void **arg, bool ovr, - bool rtnl_held, struct netlink_ext_ack *extack) -{ - struct nlattr *opt = tca[TCA_OPTIONS]; - struct nlattr *tb[TCA_TCINDEX_MAX + 1]; - struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r = *arg; - int err; - - pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p," - "p %p,r %p,*arg %p\n", - tp, handle, tca, arg, opt, p, r, *arg); - - if (!opt) - return 0; - - err = nla_parse_nested_deprecated(tb, TCA_TCINDEX_MAX, opt, - tcindex_policy, NULL); - if (err < 0) - return err; - - return tcindex_set_parms(net, tp, base, handle, p, r, tb, - tca[TCA_RATE], ovr, extack); -} - -static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker, - bool rtnl_held) -{ - struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter *f, *next; - int i; - - pr_debug("tcindex_walk(tp %p,walker %p),p %p\n", tp, walker, p); - if (p->perfect) { - for (i = 0; i < p->hash; i++) { - if (!p->perfect[i].res.class) - continue; - if (walker->count >= walker->skip) { - if (walker->fn(tp, p->perfect + i, walker) < 0) { - walker->stop = 1; - return; - } - } - walker->count++; - } - } - if (!p->h) - return; - for (i = 0; i < p->hash; i++) { - for (f = rtnl_dereference(p->h[i]); f; f = next) { - next = rtnl_dereference(f->next); - if (walker->count >= walker->skip) { - if (walker->fn(tp, &f->result, walker) < 0) { - walker->stop = 1; - return; - } - } - walker->count++; - } - } -} - -static void tcindex_destroy(struct tcf_proto *tp, bool rtnl_held, - struct netlink_ext_ack *extack) -{ - struct tcindex_data *p = rtnl_dereference(tp->root); - int i; - - pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p); - - if (p->perfect) { - for (i = 0; i < p->hash; i++) { - struct tcindex_filter_result *r = p->perfect + i; - - /* tcf_queue_work() does not guarantee the ordering we - * want, so we have to take this refcnt temporarily to - * ensure 'p' is freed after all tcindex_filter_result - * here. Imperfect hash does not need this, because it - * uses linked lists rather than an array. - */ - tcindex_data_get(p); - - tcf_unbind_filter(tp, &r->res); - if (tcf_exts_get_net(&r->exts)) - tcf_queue_work(&r->rwork, - tcindex_destroy_rexts_work); - else - __tcindex_destroy_rexts(r); - } - } - - for (i = 0; p->h && i < p->hash; i++) { - struct tcindex_filter *f, *next; - bool last; - - for (f = rtnl_dereference(p->h[i]); f; f = next) { - next = rtnl_dereference(f->next); - tcindex_delete(tp, &f->result, &last, rtnl_held, NULL); - } - } - - tcf_queue_work(&p->rwork, tcindex_destroy_work); -} - - -static int tcindex_dump(struct net *net, struct tcf_proto *tp, void *fh, - struct sk_buff *skb, struct tcmsg *t, bool rtnl_held) -{ - struct tcindex_data *p = rtnl_dereference(tp->root); - struct tcindex_filter_result *r = fh; - struct nlattr *nest; - - pr_debug("tcindex_dump(tp %p,fh %p,skb %p,t %p),p %p,r %p\n", - tp, fh, skb, t, p, r); - pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h); - - nest = nla_nest_start_noflag(skb, TCA_OPTIONS); - if (nest == NULL) - goto nla_put_failure; - - if (!fh) { - t->tcm_handle = ~0; /* whatever ... */ - if (nla_put_u32(skb, TCA_TCINDEX_HASH, p->hash) || - nla_put_u16(skb, TCA_TCINDEX_MASK, p->mask) || - nla_put_u32(skb, TCA_TCINDEX_SHIFT, p->shift) || - nla_put_u32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through)) - goto nla_put_failure; - nla_nest_end(skb, nest); - } else { - if (p->perfect) { - t->tcm_handle = r - p->perfect; - } else { - struct tcindex_filter *f; - struct tcindex_filter __rcu **fp; - int i; - - t->tcm_handle = 0; - for (i = 0; !t->tcm_handle && i < p->hash; i++) { - fp = &p->h[i]; - for (f = rtnl_dereference(*fp); - !t->tcm_handle && f; - fp = &f->next, f = rtnl_dereference(*fp)) { - if (&f->result == r) - t->tcm_handle = f->key; - } - } - } - pr_debug("handle = %d\n", t->tcm_handle); - if (r->res.class && - nla_put_u32(skb, TCA_TCINDEX_CLASSID, r->res.classid)) - goto nla_put_failure; - - if (tcf_exts_dump(skb, &r->exts) < 0) - goto nla_put_failure; - nla_nest_end(skb, nest); - - if (tcf_exts_dump_stats(skb, &r->exts) < 0) - goto nla_put_failure; - } - - return skb->len; - -nla_put_failure: - nla_nest_cancel(skb, nest); - return -1; -} - -static void tcindex_bind_class(void *fh, u32 classid, unsigned long cl, - void *q, unsigned long base) -{ - struct tcindex_filter_result *r = fh; - - if (r && r->res.classid == classid) { - if (cl) - __tcf_bind_filter(q, &r->res, base); - else - __tcf_unbind_filter(q, &r->res); - } -} - -static struct tcf_proto_ops cls_tcindex_ops __read_mostly = { - .kind = "tcindex", - .classify = tcindex_classify, - .init = tcindex_init, - .destroy = tcindex_destroy, - .get = tcindex_get, - .change = tcindex_change, - .delete = tcindex_delete, - .walk = tcindex_walk, - .dump = tcindex_dump, - .bind_class = tcindex_bind_class, - .owner = THIS_MODULE, -}; - -static int __init init_tcindex(void) -{ - return register_tcf_proto_ops(&cls_tcindex_ops); -} - -static void __exit exit_tcindex(void) -{ - unregister_tcf_proto_ops(&cls_tcindex_ops); -} - -module_init(init_tcindex) -module_exit(exit_tcindex) -MODULE_LICENSE("GPL"); From 5d03a19ac7e81f80d96c3bfeb719da38257f75e5 Mon Sep 17 00:00:00 2001 From: Liu Shixin via Jfs-discussion Date: Thu, 3 Nov 2022 11:01:59 +0800 Subject: [PATCH 0546/1017] fs/jfs: fix shift exponent db_agl2size negative [ Upstream commit fad376fce0af58deebc5075b8539dc05bf639af3 ] As a shift exponent, db_agl2size can not be less than 0. Add the missing check to fix the shift-out-of-bounds bug reported by syzkaller: UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:2227:15 shift exponent -744642816 is negative Reported-by: syzbot+0be96567042453c0c820@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Liu Shixin Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- fs/jfs/jfs_dmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 2c9493011aec..501263355ef4 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -193,7 +193,8 @@ int dbMount(struct inode *ipbmap) bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart); bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size); - if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) { + if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG || + bmp->db_agl2size < 0) { err = -EINVAL; goto err_release_metapage; } From a1368eaea058e451d20ea99ca27e72d9df0d16dd Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 5 Dec 2022 12:06:42 +0400 Subject: [PATCH 0547/1017] objtool: Fix memory leak in create_static_call_sections() [ Upstream commit 3da73f102309fe29150e5c35acd20dd82063ff67 ] strdup() allocates memory for key_name. We need to release the memory in the following error paths. Add free() to avoid memory leak. Fixes: 1e7e47883830 ("x86/static_call: Add inline static call implementation for x86-64") Signed-off-by: Miaoqian Lin Signed-off-by: Ingo Molnar Link: https://lore.kernel.org/r/20221205080642.558583-1-linmq006@gmail.com Cc: Josh Poimboeuf Cc: Peter Zijlstra Signed-off-by: Sasha Levin --- tools/objtool/check.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 5c4190382a51..9a0a54194636 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -572,6 +572,7 @@ static int create_static_call_sections(struct objtool_file *file) if (strncmp(key_name, STATIC_CALL_TRAMP_PREFIX_STR, STATIC_CALL_TRAMP_PREFIX_LEN)) { WARN("static_call: trampoline name malformed: %s", key_name); + free(key_name); return -1; } tmp = key_name + STATIC_CALL_TRAMP_PREFIX_LEN - STATIC_CALL_KEY_PREFIX_LEN; @@ -581,6 +582,7 @@ static int create_static_call_sections(struct objtool_file *file) if (!key_sym) { if (!module) { WARN("static_call: can't find static_call_key symbol: %s", tmp); + free(key_name); return -1; } From 8b98e7a45e6382b75cacf7932bcdb27482a56e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 21 Jul 2022 12:31:25 +0200 Subject: [PATCH 0548/1017] pwm: sifive: Reduce time the controller lock is held MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 0f02f491b786143f08eb19840f1cf4f12aec6dee ] The lock is only to serialize access and update to user_count and approx_period between different PWMs served by the same pwm_chip. So the lock needs only to be taken during the check if the (chip global) period can and/or needs to be changed. Signed-off-by: Uwe Kleine-König Tested-by: Emil Renner Berthing Signed-off-by: Thierry Reding Stable-dep-of: 334c7b13d383 ("pwm: sifive: Always let the first pwm_apply_state succeed") Signed-off-by: Sasha Levin --- drivers/pwm/pwm-sifive.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index 12e9e23272ab..400cc91057ac 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -41,7 +41,7 @@ struct pwm_sifive_ddata { struct pwm_chip chip; - struct mutex lock; /* lock to protect user_count */ + struct mutex lock; /* lock to protect user_count and approx_period */ struct notifier_block notifier; struct clk *clk; void __iomem *regs; @@ -76,6 +76,7 @@ static void pwm_sifive_free(struct pwm_chip *chip, struct pwm_device *pwm) mutex_unlock(&ddata->lock); } +/* Called holding ddata->lock */ static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata, unsigned long rate) { @@ -163,7 +164,6 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, return ret; } - mutex_lock(&ddata->lock); cur_state = pwm->state; enabled = cur_state.enabled; @@ -182,14 +182,17 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, /* The hardware cannot generate a 100% duty cycle */ frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1); + mutex_lock(&ddata->lock); if (state->period != ddata->approx_period) { if (ddata->user_count != 1) { + mutex_unlock(&ddata->lock); ret = -EBUSY; goto exit; } ddata->approx_period = state->period; pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk)); } + mutex_unlock(&ddata->lock); writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm)); @@ -198,7 +201,6 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, exit: clk_disable(ddata->clk); - mutex_unlock(&ddata->lock); return ret; } From c2677c49b766b365578ef7a0641bf0c857545d7b Mon Sep 17 00:00:00 2001 From: Emil Renner Berthing Date: Wed, 9 Nov 2022 12:37:24 +0100 Subject: [PATCH 0549/1017] pwm: sifive: Always let the first pwm_apply_state succeed [ Upstream commit 334c7b13d38321e47d1a51dba0bef9f4c403ec75 ] Commit 2cfe9bbec56ea579135cdd92409fff371841904f added support for the RGB and green PWM controlled LEDs on the HiFive Unmatched board managed by the leds-pwm-multicolor and leds-pwm drivers respectively. All three colours of the RGB LED and the green LED run from different lines of the same PWM, but with the same period so this works fine when the LED drivers are loaded one after the other. Unfortunately it does expose a race in the PWM driver when both LED drivers are loaded at roughly the same time. Here is an example: | Thread A | Thread B | | led_pwm_mc_probe | led_pwm_probe | | devm_fwnode_pwm_get | | | pwm_sifive_request | | | ddata->user_count++ | | | | devm_fwnode_pwm_get | | | pwm_sifive_request | | | ddata->user_count++ | | ... | ... | | pwm_state_apply | pwm_state_apply | | pwm_sifive_apply | pwm_sifive_apply | Now both calls to pwm_sifive_apply will see that ddata->approx_period, initially 0, is different from the requested period and the clock needs to be updated. But since ddata->user_count >= 2 both calls will fail with -EBUSY, which will then cause both LED drivers to fail to probe. Fix it by letting the first call to pwm_sifive_apply update the clock even when ddata->user_count != 1. Fixes: 9e37a53eb051 ("pwm: sifive: Add a driver for SiFive SoC PWM") Signed-off-by: Emil Renner Berthing Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- drivers/pwm/pwm-sifive.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index 400cc91057ac..52a55bae033d 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -184,7 +184,13 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, mutex_lock(&ddata->lock); if (state->period != ddata->approx_period) { - if (ddata->user_count != 1) { + /* + * Don't let a 2nd user change the period underneath the 1st user. + * However if ddate->approx_period == 0 this is the first time we set + * any period, so let whoever gets here first set the period so other + * users who agree on the period won't fail. + */ + if (ddata->user_count != 1 && ddata->approx_period) { mutex_unlock(&ddata->lock); ret = -EBUSY; goto exit; From 9d4a4a9ee95e054ad2384421f91acd823ceee021 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 23 Nov 2022 14:36:52 +0100 Subject: [PATCH 0550/1017] pwm: stm32-lp: fix the check on arr and cmp registers update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 3066bc2d58be31275afb51a589668f265e419c37 ] The ARR (auto reload register) and CMP (compare) registers are successively written. The status bits to check the update of these registers are polled together with regmap_read_poll_timeout(). The condition to end the loop may become true, even if one of the register isn't correctly updated. So ensure both status bits are set before clearing them. Fixes: e70a540b4e02 ("pwm: Add STM32 LPTimer PWM driver") Signed-off-by: Fabrice Gasnier Acked-by: Uwe Kleine-König Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- drivers/pwm/pwm-stm32-lp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c index 945a8b2b8564..c8a847fcb775 100644 --- a/drivers/pwm/pwm-stm32-lp.c +++ b/drivers/pwm/pwm-stm32-lp.c @@ -127,7 +127,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, /* ensure CMP & ARR registers are properly written */ ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, - (val & STM32_LPTIM_CMPOK_ARROK), + (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 100, 1000); if (ret) { dev_err(priv->chip.dev, "ARR/CMP registers write issue\n"); From 33909b1a646d1f31d631ff4a77a7303317e4a82b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 19 Aug 2022 15:33:00 -0700 Subject: [PATCH 0551/1017] f2fs: use memcpy_{to,from}_page() where possible [ Upstream commit b87846bd61c7c09560617da416208a5454530d57 ] This is simpler, and as a side effect it replaces several uses of kmap_atomic() with its recommended replacement kmap_local_page(). Signed-off-by: Eric Biggers Reviewed-by: Fabio M. De Francesco Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: b1b9896718bc ("fs: f2fs: initialize fsdata in pagecache_write()") Signed-off-by: Sasha Levin --- fs/f2fs/inline.c | 15 ++++----------- fs/f2fs/super.c | 11 ++--------- fs/f2fs/verity.c | 10 ++-------- 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 4e794c1390cc..df1a0cbfa1be 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -64,7 +64,6 @@ bool f2fs_may_inline_dentry(struct inode *inode) void f2fs_do_read_inline_data(struct page *page, struct page *ipage) { struct inode *inode = page->mapping->host; - void *src_addr, *dst_addr; if (PageUptodate(page)) return; @@ -74,11 +73,8 @@ void f2fs_do_read_inline_data(struct page *page, struct page *ipage) zero_user_segment(page, MAX_INLINE_DATA(inode), PAGE_SIZE); /* Copy the whole inline data block */ - src_addr = inline_data_addr(inode, ipage); - dst_addr = kmap_atomic(page); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); - flush_dcache_page(page); - kunmap_atomic(dst_addr); + memcpy_to_page(page, 0, inline_data_addr(inode, ipage), + MAX_INLINE_DATA(inode)); if (!PageUptodate(page)) SetPageUptodate(page); } @@ -245,7 +241,6 @@ out: int f2fs_write_inline_data(struct inode *inode, struct page *page) { - void *src_addr, *dst_addr; struct dnode_of_data dn; int err; @@ -262,10 +257,8 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page) f2fs_bug_on(F2FS_I_SB(inode), page->index); f2fs_wait_on_page_writeback(dn.inode_page, NODE, true, true); - src_addr = kmap_atomic(page); - dst_addr = inline_data_addr(inode, dn.inode_page); - memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode)); - kunmap_atomic(src_addr); + memcpy_from_page(inline_data_addr(inode, dn.inode_page), + page, 0, MAX_INLINE_DATA(inode)); set_page_dirty(dn.inode_page); f2fs_clear_page_cache_dirty_tag(page); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index fba413ced982..0bba5c72fc77 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2034,7 +2034,6 @@ static ssize_t f2fs_quota_read(struct super_block *sb, int type, char *data, size_t toread; loff_t i_size = i_size_read(inode); struct page *page; - char *kaddr; if (off > i_size) return 0; @@ -2068,9 +2067,7 @@ repeat: return -EIO; } - kaddr = kmap_atomic(page); - memcpy(data, kaddr + offset, tocopy); - kunmap_atomic(kaddr); + memcpy_from_page(data, page, offset, tocopy); f2fs_put_page(page, 1); offset = 0; @@ -2092,7 +2089,6 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type, size_t towrite = len; struct page *page; void *fsdata = NULL; - char *kaddr; int err = 0; int tocopy; @@ -2112,10 +2108,7 @@ retry: break; } - kaddr = kmap_atomic(page); - memcpy(kaddr + offset, data, tocopy); - kunmap_atomic(kaddr); - flush_dcache_page(page); + memcpy_to_page(page, offset, data, tocopy); a_ops->write_end(NULL, mapping, off, tocopy, tocopy, page, fsdata); diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c index cff94d095d0f..dafdb19ec0db 100644 --- a/fs/f2fs/verity.c +++ b/fs/f2fs/verity.c @@ -47,16 +47,13 @@ static int pagecache_read(struct inode *inode, void *buf, size_t count, size_t n = min_t(size_t, count, PAGE_SIZE - offset_in_page(pos)); struct page *page; - void *addr; page = read_mapping_page(inode->i_mapping, pos >> PAGE_SHIFT, NULL); if (IS_ERR(page)) return PTR_ERR(page); - addr = kmap_atomic(page); - memcpy(buf, addr + offset_in_page(pos), n); - kunmap_atomic(addr); + memcpy_from_page(buf, page, offset_in_page(pos), n); put_page(page); @@ -82,7 +79,6 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count, PAGE_SIZE - offset_in_page(pos)); struct page *page; void *fsdata; - void *addr; int res; res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0, @@ -90,9 +86,7 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count, if (res) return res; - addr = kmap_atomic(page); - memcpy(addr + offset_in_page(pos), buf, n); - kunmap_atomic(addr); + memcpy_to_page(page, offset_in_page(pos), buf, n); res = pagecache_write_end(NULL, inode->i_mapping, pos, n, n, page, fsdata); From 6be349d7388f3af7957dc6c7e241dc92a969fb38 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 21 Nov 2022 12:21:32 +0100 Subject: [PATCH 0552/1017] fs: f2fs: initialize fsdata in pagecache_write() [ Upstream commit b1b9896718bc1a212dc288ad66a5fa2fef11353d ] When aops->write_begin() does not initialize fsdata, KMSAN may report an error passing the latter to aops->write_end(). Fix this by unconditionally initializing fsdata. Suggested-by: Eric Biggers Fixes: 95ae251fe828 ("f2fs: add fs-verity support") Signed-off-by: Alexander Potapenko Reviewed-by: Eric Biggers Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/verity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c index dafdb19ec0db..cef40d92268f 100644 --- a/fs/f2fs/verity.c +++ b/fs/f2fs/verity.c @@ -78,7 +78,7 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count, size_t n = min_t(size_t, count, PAGE_SIZE - offset_in_page(pos)); struct page *page; - void *fsdata; + void *fsdata = NULL; int res; res = pagecache_write_begin(NULL, inode->i_mapping, pos, n, 0, From f2b9c4544e3bd60f353732291300097b0e8d8454 Mon Sep 17 00:00:00 2001 From: Xiang Yang Date: Tue, 15 Nov 2022 15:32:25 +0800 Subject: [PATCH 0553/1017] um: vector: Fix memory leak in vector_config [ Upstream commit 8f88c73afe481f93d40801596927e8c0047b6d96 ] If the return value of the uml_parse_vector_ifspec function is NULL, we should call kfree(params) to prevent memory leak. Fixes: 49da7e64f33e ("High Performance UML Vector Network Driver") Signed-off-by: Xiang Yang Acked-By: Anton Ivanov Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- arch/um/drivers/vector_kern.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 555203e3e7b4..fc662f7cc2af 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -771,6 +771,7 @@ static int vector_config(char *str, char **error_out) if (parsed == NULL) { *error_out = "vector_config failed to parse parameters"; + kfree(params); return -EINVAL; } From 846bfba34175c23b13cc2023c2d67b96e8c14c43 Mon Sep 17 00:00:00 2001 From: George Kennedy Date: Tue, 15 Nov 2022 10:14:44 -0500 Subject: [PATCH 0554/1017] ubi: ensure that VID header offset + VID header size <= alloc, size [ Upstream commit 1b42b1a36fc946f0d7088425b90d491b4257ca3e ] Ensure that the VID header offset + VID header size does not exceed the allocated area to avoid slab OOB. BUG: KASAN: slab-out-of-bounds in crc32_body lib/crc32.c:111 [inline] BUG: KASAN: slab-out-of-bounds in crc32_le_generic lib/crc32.c:179 [inline] BUG: KASAN: slab-out-of-bounds in crc32_le_base+0x58c/0x626 lib/crc32.c:197 Read of size 4 at addr ffff88802bb36f00 by task syz-executor136/1555 CPU: 2 PID: 1555 Comm: syz-executor136 Tainted: G W 6.0.0-1868 #1 Hardware name: Red Hat KVM, BIOS 1.13.0-2.module+el8.3.0+7860+a7792d29 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x85/0xad lib/dump_stack.c:106 print_address_description mm/kasan/report.c:317 [inline] print_report.cold.13+0xb6/0x6bb mm/kasan/report.c:433 kasan_report+0xa7/0x11b mm/kasan/report.c:495 crc32_body lib/crc32.c:111 [inline] crc32_le_generic lib/crc32.c:179 [inline] crc32_le_base+0x58c/0x626 lib/crc32.c:197 ubi_io_write_vid_hdr+0x1b7/0x472 drivers/mtd/ubi/io.c:1067 create_vtbl+0x4d5/0x9c4 drivers/mtd/ubi/vtbl.c:317 create_empty_lvol drivers/mtd/ubi/vtbl.c:500 [inline] ubi_read_volume_table+0x67b/0x288a drivers/mtd/ubi/vtbl.c:812 ubi_attach+0xf34/0x1603 drivers/mtd/ubi/attach.c:1601 ubi_attach_mtd_dev+0x6f3/0x185e drivers/mtd/ubi/build.c:965 ctrl_cdev_ioctl+0x2db/0x347 drivers/mtd/ubi/cdev.c:1043 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x193/0x213 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3e/0x86 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0x0 RIP: 0033:0x7f96d5cf753d Code: RSP: 002b:00007fffd72206f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f96d5cf753d RDX: 0000000020000080 RSI: 0000000040186f40 RDI: 0000000000000003 RBP: 0000000000400cd0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000400be0 R13: 00007fffd72207e0 R14: 0000000000000000 R15: 0000000000000000 Allocated by task 1555: kasan_save_stack+0x20/0x3d mm/kasan/common.c:38 kasan_set_track mm/kasan/common.c:45 [inline] set_alloc_info mm/kasan/common.c:437 [inline] ____kasan_kmalloc mm/kasan/common.c:516 [inline] __kasan_kmalloc+0x88/0xa3 mm/kasan/common.c:525 kasan_kmalloc include/linux/kasan.h:234 [inline] __kmalloc+0x138/0x257 mm/slub.c:4429 kmalloc include/linux/slab.h:605 [inline] ubi_alloc_vid_buf drivers/mtd/ubi/ubi.h:1093 [inline] create_vtbl+0xcc/0x9c4 drivers/mtd/ubi/vtbl.c:295 create_empty_lvol drivers/mtd/ubi/vtbl.c:500 [inline] ubi_read_volume_table+0x67b/0x288a drivers/mtd/ubi/vtbl.c:812 ubi_attach+0xf34/0x1603 drivers/mtd/ubi/attach.c:1601 ubi_attach_mtd_dev+0x6f3/0x185e drivers/mtd/ubi/build.c:965 ctrl_cdev_ioctl+0x2db/0x347 drivers/mtd/ubi/cdev.c:1043 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x193/0x213 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3e/0x86 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0x0 The buggy address belongs to the object at ffff88802bb36e00 which belongs to the cache kmalloc-256 of size 256 The buggy address is located 0 bytes to the right of 256-byte region [ffff88802bb36e00, ffff88802bb36f00) The buggy address belongs to the physical page: page:00000000ea4d1263 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x2bb36 head:00000000ea4d1263 order:1 compound_mapcount:0 compound_pincount:0 flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff) raw: 000fffffc0010200 ffffea000066c300 dead000000000003 ffff888100042b40 raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88802bb36e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff88802bb36e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffff88802bb36f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff88802bb36f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88802bb37000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Fixes: 801c135ce73d ("UBI: Unsorted Block Images") Reported-by: syzkaller Signed-off-by: George Kennedy Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/build.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 4153e0d15c5f..8747569e793d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -664,6 +664,12 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size); ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size); + if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) > + ubi->vid_hdr_alsize)) { + ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset); + return -EINVAL; + } + dbg_gen("min_io_size %d", ubi->min_io_size); dbg_gen("max_write_size %d", ubi->max_write_size); dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size); From 93e748ba517426912cfec83439fb64e2703083f1 Mon Sep 17 00:00:00 2001 From: Li Hua Date: Mon, 21 Nov 2022 19:18:47 +0800 Subject: [PATCH 0555/1017] ubifs: Fix build errors as symbol undefined [ Upstream commit aa6d148e6d6270274e3d5a529b71c54cd329d17f ] With CONFIG_UBIFS_FS_AUTHENTICATION not set, the compiler can assume that ubifs_node_check_hash() is never true and drops the call to ubifs_bad_hash(). Is CONFIG_CC_OPTIMIZE_FOR_SIZE enabled this optimization does not happen anymore. So When CONFIG_UBIFS_FS and CONFIG_CC_OPTIMIZE_FOR_SIZE is enabled but CONFIG_UBIFS_FS_AUTHENTICATION is not set, the build errors is as followd: ERROR: modpost: "ubifs_bad_hash" [fs/ubifs/ubifs.ko] undefined! Fix it by add no-op ubifs_bad_hash() for the CONFIG_UBIFS_FS_AUTHENTICATION=n case. Fixes: 16a26b20d2af ("ubifs: authentication: Add hashes to index nodes") Signed-off-by: Li Hua Reviewed-by: Sascha Hauer Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/ubifs.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index e7e48f3b179a..b66ebab5c5de 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1594,8 +1594,13 @@ static inline int ubifs_check_hmac(const struct ubifs_info *c, return crypto_memneq(expected, got, c->hmac_desc_len); } +#ifdef CONFIG_UBIFS_FS_AUTHENTICATION void ubifs_bad_hash(const struct ubifs_info *c, const void *node, const u8 *hash, int lnum, int offs); +#else +static inline void ubifs_bad_hash(const struct ubifs_info *c, const void *node, + const u8 *hash, int lnum, int offs) {}; +#endif int __ubifs_node_check_hash(const struct ubifs_info *c, const void *buf, const u8 *expected); From ffebd804c7ab22175fa14b74599c00e161dc1bfd Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 11 Oct 2022 11:47:27 +0800 Subject: [PATCH 0556/1017] ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted [ Upstream commit c2c36cc6ca23e614f9e4238d0ecf48549ee9002a ] Fix bad space budget when symlink file is encrypted. Bad space budget may let make_reservation() return with -ENOSPC, which could turn ubifs to read-only mode in do_writepage() process. Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216490 Fixes: ca7f85be8d6cf9 ("ubifs: Add support for encrypted symlinks") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 9257ee893bdb..7dceca1be9b5 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1117,7 +1117,6 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, int err, sz_change, len = strlen(symname); struct fscrypt_str disk_link; struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, - .new_ino_d = ALIGN(len, 8), .dirtied_ino = 1 }; struct fscrypt_name nm; @@ -1133,6 +1132,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, * Budget request settings: new inode, new direntry and changing parent * directory inode. */ + req.new_ino_d = ALIGN(disk_link.len - 1, 8); err = ubifs_budget_space(c, &req); if (err) return err; From 9e07ee28c20d1507d9c4b649932561fe583930eb Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 11 Oct 2022 11:47:28 +0800 Subject: [PATCH 0557/1017] ubifs: Rectify space budget for ubifs_xrename() [ Upstream commit 1b2ba09060e41adb356b9ae58ef94a7390928004 ] There is no space budget for ubifs_xrename(). It may let make_reservation() return with -ENOSPC, which could turn ubifs to read-only mode in do_writepage() process. Fix it by adding space budget for ubifs_xrename(). Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216569 Fixes: 9ec64962afb170 ("ubifs: Implement RENAME_EXCHANGE") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/dir.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 7dceca1be9b5..15b5664fd5c9 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1530,6 +1530,10 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry, return err; } + err = ubifs_budget_space(c, &req); + if (err) + goto out; + lock_4_inodes(old_dir, new_dir, NULL, NULL); time = current_time(old_dir); @@ -1555,6 +1559,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry, unlock_4_inodes(old_dir, new_dir, NULL, NULL); ubifs_release_budget(c, &req); +out: fscrypt_free_filename(&fst_nm); fscrypt_free_filename(&snd_nm); return err; From 495ea59a24a391bd0401c6442982ee29dca0a7e6 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 11 Oct 2022 11:47:30 +0800 Subject: [PATCH 0558/1017] ubifs: Fix wrong dirty space budget for dirty inode [ Upstream commit b248eaf049d9cdc5eb76b59399e4d3de233f02ac ] Each dirty inode should reserve 'c->bi.inode_budget' bytes in space budget calculation. Currently, space budget for dirty inode reports more space than what UBIFS actually needs to write. Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/budget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index c0b84e960b20..bdb79be6dc0e 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c @@ -403,7 +403,7 @@ static int calc_dd_growth(const struct ubifs_info *c, dd_growth = req->dirtied_page ? c->bi.page_budget : 0; if (req->dirtied_ino) - dd_growth += c->bi.inode_budget << (req->dirtied_ino - 1); + dd_growth += c->bi.inode_budget * req->dirtied_ino; if (req->mod_dent) dd_growth += c->bi.dent_budget; dd_growth += req->dirtied_ino_d; From 38a097dce1842ffca3ce007496c8e992215a120b Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 11 Oct 2022 11:47:31 +0800 Subject: [PATCH 0559/1017] ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1 [ Upstream commit 25fce616a61fc2f1821e4a9ce212d0e064707093 ] If target inode is a special file (eg. block/char device) with nlink count greater than 1, the inode with ui->data will be re-written on disk. However, UBIFS losts target inode's data_len while doing space budget. Bad space budget may let make_reservation() return with -ENOSPC, which could turn ubifs to read-only mode in do_writepage() process. Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216494 Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/dir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 15b5664fd5c9..6039943877e1 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1288,6 +1288,8 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, if (unlink) { ubifs_assert(c, inode_is_locked(new_inode)); + /* Budget for old inode's data when its nlink > 1. */ + req.dirtied_ino_d = ALIGN(ubifs_inode(new_inode)->data_len, 8); err = ubifs_purge_xattrs(new_inode); if (err) return err; From 38fd7acdc1d2c650e8d8ef4343fc306103ca75d9 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 11 Oct 2022 11:47:32 +0800 Subject: [PATCH 0560/1017] ubifs: Reserve one leb for each journal head while doing budget [ Upstream commit e874dcde1cbf82c786c0e7f2899811c02630cc52 ] UBIFS calculates available space by c->main_bytes - c->lst.total_used (which means non-index lebs' free and dirty space is accounted into total available), then index lebs and four lebs (one for gc_lnum, one for deletions, two for journal heads) are deducted. In following situation, ubifs may get -ENOSPC from make_reservation(): LEB 84: DATAHD free 122880 used 1920 dirty 2176 dark 6144 LEB 110:DELETION free 126976 used 0 dirty 0 dark 6144 (empty) LEB 201:gc_lnum free 126976 used 0 dirty 0 dark 6144 LEB 272:GCHD free 77824 used 47672 dirty 1480 dark 6144 LEB 356:BASEHD free 0 used 39776 dirty 87200 dark 6144 OTHERS: index lebs, zero-available non-index lebs UBIFS calculates the available bytes is 6888 (How to calculate it: 126976 * 5[remain main bytes] - 1920[used] - 47672[used] - 39776[used] - 126976 * 1[deletions] - 126976 * 1[gc_lnum] - 126976 * 2[journal heads] - 6144 * 5[dark] = 6888) after doing budget, however UBIFS cannot use BASEHD's dirty space(87200), because UBIFS cannot find next BASEHD to reclaim current BASEHD. (c->bi.min_idx_lebs equals to c->lst.idx_lebs, the empty leb won't be found by ubifs_find_free_space(), and dirty index lebs won't be picked as gced lebs. All non-index lebs has dirty space less then c->dead_wm, non-index lebs won't be picked as gced lebs either. So new free lebs won't be produced.). See more details in Link. To fix it, reserve one leb for each journal head while doing budget. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216562 Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/budget.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index bdb79be6dc0e..9cb05ef9b9dd 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c @@ -212,11 +212,10 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs) subtract_lebs += 1; /* - * The GC journal head LEB is not really accessible. And since - * different write types go to different heads, we may count only on - * one head's space. + * Since different write types go to different heads, we should + * reserve one leb for each head. */ - subtract_lebs += c->jhead_cnt - 1; + subtract_lebs += c->jhead_cnt; /* We also reserve one LEB for deletions, which bypass budgeting */ subtract_lebs += 1; From 35f8d4064e54c18424db2997059d4c0b1d13d093 Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Fri, 21 Oct 2022 18:21:56 +0800 Subject: [PATCH 0561/1017] ubi: Fix use-after-free when volume resizing failed [ Upstream commit 9af31d6ec1a4be4caab2550096c6bd2ba8fba472 ] There is an use-after-free problem reported by KASAN: ================================================================== BUG: KASAN: use-after-free in ubi_eba_copy_table+0x11f/0x1c0 [ubi] Read of size 8 at addr ffff888101eec008 by task ubirsvol/4735 CPU: 2 PID: 4735 Comm: ubirsvol Not tainted 6.1.0-rc1-00003-g84fa3304a7fc-dirty #14 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014 Call Trace: dump_stack_lvl+0x34/0x44 print_report+0x171/0x472 kasan_report+0xad/0x130 ubi_eba_copy_table+0x11f/0x1c0 [ubi] ubi_resize_volume+0x4f9/0xbc0 [ubi] ubi_cdev_ioctl+0x701/0x1850 [ubi] __x64_sys_ioctl+0x11d/0x170 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 When ubi_change_vtbl_record() returns an error in ubi_resize_volume(), "new_eba_tbl" will be freed on error handing path, but it is holded by "vol->eba_tbl" in ubi_eba_replace_table(). It means that the liftcycle of "vol->eba_tbl" and "vol" are different, so when resizing volume in next time, it causing an use-after-free fault. Fix it by not freeing "new_eba_tbl" after it replaced in ubi_eba_replace_table(), while will be freed in next volume resizing. Fixes: 801c135ce73d ("UBI: Unsorted Block Images") Signed-off-by: Li Zetao Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/vmt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 6ea95ade4ca6..6c7822c1cc45 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -464,7 +464,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) for (i = 0; i < -pebs; i++) { err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i); if (err) - goto out_acc; + goto out_free; } spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs += pebs; @@ -512,6 +512,8 @@ out_acc: ubi->avail_pebs += pebs; spin_unlock(&ubi->volumes_lock); } + return err; + out_free: kfree(new_eba_tbl); return err; From 31d60afe2cc2b712dbefcaab6b7d6a47036f844e Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Fri, 21 Oct 2022 18:21:57 +0800 Subject: [PATCH 0562/1017] ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume() [ Upstream commit 1e591ea072df7211f64542a09482b5f81cb3ad27 ] There is a memory leaks problem reported by kmemleak: unreferenced object 0xffff888102007a00 (size 128): comm "ubirsvol", pid 32090, jiffies 4298464136 (age 2361.231s) hex dump (first 32 bytes): ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ backtrace: [] __kmalloc+0x4d/0x150 [] ubi_eba_create_table+0x76/0x170 [ubi] [] ubi_resize_volume+0x1be/0xbc0 [ubi] [] ubi_cdev_ioctl+0x701/0x1850 [ubi] [] __x64_sys_ioctl+0x11d/0x170 [] do_syscall_64+0x35/0x80 [] entry_SYSCALL_64_after_hwframe+0x46/0xb0 This is due to a mismatch between create and destroy interfaces, and in detail that "new_eba_tbl" created by ubi_eba_create_table() but destroyed by kfree(), while will causing "new_eba_tbl->entries" not freed. Fix it by replacing kfree(new_eba_tbl) with ubi_eba_destroy_table(new_eba_tbl) Fixes: 799dca34ac54 ("UBI: hide EBA internals") Signed-off-by: Li Zetao Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/vmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 6c7822c1cc45..2e5bd473e5e2 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -515,7 +515,7 @@ out_acc: return err; out_free: - kfree(new_eba_tbl); + ubi_eba_destroy_table(new_eba_tbl); return err; } From bf50229494f0443b3f08427d7df63e5a7e2a796a Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Sat, 22 Oct 2022 19:52:11 +0800 Subject: [PATCH 0563/1017] ubifs: Fix memory leak in alloc_wbufs() [ Upstream commit 4a1ff3c5d04b9079b4f768d9a71b51c4af578dd2 ] kmemleak reported a sequence of memory leaks, and show them as following: unreferenced object 0xffff8881575f8400 (size 1024): comm "mount", pid 19625, jiffies 4297119604 (age 20.383s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] __kmalloc+0x4d/0x150 [] ubifs_mount+0x307b/0x7170 [ubifs] [] legacy_get_tree+0xed/0x1d0 [] vfs_get_tree+0x7d/0x230 [] path_mount+0xdd4/0x17b0 [] __x64_sys_mount+0x1fa/0x270 [] do_syscall_64+0x35/0x80 [] entry_SYSCALL_64_after_hwframe+0x46/0xb0 unreferenced object 0xffff8881798a6e00 (size 512): comm "mount", pid 19677, jiffies 4297121912 (age 37.816s) hex dump (first 32 bytes): 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk backtrace: [] __kmalloc+0x4d/0x150 [] ubifs_wbuf_init+0x52/0x480 [ubifs] [] ubifs_mount+0x31f5/0x7170 [ubifs] [] legacy_get_tree+0xed/0x1d0 [] vfs_get_tree+0x7d/0x230 [] path_mount+0xdd4/0x17b0 [] __x64_sys_mount+0x1fa/0x270 [] do_syscall_64+0x35/0x80 [] entry_SYSCALL_64_after_hwframe+0x46/0xb0 The problem is that the ubifs_wbuf_init() returns an error in the loop which in the alloc_wbufs(), then the wbuf->buf and wbuf->inodes that were successfully alloced before are not freed. Fix it by adding error hanging path in alloc_wbufs() which frees the memory alloced before when ubifs_wbuf_init() returns an error. Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Signed-off-by: Li Zetao Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/super.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 6a8f9efc2e2f..1df193c87e92 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -833,7 +833,7 @@ static int alloc_wbufs(struct ubifs_info *c) INIT_LIST_HEAD(&c->jheads[i].buds_list); err = ubifs_wbuf_init(c, &c->jheads[i].wbuf); if (err) - return err; + goto out_wbuf; c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; c->jheads[i].wbuf.jhead = i; @@ -841,7 +841,7 @@ static int alloc_wbufs(struct ubifs_info *c) c->jheads[i].log_hash = ubifs_hash_get_desc(c); if (IS_ERR(c->jheads[i].log_hash)) { err = PTR_ERR(c->jheads[i].log_hash); - goto out; + goto out_log_hash; } } @@ -854,9 +854,18 @@ static int alloc_wbufs(struct ubifs_info *c) return 0; -out: - while (i--) +out_log_hash: + kfree(c->jheads[i].wbuf.buf); + kfree(c->jheads[i].wbuf.inodes); + +out_wbuf: + while (i--) { + kfree(c->jheads[i].wbuf.buf); + kfree(c->jheads[i].wbuf.inodes); kfree(c->jheads[i].log_hash); + } + kfree(c->jheads); + c->jheads = NULL; return err; } From fcbc795abe7897da4b5d2a6ab5010e36774b00c2 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 14 Nov 2022 18:26:24 +0800 Subject: [PATCH 0564/1017] ubi: Fix possible null-ptr-deref in ubi_free_volume() [ Upstream commit c15859bfd326c10230f09cb48a17f8a35f190342 ] It willl cause null-ptr-deref in the following case: uif_init() ubi_add_volume() cdev_add() -> if it fails, call kill_volumes() device_register() kill_volumes() -> if ubi_add_volume() fails call this function ubi_free_volume() cdev_del() device_unregister() -> trying to delete a not added device, it causes null-ptr-deref So in ubi_free_volume(), it delete devices whether they are added or not, it will causes null-ptr-deref. Handle the error case whlie calling ubi_add_volume() to fix this problem. If add volume fails, set the corresponding vol to null, so it can not be accessed in kill_volumes() and release the resource in ubi_add_volume() error path. Fixes: 801c135ce73d ("UBI: Unsorted Block Images") Suggested-by: Zhihao Cheng Signed-off-by: Yang Yingliang Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/build.c | 1 + drivers/mtd/ubi/vmt.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 8747569e793d..e45fdc1bf66a 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -467,6 +467,7 @@ static int uif_init(struct ubi_device *ubi) err = ubi_add_volume(ubi, ubi->volumes[i]); if (err) { ubi_err(ubi, "cannot add volume %d", i); + ubi->volumes[i] = NULL; goto out_volumes; } } diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 2e5bd473e5e2..d79323e8ea29 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -582,6 +582,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) if (err) { ubi_err(ubi, "cannot add character device for volume %d, error %d", vol_id, err); + vol_release(&vol->dev); return err; } @@ -592,15 +593,14 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) vol->dev.groups = volume_dev_groups; dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); err = device_register(&vol->dev); - if (err) - goto out_cdev; + if (err) { + cdev_del(&vol->cdev); + put_device(&vol->dev); + return err; + } self_check_volumes(ubi); return err; - -out_cdev: - cdev_del(&vol->cdev); - return err; } /** From 343d273d5fd06b6c065d4015506ae9ebbf6c64e6 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Fri, 18 Nov 2022 17:02:35 +0800 Subject: [PATCH 0565/1017] ubifs: Re-statistic cleaned znode count if commit failed [ Upstream commit 944e096aa24071d3fe22822f6249d3ae309e39ea ] Dirty znodes will be written on flash in committing process with following states: process A | znode state ------------------------------------------------------ do_commit | DIRTY_ZNODE ubifs_tnc_start_commit | DIRTY_ZNODE get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE layout_commit | DIRTY_ZNODE | COW_ZNODE fill_gap | 0 write master | 0 or OBSOLETE_ZNODE process B | znode state ------------------------------------------------------ do_commit | DIRTY_ZNODE[1] ubifs_tnc_start_commit | DIRTY_ZNODE get_znodes_to_commit | DIRTY_ZNODE | COW_ZNODE ubifs_tnc_end_commit | DIRTY_ZNODE | COW_ZNODE write_index | 0 write master | 0 or OBSOLETE_ZNODE[2] or | DIRTY_ZNODE[3] [1] znode is dirtied without concurrent committing process [2] znode is copied up (re-dirtied by other process) before cleaned up in committing process [3] znode is re-dirtied after cleaned up in committing process Currently, the clean znode count is updated in free_obsolete_znodes(), which is called only in normal path. If do_commit failed, clean znode count won't be updated, which triggers a failure ubifs assertion[4] in ubifs_tnc_close(): ubifs_assert_failed [ubifs]: UBIFS assert failed: freed == n [4] Commit 380347e9ca7682 ("UBIFS: Add an assertion for clean_zn_cnt"). Fix it by re-statisticing cleaned znode count in tnc_destroy_cnext(). Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216704 Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/tnc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 894f1ab14616..7c36b6677430 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -3053,6 +3053,21 @@ static void tnc_destroy_cnext(struct ubifs_info *c) cnext = cnext->cnext; if (ubifs_zn_obsolete(znode)) kfree(znode); + else if (!ubifs_zn_cow(znode)) { + /* + * Don't forget to update clean znode count after + * committing failed, because ubifs will check this + * count while closing tnc. Non-obsolete znode could + * be re-dirtied during committing process, so dirty + * flag is untrustable. The flag 'COW_ZNODE' is set + * for each dirty znode before committing, and it is + * cleared as long as the znode become clean, so we + * can statistic clean znode count according to this + * flag. + */ + atomic_long_inc(&c->clean_zn_cnt); + atomic_long_inc(&ubifs_clean_zn_cnt); + } } while (cnext && cnext != c->cnext); } From 9d4768523b092bfb9a9bfa6b1d903b968c8008cf Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Fri, 18 Nov 2022 17:02:36 +0800 Subject: [PATCH 0566/1017] ubifs: dirty_cow_znode: Fix memleak in error handling path [ Upstream commit 122deabfe1428bffe95e2bf364ff8a5059bdf089 ] Following process will cause a memleak for copied up znode: dirty_cow_znode zn = copy_znode(c, znode); err = insert_old_idx(c, zbr->lnum, zbr->offs); if (unlikely(err)) return ERR_PTR(err); // No one refers to zn. Fix it by adding copied znode back to tnc, then it will be freed by ubifs_destroy_tnc_subtree() while closing tnc. Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216705 Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/tnc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 7c36b6677430..07470449b960 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -267,11 +267,18 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, if (zbr->len) { err = insert_old_idx(c, zbr->lnum, zbr->offs); if (unlikely(err)) - return ERR_PTR(err); + /* + * Obsolete znodes will be freed by tnc_destroy_cnext() + * or free_obsolete_znodes(), copied up znodes should + * be added back to tnc and freed by + * ubifs_destroy_tnc_subtree(). + */ + goto out; err = add_idx_dirt(c, zbr->lnum, zbr->len); } else err = 0; +out: zbr->znode = zn; zbr->lnum = 0; zbr->offs = 0; From f09a84548c379d4257368aa05cb5273c42aa829d Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Wed, 1 Jun 2022 10:59:59 +0800 Subject: [PATCH 0567/1017] ubifs: ubifs_writepage: Mark page dirty after writing inode failed [ Upstream commit fb8bc4c74ae4526d9489362ab2793a936d072b84 ] There are two states for ubifs writing pages: 1. Dirty, Private 2. Not Dirty, Not Private There is a third possibility which maybe related to [1] that page is private but not dirty caused by following process: PA lock(page) ubifs_write_end attach_page_private // set Private __set_page_dirty_nobuffers // set Dirty unlock(page) write_cache_pages lock(page) clear_page_dirty_for_io(page) // clear Dirty ubifs_writepage write_inode // fail, goto out, following codes are not executed // do_writepage // set_page_writeback // set Writeback // detach_page_private // clear Private // end_page_writeback // clear Writeback out: unlock(page) // Private, Not Dirty PB ksys_fadvise64_64 generic_fadvise invalidate_inode_page // page is neither Dirty nor Writeback invalidate_complete_page // page_has_private is true try_to_release_page ubifs_releasepage ubifs_assert(c, 0) !!! Then we may get following assertion failed: UBIFS error (ubi0:0 pid 1492): ubifs_assert_failed [ubifs]: UBIFS assert failed: 0, in fs/ubifs/file.c:1499 UBIFS warning (ubi0:0 pid 1492): ubifs_ro_mode [ubifs]: switched to read-only mode, error -22 CPU: 2 PID: 1492 Comm: aa Not tainted 5.16.0-rc2-00012-g7bb767dee0ba-dirty Call Trace: dump_stack+0x13/0x1b ubifs_ro_mode+0x54/0x60 [ubifs] ubifs_assert_failed+0x4b/0x80 [ubifs] ubifs_releasepage+0x7e/0x1e0 [ubifs] try_to_release_page+0x57/0xe0 invalidate_inode_page+0xfb/0x130 invalidate_mapping_pagevec+0x12/0x20 generic_fadvise+0x303/0x3c0 vfs_fadvise+0x35/0x40 ksys_fadvise64_64+0x4c/0xb0 Jump [2] to find a reproducer. [1] https://linux-mtd.infradead.narkive.com/NQoBeT1u/patch-rfc-ubifs-fix-assert-failed-in-ubifs-set-page-dirty [2] https://bugzilla.kernel.org/show_bug.cgi?id=215357 Fixes: 1e51764a3c2ac0 ("UBIFS: add new flash file system") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/ubifs/file.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 354457e846cd..19fdcda04589 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1031,7 +1031,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc) if (page->index >= synced_i_size >> PAGE_SHIFT) { err = inode->i_sb->s_op->write_inode(inode, NULL); if (err) - goto out_unlock; + goto out_redirty; /* * The inode has been written, but the write-buffer has * not been synchronized, so in case of an unclean @@ -1059,11 +1059,17 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc) if (i_size > synced_i_size) { err = inode->i_sb->s_op->write_inode(inode, NULL); if (err) - goto out_unlock; + goto out_redirty; } return do_writepage(page, len); - +out_redirty: + /* + * redirty_page_for_writepage() won't call ubifs_dirty_inode() because + * it passes I_DIRTY_PAGES flag while calling __mark_inode_dirty(), so + * there is no need to do space budget for dirty inode. + */ + redirty_page_for_writepage(wbc, page); out_unlock: unlock_page(page); return err; From 0aa0253f6c99cf9b4fd2ec4e8591cba8dae4e88f Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Tue, 9 Aug 2022 15:06:19 +0800 Subject: [PATCH 0568/1017] ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling fastmap [ Upstream commit 76f9476ece445a07aeb72df9d896cd563fb5b50f ] After disabling fastmap(ubi->fm_disabled = 1), fastmap won't be updated, fm_anchor PEB is missed being scheduled for erasing. Besides, fm_anchor PEB may have smallest erase count, it doesn't participate wear-leveling. The difference of erase count between fm_anchor PEB and other PEBs will be larger and larger later on. In which situation fastmap can be disabled? Initially, we have an UBI image with fastmap. Then the image will be atttached without module parameter 'fm_autoconvert', ubi turns to full scanning mode in one random attaching process(eg. bad fastmap caused by powercut), ubi fastmap is disabled since then. Fix it by not getting fm_anchor if fastmap is disabled in ubi_refill_pools(). Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216341 Fixes: 4b68bf9a69d22d ("ubi: Select fastmap anchor PEBs considering ...") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/fastmap-wl.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 053ab52668e8..69592be33adf 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -146,13 +146,15 @@ void ubi_refill_pools(struct ubi_device *ubi) if (ubi->fm_anchor) { wl_tree_add(ubi->fm_anchor, &ubi->free); ubi->free_count++; + ubi->fm_anchor = NULL; } - /* - * All available PEBs are in ubi->free, now is the time to get - * the best anchor PEBs. - */ - ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1); + if (!ubi->fm_disabled) + /* + * All available PEBs are in ubi->free, now is the time to get + * the best anchor PEBs. + */ + ubi->fm_anchor = ubi_wl_get_fm_peb(ubi, 1); for (;;) { enough = 0; From 9d448dd6bcb61a508204b57ea1f454ba9bac2f24 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Sat, 30 Jul 2022 19:28:37 +0800 Subject: [PATCH 0569/1017] ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show() [ Upstream commit a240bc5c43130c6aa50831d7caaa02a1d84e1bce ] Wear-leveling entry could be freed in error path, which may be accessed again in eraseblk_count_seq_show(), for example: __erase_worker eraseblk_count_seq_show wl = ubi->lookuptbl[*block_number] if (wl) wl_entry_destroy ubi->lookuptbl[e->pnum] = NULL kmem_cache_free(ubi_wl_entry_slab, e) erase_count = wl->ec // UAF! Wear-leveling entry updating/accessing in ubi->lookuptbl should be protected by ubi->wl_lock, fix it by adding ubi->wl_lock to serialize wl entry accessing between wl_entry_destroy() and eraseblk_count_seq_show(). Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216305 Fixes: 7bccd12d27b7e3 ("ubi: Add debugfs file for tracking PEB state") Fixes: 801c135ce73d5d ("UBI: Unsorted Block Images") Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/wl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 820b5c1c8e8e..7406bc96affb 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -885,8 +885,11 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, err = do_sync_erase(ubi, e1, vol_id, lnum, 0); if (err) { - if (e2) + if (e2) { + spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e2); + spin_unlock(&ubi->wl_lock); + } goto out_ro; } @@ -1121,14 +1124,18 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk) /* Re-schedule the LEB for erasure */ err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false); if (err1) { + spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e); + spin_unlock(&ubi->wl_lock); err = err1; goto out_ro; } return err; } + spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e); + spin_unlock(&ubi->wl_lock); if (err != -EIO) /* * If this is not %-EIO, we have no idea what to do. Scheduling From 8a18856e074479bd050b01e688c58defadce7ab0 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Mon, 13 Jun 2022 14:59:04 +0800 Subject: [PATCH 0570/1017] ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed [ Upstream commit 4d57a7333e26040f2b583983e1970d9d460e56b0 ] Following process will trigger an infinite loop in ubi_wl_put_peb(): ubifs_bgt ubi_bgt ubifs_leb_unmap ubi_leb_unmap ubi_eba_unmap_leb ubi_wl_put_peb wear_leveling_worker e1 = rb_entry(rb_first(&ubi->used) e2 = get_peb_for_wl(ubi) ubi_io_read_vid_hdr // return err (flash fault) out_error: ubi->move_from = ubi->move_to = NULL wl_entry_destroy(ubi, e1) ubi->lookuptbl[e->pnum] = NULL retry: e = ubi->lookuptbl[pnum]; // return NULL if (e == ubi->move_from) { // NULL == NULL gets true goto retry; // infinite loop !!! $ top PID USER PR NI VIRT RES SHR S %CPU %MEM COMMAND 7676 root 20 0 0 0 0 R 100.0 0.0 ubifs_bgt0_0 Fix it by: 1) Letting ubi_wl_put_peb() returns directly if wearl leveling entry has been removed from 'ubi->lookuptbl'. 2) Using 'ubi->wl_lock' protecting wl entry deletion to preventing an use-after-free problem for wl entry in ubi_wl_put_peb(). Fetch a reproducer in [Link]. Fixes: 43f9b25a9cdd7b1 ("UBI: bugfix: protect from volume removal") Fixes: ee59ba8b064f692 ("UBI: Fix stale pointers in ubi->lookuptbl") Link: https://bugzilla.kernel.org/show_bug.cgi?id=216111 Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- drivers/mtd/ubi/wl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 7406bc96affb..6da09263e0b9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -971,11 +971,11 @@ out_error: spin_lock(&ubi->wl_lock); ubi->move_from = ubi->move_to = NULL; ubi->move_to_put = ubi->wl_scheduled = 0; + wl_entry_destroy(ubi, e1); + wl_entry_destroy(ubi, e2); spin_unlock(&ubi->wl_lock); ubi_free_vid_buf(vidb); - wl_entry_destroy(ubi, e1); - wl_entry_destroy(ubi, e2); out_ro: ubi_ro_mode(ubi); @@ -1251,6 +1251,18 @@ int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, retry: spin_lock(&ubi->wl_lock); e = ubi->lookuptbl[pnum]; + if (!e) { + /* + * This wl entry has been removed for some errors by other + * process (eg. wear leveling worker), corresponding process + * (except __erase_worker, which cannot concurrent with + * ubi_wl_put_peb) will set ubi ro_mode at the same time, + * just ignore this wl entry. + */ + spin_unlock(&ubi->wl_lock); + up_read(&ubi->fm_protect); + return 0; + } if (e == ubi->move_from) { /* * User is putting the physical eraseblock which was selected to From 7cb46fa16b96ff197eb84a33b23a8448fe0c1e8d Mon Sep 17 00:00:00 2001 From: Ammar Faizi Date: Sat, 24 Dec 2022 00:23:38 +0700 Subject: [PATCH 0571/1017] x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list [ Upstream commit 5541992e512de8c9133110809f767bd1b54ee10d ] The 'syscall' instruction clobbers '%rcx' and '%r11', but they are not listed in the inline Assembly that performs the syscall instruction. No real bug is found. It wasn't buggy by luck because '%rcx' and '%r11' are caller-saved registers, and not used in the functions, and the functions are never inlined. Add them to the clobber list for code correctness. Fixes: f1c2bb8b9964ed31de988910f8b1cfb586d30091 ("um: implement a x86_64 vDSO") Signed-off-by: Ammar Faizi Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- arch/x86/um/vdso/um_vdso.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/x86/um/vdso/um_vdso.c b/arch/x86/um/vdso/um_vdso.c index 2112b8d14668..ff0f3b4b6c45 100644 --- a/arch/x86/um/vdso/um_vdso.c +++ b/arch/x86/um/vdso/um_vdso.c @@ -17,8 +17,10 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts) { long ret; - asm("syscall" : "=a" (ret) : - "0" (__NR_clock_gettime), "D" (clock), "S" (ts) : "memory"); + asm("syscall" + : "=a" (ret) + : "0" (__NR_clock_gettime), "D" (clock), "S" (ts) + : "rcx", "r11", "memory"); return ret; } @@ -29,8 +31,10 @@ int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) { long ret; - asm("syscall" : "=a" (ret) : - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); + asm("syscall" + : "=a" (ret) + : "0" (__NR_gettimeofday), "D" (tv), "S" (tz) + : "rcx", "r11", "memory"); return ret; } From 273559f58f71512e4be929b78d4e05f60d48a60c Mon Sep 17 00:00:00 2001 From: ruanjinjie Date: Wed, 16 Nov 2022 17:49:50 +0800 Subject: [PATCH 0572/1017] watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in error path [ Upstream commit 07bec0e09c1afbab4c5674fd2341f4f52d594f30 ] free_irq() is missing in case of error in at91_wdt_init(), use devm_request_irq to fix that. Fixes: 5161b31dc39a ("watchdog: at91sam9_wdt: better watchdog support") Signed-off-by: ruanjinjie Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20221116094950.3141943-1-ruanjinjie@huawei.com [groeck: Adjust multi-line alignment] Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin --- drivers/watchdog/at91sam9_wdt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 292b5a1ca831..fed7be246442 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -206,10 +206,9 @@ static int at91_wdt_init(struct platform_device *pdev, struct at91wdt *wdt) "min heartbeat and max heartbeat might be too close for the system to handle it correctly\n"); if ((tmp & AT91_WDT_WDFIEN) && wdt->irq) { - err = request_irq(wdt->irq, wdt_interrupt, - IRQF_SHARED | IRQF_IRQPOLL | - IRQF_NO_SUSPEND, - pdev->name, wdt); + err = devm_request_irq(dev, wdt->irq, wdt_interrupt, + IRQF_SHARED | IRQF_IRQPOLL | IRQF_NO_SUSPEND, + pdev->name, wdt); if (err) return err; } From c5a21a5501508ae3afa2fe6d5a3e74a37fa48df3 Mon Sep 17 00:00:00 2001 From: Chen Jun Date: Wed, 16 Nov 2022 01:27:14 +0000 Subject: [PATCH 0573/1017] watchdog: Fix kmemleak in watchdog_cdev_register [ Upstream commit 13721a2ac66b246f5802ba1b75ad8637e53eeecc ] kmemleak reports memory leaks in watchdog_dev_register, as follows: unreferenced object 0xffff888116233000 (size 2048): comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s) hex dump (first 32 bytes): 80 fa b9 05 81 88 ff ff 08 30 23 16 81 88 ff ff .........0#..... 08 30 23 16 81 88 ff ff 00 00 00 00 00 00 00 00 .0#............. backtrace: [<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220 [<000000006a389304>] kmalloc_trace+0x21/0x110 [<000000008d640eea>] watchdog_dev_register+0x4e/0x780 [watchdog] [<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog] [<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog] [<000000001f730178>] 0xffffffffc10880ae [<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0 [<00000000b98be325>] do_init_module+0x1ca/0x5f0 [<0000000046d08e7c>] load_module+0x6133/0x70f0 ... unreferenced object 0xffff888105b9fa80 (size 16): comm ""modprobe"", pid 28147, jiffies 4353426116 (age 61.741s) hex dump (first 16 bytes): 77 61 74 63 68 64 6f 67 31 00 b9 05 81 88 ff ff watchdog1....... backtrace: [<000000007f001ffd>] __kmem_cache_alloc_node+0x157/0x220 [<00000000486ab89b>] __kmalloc_node_track_caller+0x44/0x1b0 [<000000005a39aab0>] kvasprintf+0xb5/0x140 [<0000000024806f85>] kvasprintf_const+0x55/0x180 [<000000009276cb7f>] kobject_set_name_vargs+0x56/0x150 [<00000000a92e820b>] dev_set_name+0xab/0xe0 [<00000000cec812c6>] watchdog_dev_register+0x285/0x780 [watchdog] [<0000000053c9f248>] __watchdog_register_device+0x4f0/0x680 [watchdog] [<00000000b2979824>] watchdog_register_device+0xd2/0x110 [watchdog] [<000000001f730178>] 0xffffffffc10880ae [<000000007a1a8bcc>] do_one_initcall+0xcb/0x4d0 [<00000000b98be325>] do_init_module+0x1ca/0x5f0 [<0000000046d08e7c>] load_module+0x6133/0x70f0 ... The reason is that put_device is not be called if cdev_device_add fails and wdd->id != 0. watchdog_cdev_register wd_data = kzalloc [1] err = dev_set_name [2] .. err = cdev_device_add if (err) { if (wdd->id == 0) { // wdd->id != 0 .. } return err; // [1],[2] would be leaked To fix it, call put_device in all wdd->id cases. Fixes: 72139dfa2464 ("watchdog: Fix the race between the release of watchdog_core_data and cdev") Signed-off-by: Chen Jun Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20221116012714.102066-1-chenjun102@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin --- drivers/watchdog/watchdog_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 2ee017442dfc..f37255cd75fd 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -1037,8 +1037,8 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) if (wdd->id == 0) { misc_deregister(&watchdog_miscdev); old_wd_data = NULL; - put_device(&wd_data->dev); } + put_device(&wd_data->dev); return err; } From 9f7abdd500269d044388593654a85afc3e174b91 Mon Sep 17 00:00:00 2001 From: Li Hua Date: Wed, 16 Nov 2022 10:07:06 +0800 Subject: [PATCH 0574/1017] watchdog: pcwd_usb: Fix attempting to access uninitialized memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 7d06c07c67100fd0f8e6b3ab7145ce789f788117 ] The stack variable msb and lsb may be used uninitialized in function usb_pcwd_get_temperature and usb_pcwd_get_timeleft when usb card no response. The build waring is: drivers/watchdog/pcwd_usb.c:336:22: error: ‘lsb’ is used uninitialized in this function [-Werror=uninitialized] *temperature = (lsb * 9 / 5) + 32; ~~~~^~~ drivers/watchdog/pcwd_usb.c:328:21: note: ‘lsb’ was declared here unsigned char msb, lsb; ^~~ cc1: all warnings being treated as errors scripts/Makefile.build:250: recipe for target 'drivers/watchdog/pcwd_usb.o' failed make[3]: *** [drivers/watchdog/pcwd_usb.o] Error 1 Fixes: b7e04f8c61a4 ("mv watchdog tree under drivers") Signed-off-by: Li Hua Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20221116020706.70847-1-hucool.lihua@huawei.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin --- drivers/watchdog/pcwd_usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 1bdaf17c1d38..8202f0a6b093 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -325,7 +325,8 @@ static int usb_pcwd_set_heartbeat(struct usb_pcwd_private *usb_pcwd, int t) static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temperature) { - unsigned char msb, lsb; + unsigned char msb = 0x00; + unsigned char lsb = 0x00; usb_pcwd_send_command(usb_pcwd, CMD_READ_TEMP, &msb, &lsb); @@ -341,7 +342,8 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left) { - unsigned char msb, lsb; + unsigned char msb = 0x00; + unsigned char lsb = 0x00; /* Read the time that's left before rebooting */ /* Note: if the board is not yet armed then we will read 0xFFFF */ From 1ff0b87df98b93e10ced45773aa7d35377355421 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Fri, 10 Feb 2023 15:17:30 +0800 Subject: [PATCH 0575/1017] netfilter: ctnetlink: fix possible refcount leak in ctnetlink_create_conntrack() [ Upstream commit ac4893980bbe79ce383daf9a0885666a30fe4c83 ] nf_ct_put() needs to be called to put the refcount got by nf_conntrack_find_get() to avoid refcount leak when nf_conntrack_hash_check_insert() fails. Fixes: 7d367e06688d ("netfilter: ctnetlink: fix soft lockup when netlink adds new entries (v2)") Signed-off-by: Hangyu Hua Acked-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_conntrack_netlink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2efdc50f978b..f8ba3bc25cf3 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -2359,12 +2359,15 @@ ctnetlink_create_conntrack(struct net *net, err = nf_conntrack_hash_check_insert(ct); if (err < 0) - goto err2; + goto err3; rcu_read_unlock(); return ct; +err3: + if (ct->master) + nf_ct_put(ct->master); err2: rcu_read_unlock(); err1: From 9060abce3305ab2354c892c09d5689df51486df5 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 17 Feb 2023 23:20:06 +0100 Subject: [PATCH 0576/1017] netfilter: ebtables: fix table blob use-after-free [ Upstream commit e58a171d35e32e6e8c37cfe0e8a94406732a331f ] We are not allowed to return an error at this point. Looking at the code it looks like ret is always 0 at this point, but its not. t = find_table_lock(net, repl->name, &ret, &ebt_mutex); ... this can return a valid table, with ret != 0. This bug causes update of table->private with the new blob, but then frees the blob right away in the caller. Syzbot report: BUG: KASAN: vmalloc-out-of-bounds in __ebt_unregister_table+0xc00/0xcd0 net/bridge/netfilter/ebtables.c:1168 Read of size 4 at addr ffffc90005425000 by task kworker/u4:4/74 Workqueue: netns cleanup_net Call Trace: kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 __ebt_unregister_table+0xc00/0xcd0 net/bridge/netfilter/ebtables.c:1168 ebt_unregister_table+0x35/0x40 net/bridge/netfilter/ebtables.c:1372 ops_exit_list+0xb0/0x170 net/core/net_namespace.c:169 cleanup_net+0x4ee/0xb10 net/core/net_namespace.c:613 ... ip(6)tables appears to be ok (ret should be 0 at this point) but make this more obvious. Fixes: c58dd2dd443c ("netfilter: Can't fail and free after table replacement") Reported-by: syzbot+f61594de72d6705aea03@syzkaller.appspotmail.com Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/bridge/netfilter/ebtables.c | 2 +- net/ipv4/netfilter/ip_tables.c | 3 +-- net/ipv6/netfilter/ip6_tables.c | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 06b80b584381..8335b7e4bcf6 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1049,7 +1049,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries, AUDIT_XT_OP_REPLACE, GFP_KERNEL); - return ret; + return 0; free_unlock: mutex_unlock(&ebt_mutex); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index f77ea0dbe656..ec981618b7b2 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1044,7 +1044,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, struct xt_counters *counters; struct ipt_entry *iter; - ret = 0; counters = xt_counters_alloc(num_counters); if (!counters) { ret = -ENOMEM; @@ -1090,7 +1089,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n"); } vfree(counters); - return ret; + return 0; put_module: module_put(t->me); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index d36168baf677..99bb11d16712 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1062,7 +1062,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, struct xt_counters *counters; struct ip6t_entry *iter; - ret = 0; counters = xt_counters_alloc(num_counters); if (!counters) { ret = -ENOMEM; @@ -1108,7 +1107,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n"); } vfree(counters); - return ret; + return 0; put_module: module_put(t->me); From da26369377f0b671c14692e2d65ceb38131053e1 Mon Sep 17 00:00:00 2001 From: Lu Wei Date: Wed, 22 Feb 2023 16:36:28 +0800 Subject: [PATCH 0577/1017] ipv6: Add lwtunnel encap size of all siblings in nexthop calculation [ Upstream commit 4cc59f386991ec9374cb4bc83dbe1c0b5a95033f ] In function rt6_nlmsg_size(), the length of nexthop is calculated by multipling the nexthop length of fib6_info and the number of siblings. However if the fib6_info has no lwtunnel but the siblings have lwtunnels, the nexthop length is less than it should be, and it will trigger a warning in inet6_rt_notify() as follows: WARNING: CPU: 0 PID: 6082 at net/ipv6/route.c:6180 inet6_rt_notify+0x120/0x130 ...... Call Trace: fib6_add_rt2node+0x685/0xa30 fib6_add+0x96/0x1b0 ip6_route_add+0x50/0xd0 inet6_rtm_newroute+0x97/0xa0 rtnetlink_rcv_msg+0x156/0x3d0 netlink_rcv_skb+0x5a/0x110 netlink_unicast+0x246/0x350 netlink_sendmsg+0x250/0x4c0 sock_sendmsg+0x66/0x70 ___sys_sendmsg+0x7c/0xd0 __sys_sendmsg+0x5d/0xb0 do_syscall_64+0x3f/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc This bug can be reproduced by script: ip -6 addr add 2002::2/64 dev ens2 ip -6 route add 100::/64 via 2002::1 dev ens2 metric 100 for i in 10 20 30 40 50 60 70; do ip link add link ens2 name ipv_$i type ipvlan ip -6 addr add 2002::$i/64 dev ipv_$i ifconfig ipv_$i up done for i in 10 20 30 40 50 60; do ip -6 route append 100::/64 encap ip6 dst 2002::$i via 2002::1 dev ipv_$i metric 100 done ip -6 route append 100::/64 via 2002::1 dev ipv_70 metric 100 This patch fixes it by adding nexthop_len of every siblings using rt6_nh_nlmsg_size(). Fixes: beb1afac518d ("net: ipv6: Add support to dump multipath routes via RTA_MULTIPATH attribute") Signed-off-by: Lu Wei Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20230222083629.335683-2-luwei32@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/ipv6/route.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 803d1aa83140..a6d5c99f65a3 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -5444,16 +5444,17 @@ static size_t rt6_nlmsg_size(struct fib6_info *f6i) nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size, &nexthop_len); } else { + struct fib6_info *sibling, *next_sibling; struct fib6_nh *nh = f6i->fib6_nh; nexthop_len = 0; if (f6i->fib6_nsiblings) { - nexthop_len = nla_total_size(0) /* RTA_MULTIPATH */ - + NLA_ALIGN(sizeof(struct rtnexthop)) - + nla_total_size(16) /* RTA_GATEWAY */ - + lwtunnel_get_encap_size(nh->fib_nh_lws); + rt6_nh_nlmsg_size(nh, &nexthop_len); - nexthop_len *= f6i->fib6_nsiblings; + list_for_each_entry_safe(sibling, next_sibling, + &f6i->fib6_siblings, fib6_siblings) { + rt6_nh_nlmsg_size(sibling->fib6_nh, &nexthop_len); + } } nexthop_len += lwtunnel_get_encap_size(nh->fib_nh_lws); } From 8ee401f89cdb10f39098c0656d695b2bc4052100 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Wed, 22 Feb 2023 12:07:21 -0500 Subject: [PATCH 0578/1017] sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop [ Upstream commit 68ba44639537de6f91fe32783766322d41848127 ] With this refcnt added in sctp_stream_priorities, we don't need to traverse all streams to check if the prio is used by other streams when freeing one stream's prio in sctp_sched_prio_free_sid(). This can avoid a nested loop (up to 65535 * 65535), which may cause a stuck as Ying reported: watchdog: BUG: soft lockup - CPU#23 stuck for 26s! [ksoftirqd/23:136] Call Trace: sctp_sched_prio_free_sid+0xab/0x100 [sctp] sctp_stream_free_ext+0x64/0xa0 [sctp] sctp_stream_free+0x31/0x50 [sctp] sctp_association_free+0xa5/0x200 [sctp] Note that it doesn't need to use refcount_t type for this counter, as its accessing is always protected under the sock lock. v1->v2: - add a check in sctp_sched_prio_set to avoid the possible prio_head refcnt overflow. Fixes: 9ed7bfc79542 ("sctp: fix memory leak in sctp_stream_outq_migrate()") Reported-by: Ying Xu Acked-by: Marcelo Ricardo Leitner Signed-off-by: Xin Long Link: https://lore.kernel.org/r/825eb0c905cb864991eba335f4a2b780e543f06b.1677085641.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/net/sctp/structs.h | 1 + net/sctp/stream_sched_prio.c | 52 +++++++++++++++--------------------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index be9ff0422c16..be59e8df0bff 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1394,6 +1394,7 @@ struct sctp_stream_priorities { /* The next stream in line */ struct sctp_stream_out_ext *next; __u16 prio; + __u16 users; }; struct sctp_stream_out_ext { diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c index 4fc9f2923ed1..7dd9f8b387cc 100644 --- a/net/sctp/stream_sched_prio.c +++ b/net/sctp/stream_sched_prio.c @@ -25,6 +25,18 @@ static void sctp_sched_prio_unsched_all(struct sctp_stream *stream); +static struct sctp_stream_priorities *sctp_sched_prio_head_get(struct sctp_stream_priorities *p) +{ + p->users++; + return p; +} + +static void sctp_sched_prio_head_put(struct sctp_stream_priorities *p) +{ + if (p && --p->users == 0) + kfree(p); +} + static struct sctp_stream_priorities *sctp_sched_prio_new_head( struct sctp_stream *stream, int prio, gfp_t gfp) { @@ -38,6 +50,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_new_head( INIT_LIST_HEAD(&p->active); p->next = NULL; p->prio = prio; + p->users = 1; return p; } @@ -53,7 +66,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_get_head( */ list_for_each_entry(p, &stream->prio_list, prio_sched) { if (p->prio == prio) - return p; + return sctp_sched_prio_head_get(p); if (p->prio > prio) break; } @@ -70,7 +83,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_get_head( */ break; if (p->prio == prio) - return p; + return sctp_sched_prio_head_get(p); } /* If not even there, allocate a new one. */ @@ -154,32 +167,21 @@ static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid, struct sctp_stream_out_ext *soute = sout->ext; struct sctp_stream_priorities *prio_head, *old; bool reschedule = false; - int i; + + old = soute->prio_head; + if (old && old->prio == prio) + return 0; prio_head = sctp_sched_prio_get_head(stream, prio, gfp); if (!prio_head) return -ENOMEM; reschedule = sctp_sched_prio_unsched(soute); - old = soute->prio_head; soute->prio_head = prio_head; if (reschedule) sctp_sched_prio_sched(stream, soute); - if (!old) - /* Happens when we set the priority for the first time */ - return 0; - - for (i = 0; i < stream->outcnt; i++) { - soute = SCTP_SO(stream, i)->ext; - if (soute && soute->prio_head == old) - /* It's still in use, nothing else to do here. */ - return 0; - } - - /* No hits, we are good to free it. */ - kfree(old); - + sctp_sched_prio_head_put(old); return 0; } @@ -206,20 +208,8 @@ static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid, static void sctp_sched_prio_free_sid(struct sctp_stream *stream, __u16 sid) { - struct sctp_stream_priorities *prio = SCTP_SO(stream, sid)->ext->prio_head; - int i; - - if (!prio) - return; - + sctp_sched_prio_head_put(SCTP_SO(stream, sid)->ext->prio_head); SCTP_SO(stream, sid)->ext->prio_head = NULL; - for (i = 0; i < stream->outcnt; i++) { - if (SCTP_SO(stream, i)->ext && - SCTP_SO(stream, i)->ext->prio_head == prio) - return; - } - - kfree(prio); } static void sctp_sched_prio_free(struct sctp_stream *stream) From 82a0c1fe1fe0a0b9957e8f6a0b99884f64ba0ba4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Feb 2023 08:38:45 +0000 Subject: [PATCH 0579/1017] net: fix __dev_kfree_skb_any() vs drop monitor [ Upstream commit ac3ad19584b26fae9ac86e4faebe790becc74491 ] dev_kfree_skb() is aliased to consume_skb(). When a driver is dropping a packet by calling dev_kfree_skb_any() we should propagate the drop reason instead of pretending the packet was consumed. Note: Now we have enum skb_drop_reason we could remove enum skb_free_reason (for linux-6.4) v2: added an unlikely(), suggested by Yunsheng Lin. Fixes: e6247027e517 ("net: introduce dev_consume_skb_any()") Signed-off-by: Eric Dumazet Cc: Yunsheng Lin Reviewed-by: Yunsheng Lin Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index b7646d4e079b..8cbcb6a104f2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3119,8 +3119,10 @@ void __dev_kfree_skb_any(struct sk_buff *skb, enum skb_free_reason reason) { if (in_irq() || irqs_disabled()) __dev_kfree_skb_irq(skb, reason); + else if (unlikely(reason == SKB_REASON_DROPPED)) + kfree_skb(skb); else - dev_kfree_skb(skb); + consume_skb(skb); } EXPORT_SYMBOL(__dev_kfree_skb_any); From c959a53b62a6d5bdcf6f2c4295714f68a2381f6a Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 30 Jan 2023 12:30:35 +0100 Subject: [PATCH 0580/1017] 9p/xen: fix version parsing [ Upstream commit f1956f4ec15195ec60976d9b5625326285ab102e ] When connecting the Xen 9pfs frontend to the backend, the "versions" Xenstore entry written by the backend is parsed in a wrong way. The "versions" entry is defined to contain the versions supported by the backend separated by commas (e.g. "1,2"). Today only version "1" is defined. Unfortunately the frontend doesn't look for "1" being listed in the entry, but it is expecting the entry to have the value "1". This will result in failure as soon as the backend will support e.g. versions "1" and "2". Fix that by scanning the entry correctly. Link: https://lkml.kernel.org/r/20230130113036.7087-2-jgross@suse.com Fixes: 71ebd71921e4 ("xen/9pfs: connect to the backend") Signed-off-by: Juergen Gross Reviewed-by: Simon Horman Signed-off-by: Dominique Martinet Signed-off-by: Eric Van Hensbergen Signed-off-by: Sasha Levin --- net/9p/trans_xen.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 6c8a33f98f09..d8ed75e8dbb1 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -399,13 +399,19 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, int ret, i; struct xenbus_transaction xbt; struct xen_9pfs_front_priv *priv = NULL; - char *versions; + char *versions, *v; unsigned int max_rings, max_ring_order, len = 0; versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len); if (IS_ERR(versions)) return PTR_ERR(versions); - if (strcmp(versions, "1")) { + for (v = versions; *v; v++) { + if (simple_strtoul(v, &v, 10) == 1) { + v = NULL; + break; + } + } + if (v) { kfree(versions); return -EINVAL; } From 3e0359f151ac151abe3fa71040e450ed69cb824b Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 30 Jan 2023 12:30:36 +0100 Subject: [PATCH 0581/1017] 9p/xen: fix connection sequence [ Upstream commit c15fe55d14b3b4ded5af2a3260877460a6ffb8ad ] Today the connection sequence of the Xen 9pfs frontend doesn't match the documented sequence. It can work reliably only for a PV 9pfs device having been added at boot time already, as the frontend is not waiting for the backend to have set its state to "XenbusStateInitWait" before reading the backend properties from Xenstore. Fix that by following the documented sequence [1] (the documentation has a bug, so the reference is for the patch fixing that). [1]: https://lore.kernel.org/xen-devel/20230130090937.31623-1-jgross@suse.com/T/#u Link: https://lkml.kernel.org/r/20230130113036.7087-3-jgross@suse.com Fixes: 868eb122739a ("xen/9pfs: introduce Xen 9pfs transport driver") Signed-off-by: Juergen Gross Reviewed-by: Simon Horman Signed-off-by: Dominique Martinet Signed-off-by: Eric Van Hensbergen Signed-off-by: Sasha Levin --- net/9p/trans_xen.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index d8ed75e8dbb1..220e8f4ac0cf 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -393,12 +393,11 @@ out: return ret; } -static int xen_9pfs_front_probe(struct xenbus_device *dev, - const struct xenbus_device_id *id) +static int xen_9pfs_front_init(struct xenbus_device *dev) { int ret, i; struct xenbus_transaction xbt; - struct xen_9pfs_front_priv *priv = NULL; + struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev); char *versions, *v; unsigned int max_rings, max_ring_order, len = 0; @@ -426,11 +425,6 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order)) p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->dev = dev; priv->num_rings = XEN_9PFS_NUM_RINGS; priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings), GFP_KERNEL); @@ -489,23 +483,35 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, goto error; } - write_lock(&xen_9pfs_lock); - list_add_tail(&priv->list, &xen_9pfs_devs); - write_unlock(&xen_9pfs_lock); - dev_set_drvdata(&dev->dev, priv); - xenbus_switch_state(dev, XenbusStateInitialised); - return 0; error_xenbus: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, ret, "writing xenstore"); error: - dev_set_drvdata(&dev->dev, NULL); xen_9pfs_front_free(priv); return ret; } +static int xen_9pfs_front_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + struct xen_9pfs_front_priv *priv = NULL; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + dev_set_drvdata(&dev->dev, priv); + + write_lock(&xen_9pfs_lock); + list_add_tail(&priv->list, &xen_9pfs_devs); + write_unlock(&xen_9pfs_lock); + + return 0; +} + static int xen_9pfs_front_resume(struct xenbus_device *dev) { dev_warn(&dev->dev, "suspend/resume unsupported\n"); @@ -524,6 +530,8 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev, break; case XenbusStateInitWait: + if (!xen_9pfs_front_init(dev)) + xenbus_switch_state(dev, XenbusStateInitialised); break; case XenbusStateConnected: From 0ac65fab2b3f121e4d606b3729cf06da0bfc8885 Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Wed, 4 Jan 2023 10:04:24 +0800 Subject: [PATCH 0582/1017] 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv() [ Upstream commit 74a25e6e916cb57dab4267a96fbe8864ed21abdb ] When down_interruptible() or ib_post_send() failed in rdma_request(), receive dma buffer is not unmapped. Add unmap action to error path. Also if ib_post_recv() failed in post_recv(), dma buffer is not unmapped. Add unmap action to error path. Link: https://lkml.kernel.org/r/20230104020424.611926-1-shaozhengchao@huawei.com Fixes: fc79d4b104f0 ("9p: rdma: RDMA Transport Support for 9P") Signed-off-by: Zhengchao Shao Reviewed-by: Leon Romanovsky Signed-off-by: Dominique Martinet Signed-off-by: Eric Van Hensbergen Signed-off-by: Sasha Levin --- net/9p/trans_rdma.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 2885ff9c76f0..7217bd9886e3 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c @@ -386,6 +386,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c) struct p9_trans_rdma *rdma = client->trans; struct ib_recv_wr wr; struct ib_sge sge; + int ret; c->busa = ib_dma_map_single(rdma->cm_id->device, c->rc.sdata, client->msize, @@ -403,7 +404,12 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c) wr.wr_cqe = &c->cqe; wr.sg_list = &sge; wr.num_sge = 1; - return ib_post_recv(rdma->qp, &wr, NULL); + + ret = ib_post_recv(rdma->qp, &wr, NULL); + if (ret) + ib_dma_unmap_single(rdma->cm_id->device, c->busa, + client->msize, DMA_FROM_DEVICE); + return ret; error: p9_debug(P9_DEBUG_ERROR, "EIO\n"); @@ -500,7 +506,7 @@ dont_need_post_recv: if (down_interruptible(&rdma->sq_sem)) { err = -EINTR; - goto send_error; + goto dma_unmap; } /* Mark request as `sent' *before* we actually send it, @@ -510,11 +516,14 @@ dont_need_post_recv: req->status = REQ_STATUS_SENT; err = ib_post_send(rdma->qp, &wr, NULL); if (err) - goto send_error; + goto dma_unmap; /* Success */ return 0; +dma_unmap: + ib_dma_unmap_single(rdma->cm_id->device, c->busa, + c->req->tc.size, DMA_TO_DEVICE); /* Handle errors that happened during or while preparing the send: */ send_error: req->status = REQ_STATUS_ERROR; From 8817602cffe0107834865b5d2c2fb7f77132d7dc Mon Sep 17 00:00:00 2001 From: Maor Dickman Date: Wed, 8 Feb 2023 17:44:06 +0200 Subject: [PATCH 0583/1017] net/mlx5: Geneve, Fix handling of Geneve object id as error code [ Upstream commit d28a06d7dbedc598a06bd1e53a28125f87ca5d0c ] On success, mlx5_geneve_tlv_option_create returns non negative Geneve object id. In case the object id is positive value the caller functions will handle it as an error (non zero) and will fail to offload the Geneve rule. Fix this by changing caller function ,mlx5_geneve_tlv_option_add, to return 0 in case valid non negative object id was provided. Fixes: 0ccc171ea6a2 ("net/mlx5: Geneve, Manage Geneve TLV options") Signed-off-by: Maor Dickman Reviewed-by: Raed Salem Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c index 23361a9ae4fa..6dc83e871cd7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c @@ -105,6 +105,7 @@ int mlx5_geneve_tlv_option_add(struct mlx5_geneve *geneve, struct geneve_opt *op geneve->opt_type = opt->type; geneve->obj_id = res; geneve->refcount++; + res = 0; } unlock: From 8978315cb4bf8878c9c8ec05dafd8f7ff539860d Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Sat, 25 Feb 2023 13:56:14 +0300 Subject: [PATCH 0584/1017] nfc: fix memory leak of se_io context in nfc_genl_se_io [ Upstream commit 25ff6f8a5a3b8dc48e8abda6f013e8cc4b14ffea ] The callback context for sending/receiving APDUs to/from the selected secure element is allocated inside nfc_genl_se_io and supposed to be eventually freed in se_io_cb callback function. However, there are several error paths where the bwi_timer is not charged to call se_io_cb later, and the cb_context is leaked. The patch proposes to free the cb_context explicitly on those error paths. At the moment we can't simply check 'dev->ops->se_io()' return value as it may be negative in both cases: when the timer was charged and was not. Fixes: 5ce3f32b5264 ("NFC: netlink: SE API implementation") Reported-by: syzbot+df64c0a2e8d68e78a4fa@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin Signed-off-by: Alexey Khoroshilov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/nfc/st-nci/se.c | 6 ++++++ drivers/nfc/st21nfca/se.c | 6 ++++++ net/nfc/netlink.c | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c index 37d397aae9b9..a14afceaf5e9 100644 --- a/drivers/nfc/st-nci/se.c +++ b/drivers/nfc/st-nci/se.c @@ -664,6 +664,12 @@ int st_nci_se_io(struct nci_dev *ndev, u32 se_idx, ST_NCI_EVT_TRANSMIT_DATA, apdu, apdu_length); default: + /* Need to free cb_context here as at the moment we can't + * clearly indicate to the caller if the callback function + * would be called (and free it) or not. In both cases a + * negative value may be returned to the caller. + */ + kfree(cb_context); return -ENODEV; } } diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index d41636504246..6a1d3b2752fb 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -236,6 +236,12 @@ int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, ST21NFCA_EVT_TRANSMIT_DATA, apdu, apdu_length); default: + /* Need to free cb_context here as at the moment we can't + * clearly indicate to the caller if the callback function + * would be called (and free it) or not. In both cases a + * negative value may be returned to the caller. + */ + kfree(cb_context); return -ENODEV; } } diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 610caea4feec..3f4785be066a 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -1442,7 +1442,11 @@ static int nfc_se_io(struct nfc_dev *dev, u32 se_idx, rc = dev->ops->se_io(dev, se_idx, apdu, apdu_length, cb, cb_context); + device_unlock(&dev->dev); + return rc; + error: + kfree(cb_context); device_unlock(&dev->dev); return rc; } From 2f935409cd82f45205b597cd93efbd7cfb10d54c Mon Sep 17 00:00:00 2001 From: Pedro Tammela Date: Fri, 24 Feb 2023 12:00:58 -0300 Subject: [PATCH 0585/1017] net/sched: act_sample: fix action bind logic [ Upstream commit 4a20056a49a1854966562241922f68197f950539 ] The TC architecture allows filters and actions to be created independently. In filters the user can reference action objects using: tc action add action sample ... index 1 tc filter add ... action pedit index 1 In the current code for act_sample this is broken as it checks netlink attributes for create/update before actually checking if we are binding to an existing action. tdc results: 1..29 ok 1 9784 - Add valid sample action with mandatory arguments ok 2 5c91 - Add valid sample action with mandatory arguments and continue control action ok 3 334b - Add valid sample action with mandatory arguments and drop control action ok 4 da69 - Add valid sample action with mandatory arguments and reclassify control action ok 5 13ce - Add valid sample action with mandatory arguments and pipe control action ok 6 1886 - Add valid sample action with mandatory arguments and jump control action ok 7 7571 - Add sample action with invalid rate ok 8 b6d4 - Add sample action with mandatory arguments and invalid control action ok 9 a874 - Add invalid sample action without mandatory arguments ok 10 ac01 - Add invalid sample action without mandatory argument rate ok 11 4203 - Add invalid sample action without mandatory argument group ok 12 14a7 - Add invalid sample action without mandatory argument group ok 13 8f2e - Add valid sample action with trunc argument ok 14 45f8 - Add sample action with maximum rate argument ok 15 ad0c - Add sample action with maximum trunc argument ok 16 83a9 - Add sample action with maximum group argument ok 17 ed27 - Add sample action with invalid rate argument ok 18 2eae - Add sample action with invalid group argument ok 19 6ff3 - Add sample action with invalid trunc size ok 20 2b2a - Add sample action with invalid index ok 21 dee2 - Add sample action with maximum allowed index ok 22 560e - Add sample action with cookie ok 23 704a - Replace existing sample action with new rate argument ok 24 60eb - Replace existing sample action with new group argument ok 25 2cce - Replace existing sample action with new trunc argument ok 26 59d1 - Replace existing sample action with new control argument ok 27 0a6e - Replace sample action with invalid goto chain control ok 28 3872 - Delete sample action with valid index ok 29 a394 - Delete sample action with invalid index Fixes: 5c5670fae430 ("net/sched: Introduce sample tc action") Reviewed-by: Jamal Hadi Salim Signed-off-by: Pedro Tammela Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/act_sample.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 2f0e98bcf494..6988a9cf4080 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c @@ -54,8 +54,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, sample_policy, NULL); if (ret < 0) return ret; - if (!tb[TCA_SAMPLE_PARMS] || !tb[TCA_SAMPLE_RATE] || - !tb[TCA_SAMPLE_PSAMPLE_GROUP]) + + if (!tb[TCA_SAMPLE_PARMS]) return -EINVAL; parm = nla_data(tb[TCA_SAMPLE_PARMS]); @@ -79,6 +79,13 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla, tcf_idr_release(*a, bind); return -EEXIST; } + + if (!tb[TCA_SAMPLE_RATE] || !tb[TCA_SAMPLE_PSAMPLE_GROUP]) { + NL_SET_ERR_MSG(extack, "sample rate and group are required"); + err = -EINVAL; + goto release_idr; + } + err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); if (err < 0) goto release_idr; From 4d08ed4651a105224b97f53f6a586a3efa175498 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 25 Feb 2023 17:22:37 +0100 Subject: [PATCH 0586/1017] ARM: dts: spear320-hmi: correct STMPE GPIO compatible [ Upstream commit 33a0c1b850c8c85f400531dab3a0b022cdb164b1 ] The compatible is st,stmpe-gpio. Fixes: e2eb69183ec4 ("ARM: SPEAr320: DT: Add SPEAr 320 HMI board support") Signed-off-by: Krzysztof Kozlowski Acked-by: Viresh Kumar Link: https://lore.kernel.org/r/20230225162237.40242-1-krzysztof.kozlowski@linaro.org Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- arch/arm/boot/dts/spear320-hmi.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts index 367ba48aac3e..5c562fb4886f 100644 --- a/arch/arm/boot/dts/spear320-hmi.dts +++ b/arch/arm/boot/dts/spear320-hmi.dts @@ -242,7 +242,7 @@ irq-trigger = <0x1>; stmpegpio: stmpe-gpio { - compatible = "stmpe,gpio"; + compatible = "st,stmpe-gpio"; reg = <0>; gpio-controller; #gpio-cells = <2>; From ac73d8f6a64a9be3ab1c9e8d9ed66d81aebc82f5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Feb 2023 08:33:36 +0000 Subject: [PATCH 0587/1017] tcp: tcp_check_req() can be called from process context [ Upstream commit 580f98cc33a260bb8c6a39ae2921b29586b84fdf ] This is a follow up of commit 0a375c822497 ("tcp: tcp_rtx_synack() can be called from process context"). Frederick Lawler reported another "__this_cpu_add() in preemptible" warning caused by the same reason. In my former patch I took care of tcp_rtx_synack() but forgot that tcp_check_req() also contained some SNMP updates. Note that some parts of tcp_check_req() always run in BH context, I added a comment to clarify this. Fixes: 8336886f786f ("tcp: TCP Fast Open Server - support TFO listeners") Link: https://lore.kernel.org/netdev/8cd33923-a21d-397c-e46b-2a068c287b03@cloudflare.com/T/ Signed-off-by: Eric Dumazet Reported-by: Frederick Lawler Tested-by: Frederick Lawler Link: https://lore.kernel.org/r/20230227083336.4153089-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/tcp_minisocks.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index e42312321191..8d854feebdb0 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -565,6 +565,9 @@ EXPORT_SYMBOL(tcp_create_openreq_child); * validation and inside tcp_v4_reqsk_send_ack(). Can we do better? * * We don't need to initialize tmp_opt.sack_ok as we don't use the results + * + * Note: If @fastopen is true, this can be called from process context. + * Otherwise, this is from BH context. */ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, @@ -717,7 +720,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, &tcp_rsk(req)->last_oow_ack_time)) req->rsk_ops->send_ack(sk, skb, req); if (paws_reject) - __NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); + NET_INC_STATS(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED); return NULL; } @@ -736,7 +739,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, * "fourth, check the SYN bit" */ if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { - __TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); + TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); goto embryonic_reset; } From 3e734e694181b27687ce17da3229aa8edfd21760 Mon Sep 17 00:00:00 2001 From: George Kennedy Date: Mon, 27 Feb 2023 15:21:41 -0500 Subject: [PATCH 0588/1017] vc_screen: modify vcs_size() handling in vcs_read() [ Upstream commit 46d733d0efc79bc8430d63b57ab88011806d5180 ] Restore the vcs_size() handling in vcs_read() to what it had been in previous version. Fixes: 226fae124b2d ("vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF") Suggested-by: Jiri Slaby Signed-off-by: George Kennedy Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- drivers/tty/vt/vc_screen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 71e091f879f0..1dc07f9214d5 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -415,10 +415,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) */ size = vcs_size(vc, attr, uni_mode); if (size < 0) { - if (read) - break; ret = size; - goto unlock_out; + break; } if (pos >= size) break; From 555f315832ecc4ab9ffc94fbaea77ad3b5e98dd5 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 29 Dec 2022 15:53:19 -0600 Subject: [PATCH 0589/1017] rtc: sun6i: Always export the internal oscillator [ Upstream commit 344f4030f6c50a9db2d03021884c4bf36191b53a ] On all variants of the hardware, the internal oscillator is one possible parent for the AR100 clock. It needs to be exported so we can model that relationship correctly in the devicetree. Fixes: c56afc1844d6 ("rtc: sun6i: Expose internal oscillator through device tree") Signed-off-by: Samuel Holland Acked-by: Jernej Skrabec Link: https://lore.kernel.org/r/20221229215319.14145-1-samuel@sholland.org Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-sun6i.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 52b36b7c6129..a72856fb5252 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -128,7 +128,6 @@ struct sun6i_rtc_clk_data { unsigned int fixed_prescaler : 16; unsigned int has_prescaler : 1; unsigned int has_out_clk : 1; - unsigned int export_iosc : 1; unsigned int has_losc_en : 1; unsigned int has_auto_swt : 1; }; @@ -260,10 +259,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, /* Yes, I know, this is ugly. */ sun6i_rtc = rtc; - /* Only read IOSC name from device tree if it is exported */ - if (rtc->data->export_iosc) - of_property_read_string_index(node, "clock-output-names", 2, - &iosc_name); + of_property_read_string_index(node, "clock-output-names", 2, + &iosc_name); rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL, iosc_name, @@ -304,13 +301,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, goto err_register; } - clk_data->num = 2; + clk_data->num = 3; clk_data->hws[0] = &rtc->hw; clk_data->hws[1] = __clk_get_hw(rtc->ext_losc); - if (rtc->data->export_iosc) { - clk_data->hws[2] = rtc->int_osc; - clk_data->num = 3; - } + clk_data->hws[2] = rtc->int_osc; of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); return; @@ -350,7 +344,6 @@ static const struct sun6i_rtc_clk_data sun8i_h3_rtc_data = { .fixed_prescaler = 32, .has_prescaler = 1, .has_out_clk = 1, - .export_iosc = 1, }; static void __init sun8i_h3_rtc_clk_init(struct device_node *node) @@ -368,7 +361,6 @@ static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = { .fixed_prescaler = 32, .has_prescaler = 1, .has_out_clk = 1, - .export_iosc = 1, .has_losc_en = 1, .has_auto_swt = 1, }; From af5f9a47614755023d615f0ba4fd35e9e490f0fc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 14 Feb 2023 14:28:08 +0100 Subject: [PATCH 0590/1017] scsi: ipr: Work around fortify-string warning [ Upstream commit ee4e7dfe4ffc9ca50c6875757bd119abfe22b5c5 ] The ipr_log_vpd_compact() function triggers a fortified memcpy() warning about a potential string overflow with all versions of clang: In file included from drivers/scsi/ipr.c:43: In file included from include/linux/string.h:254: include/linux/fortify-string.h:520:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] __write_overflow_field(p_size_field, size); ^ include/linux/fortify-string.h:520:4: error: call to '__write_overflow_field' declared with 'warning' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror,-Wattribute-warning] 2 errors generated. I don't see anything actually wrong with the function, but this is the only instance I can reproduce of the fortification going wrong in the kernel at the moment, so the easiest solution may be to rewrite the function into something that does not trigger the warning. Instead of having a combined buffer for vendor/device/serial strings, use three separate local variables and just truncate the whitespace individually. Link: https://lore.kernel.org/r/20230214132831.2118392-1-arnd@kernel.org Cc: Kees Cook Fixes: 8cf093e275d0 ("[SCSI] ipr: Improved dual adapter errors") Signed-off-by: Arnd Bergmann Reviewed-by: Damien Le Moal Reviewed-by: Kees Cook Acked-by: Brian King Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ipr.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index a5e6fbd86ad4..8c376736a8f5 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -1516,23 +1516,22 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) } /** - * strip_and_pad_whitespace - Strip and pad trailing whitespace. - * @i: index into buffer - * @buf: string to modify + * strip_whitespace - Strip and pad trailing whitespace. + * @i: size of buffer + * @buf: string to modify * - * This function will strip all trailing whitespace, pad the end - * of the string with a single space, and NULL terminate the string. + * This function will strip all trailing whitespace and + * NUL terminate the string. * - * Return value: - * new length of string **/ -static int strip_and_pad_whitespace(int i, char *buf) +static void strip_whitespace(int i, char *buf) { + if (i < 1) + return; + i--; while (i && buf[i] == ' ') i--; - buf[i+1] = ' '; - buf[i+2] = '\0'; - return i + 2; + buf[i+1] = '\0'; } /** @@ -1547,19 +1546,21 @@ static int strip_and_pad_whitespace(int i, char *buf) static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, struct ipr_vpd *vpd) { - char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3]; - int i = 0; + char vendor_id[IPR_VENDOR_ID_LEN + 1]; + char product_id[IPR_PROD_ID_LEN + 1]; + char sn[IPR_SERIAL_NUM_LEN + 1]; - memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); - i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer); + memcpy(vendor_id, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); + strip_whitespace(IPR_VENDOR_ID_LEN, vendor_id); - memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN); - i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer); + memcpy(product_id, vpd->vpids.product_id, IPR_PROD_ID_LEN); + strip_whitespace(IPR_PROD_ID_LEN, product_id); - memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN); - buffer[IPR_SERIAL_NUM_LEN + i] = '\0'; + memcpy(sn, vpd->sn, IPR_SERIAL_NUM_LEN); + strip_whitespace(IPR_SERIAL_NUM_LEN, sn); - ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer); + ipr_hcam_err(hostrcb, "%s VPID/SN: %s %s %s\n", prefix, + vendor_id, product_id, sn); } /** From c79a924ed6afac1708dfd370ba66bcf6a852ced6 Mon Sep 17 00:00:00 2001 From: Zhong Jinghua Date: Tue, 21 Feb 2023 17:50:27 +0800 Subject: [PATCH 0591/1017] loop: loop_set_status_from_info() check before assignment [ Upstream commit 9f6ad5d533d1c71e51bdd06a5712c4fbc8768dfa ] In loop_set_status_from_info(), lo->lo_offset and lo->lo_sizelimit should be checked before reassignment, because if an overflow error occurs, the original correct value will be changed to the wrong value, and it will not be changed back. More, the original patch did not solve the problem, the value was set and ioctl returned an error, but the subsequent io used the value in the loop driver, which still caused an alarm: loop_handle_cmd do_req_filebacked loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; lo_rw_aio cmd->iocb.ki_pos = pos Fixes: c490a0b5a4f3 ("loop: Check for overflow while configuring loop") Signed-off-by: Zhong Jinghua Reviewed-by: Chaitanya Kulkarni Link: https://lore.kernel.org/r/20230221095027.3656193-1-zhongjinghua@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/loop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b10410585a74..d86fbea54652 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1029,13 +1029,13 @@ loop_set_status_from_info(struct loop_device *lo, if (err) return err; + /* Avoid assigning overflow values */ + if (info->lo_offset > LLONG_MAX || info->lo_sizelimit > LLONG_MAX) + return -EOVERFLOW; + lo->lo_offset = info->lo_offset; lo->lo_sizelimit = info->lo_sizelimit; - /* loff_t vars have been assigned __u64 */ - if (lo->lo_offset < 0 || lo->lo_sizelimit < 0) - return -EOVERFLOW; - memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); lo->lo_file_name[LO_NAME_SIZE-1] = 0; From c8e7c0ec458c677d2c55635c22a7118d5b303abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Fri, 24 Feb 2023 11:45:51 +0100 Subject: [PATCH 0592/1017] ASoC: adau7118: don't disable regulators on device unbind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b5bfa7277ee7d944421e0ef193586c6e34d7492c ] The regulators are supposed to be controlled through the set_bias_level() component callback. Moreover, the regulators are not enabled during probe and so, this would lead to a regulator unbalanced use count. Fixes: ca514c0f12b02 ("ASOC: Add ADAU7118 8 Channel PDM-to-I2S/TDM Converter driver") Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20230224104551.1139981-1-nuno.sa@analog.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/adau7118.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/sound/soc/codecs/adau7118.c b/sound/soc/codecs/adau7118.c index 841229dcbca1..305f294b7710 100644 --- a/sound/soc/codecs/adau7118.c +++ b/sound/soc/codecs/adau7118.c @@ -445,22 +445,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = { .non_legacy_dai_naming = 1, }; -static void adau7118_regulator_disable(void *data) -{ - struct adau7118_data *st = data; - int ret; - /* - * If we fail to disable DVDD, don't bother in trying IOVDD. We - * actually don't want to be left in the situation where DVDD - * is enabled and IOVDD is disabled. - */ - ret = regulator_disable(st->dvdd); - if (ret) - return; - - regulator_disable(st->iovdd); -} - static int adau7118_regulator_setup(struct adau7118_data *st) { st->iovdd = devm_regulator_get(st->dev, "iovdd"); @@ -482,8 +466,7 @@ static int adau7118_regulator_setup(struct adau7118_data *st) regcache_cache_only(st->map, true); } - return devm_add_action_or_reset(st->dev, adau7118_regulator_disable, - st); + return 0; } static int adau7118_parset_dt(const struct adau7118_data *st) From 2bc1f260ede1274a59db706768b6292a24d45128 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Feb 2022 19:23:32 +0000 Subject: [PATCH 0593/1017] ASoC: zl38060: Remove spurious gpiolib select [ Upstream commit 8e70aaae32b72d3088d18a3447b67112b3f5979a ] The usage of GPIOs is optional in the code so don't force on gpiolib when building it, avoiding warnings in randconfigs. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220202192333.3655269-6-broonie@kernel.org Signed-off-by: Mark Brown Stable-dep-of: 0de2cc3707b6 ("ASoC: zl38060 add gpiolib dependency") Signed-off-by: Sasha Levin --- sound/soc/codecs/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 25f331551f68..a96f18a9479e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1701,7 +1701,6 @@ config SND_SOC_WSA881X config SND_SOC_ZL38060 tristate "Microsemi ZL38060 Connected Home Audio Processor" depends on SPI_MASTER - select GPIOLIB select REGMAP help Support for ZL38060 Connected Home Audio Processor from Microsemi, From 01829cb8708912ab0a2ae50b35c04a929045c5bf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Feb 2023 09:58:26 +0100 Subject: [PATCH 0594/1017] ASoC: zl38060 add gpiolib dependency [ Upstream commit 0de2cc3707b6b6e2ad40bd24ce09a5c1f65d01e1 ] Without gpiolib, this driver fails to link: arm-linux-gnueabi-ld: sound/soc/codecs/zl38060.o: in function `chip_gpio_get': zl38060.c:(.text+0x30): undefined reference to `gpiochip_get_data' arm-linux-gnueabi-ld: sound/soc/codecs/zl38060.o: in function `zl38_spi_probe': zl38060.c:(.text+0xa18): undefined reference to `devm_gpiochip_add_data_with_key' This appears to have been in the driver since the start, but is hard to hit in randconfig testing since gpiolib is almost always selected by something else. Fixes: 52e8a94baf90 ("ASoC: Add initial ZL38060 driver") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230227085850.2503725-1-arnd@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a96f18a9479e..f1c9e563994b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1701,6 +1701,7 @@ config SND_SOC_WSA881X config SND_SOC_ZL38060 tristate "Microsemi ZL38060 Connected Home Audio Processor" depends on SPI_MASTER + depends on GPIOLIB select REGMAP help Support for ZL38060 Connected Home Audio Processor from Microsemi, From f73134231fa23e0856c15010db5f5c03693c1e92 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 27 Feb 2023 13:06:50 +0300 Subject: [PATCH 0595/1017] thermal: intel: quark_dts: fix error pointer dereference [ Upstream commit f1b930e740811d416de4d2074da48b6633a672c8 ] If alloc_soc_dts() fails, then we can just return. Trying to free "soc_dts" will lead to an Oops. Fixes: 8c1876939663 ("thermal: intel Quark SoC X1000 DTS thermal driver") Signed-off-by: Dan Carpenter Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/intel/intel_quark_dts_thermal.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/thermal/intel/intel_quark_dts_thermal.c b/drivers/thermal/intel/intel_quark_dts_thermal.c index 3eafc6b0e6c3..b43fbd5eaa6b 100644 --- a/drivers/thermal/intel/intel_quark_dts_thermal.c +++ b/drivers/thermal/intel/intel_quark_dts_thermal.c @@ -415,22 +415,14 @@ MODULE_DEVICE_TABLE(x86cpu, qrk_thermal_ids); static int __init intel_quark_thermal_init(void) { - int err = 0; - if (!x86_match_cpu(qrk_thermal_ids) || !iosf_mbi_available()) return -ENODEV; soc_dts = alloc_soc_dts(); - if (IS_ERR(soc_dts)) { - err = PTR_ERR(soc_dts); - goto err_free; - } + if (IS_ERR(soc_dts)) + return PTR_ERR(soc_dts); return 0; - -err_free: - free_soc_dts(soc_dts); - return err; } static void __exit intel_quark_thermal_exit(void) From e30b26e746175a775921b948479308644336b796 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 25 Feb 2023 21:39:52 -0800 Subject: [PATCH 0596/1017] thermal: intel: BXT_PMIC: select REGMAP instead of depending on it [ Upstream commit 1467fb960349dfa5e300658f1a409dde2cfb0c51 ] REGMAP is a hidden (not user visible) symbol. Users cannot set it directly thru "make *config", so drivers should select it instead of depending on it if they need it. Consistently using "select" or "depends on" can also help reduce Kconfig circular dependency issues. Therefore, change the use of "depends on REGMAP" to "select REGMAP". Fixes: b474303ffd57 ("thermal: add Intel BXT WhiskeyCove PMIC thermal driver") Signed-off-by: Randy Dunlap Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/intel/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/intel/Kconfig b/drivers/thermal/intel/Kconfig index 8025b21f43fa..b5427579fae5 100644 --- a/drivers/thermal/intel/Kconfig +++ b/drivers/thermal/intel/Kconfig @@ -60,7 +60,8 @@ endmenu config INTEL_BXT_PMIC_THERMAL tristate "Intel Broxton PMIC thermal driver" - depends on X86 && INTEL_SOC_PMIC_BXTWC && REGMAP + depends on X86 && INTEL_SOC_PMIC_BXTWC + select REGMAP help Select this driver for Intel Broxton PMIC with ADC channels monitoring system temperature measurements and alerts. From 25c9fba724bdfa66e4f0d19e8b3d331eca798be9 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Fri, 13 Jan 2023 20:55:01 +0800 Subject: [PATCH 0597/1017] tracing: Add NULL checks for buffer in ring_buffer_free_read_page() [ Upstream commit 3e4272b9954094907f16861199728f14002fcaf6 ] In a previous commit 7433632c9ff6, buffer, buffer->buffers and buffer->buffers[cpu] in ring_buffer_wake_waiters() can be NULL, and thus the related checks are added. However, in the same call stack, these variables are also used in ring_buffer_free_read_page(): tracing_buffers_release() ring_buffer_wake_waiters(iter->array_buffer->buffer) cpu_buffer = buffer->buffers[cpu] -> Add checks by previous commit ring_buffer_free_read_page(iter->array_buffer->buffer) cpu_buffer = buffer->buffers[cpu] -> No check Thus, to avod possible null-pointer derefernces, the related checks should be added. These results are reported by a static tool designed by myself. Link: https://lkml.kernel.org/r/20230113125501.760324-1-baijiaju1990@gmail.com Reported-by: TOTE Robot Signed-off-by: Jia-Ju Bai Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/ring_buffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index c00463613eab..70da6f3212bc 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5302,11 +5302,16 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page); */ void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data) { - struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu]; + struct ring_buffer_per_cpu *cpu_buffer; struct buffer_data_page *bpage = data; struct page *page = virt_to_page(bpage); unsigned long flags; + if (!buffer || !buffer->buffers || !buffer->buffers[cpu]) + return; + + cpu_buffer = buffer->buffers[cpu]; + /* If the page is still in use someplace else, we can't reuse it */ if (page_ref_count(page) > 1) goto out; From 07fb5653366c86fad87d84bad9d5c3f6fbc1e307 Mon Sep 17 00:00:00 2001 From: Darrell Kavanagh Date: Wed, 15 Feb 2023 11:50:45 +0000 Subject: [PATCH 0598/1017] firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3 [ Upstream commit e1d447157f232c650e6f32c9fb89ff3d0207c69a ] Another Lenovo convertable which reports a landscape resolution of 1920x1200 with a pitch of (1920 * 4) bytes, while the actual framebuffer has a resolution of 1200x1920 with a pitch of (1200 * 4) bytes. Signed-off-by: Darrell Kavanagh Reviewed-by: Hans de Goede Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin --- arch/x86/kernel/sysfb_efi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/sysfb_efi.c b/arch/x86/kernel/sysfb_efi.c index 653b7f617b61..9ea65611fba0 100644 --- a/arch/x86/kernel/sysfb_efi.c +++ b/arch/x86/kernel/sysfb_efi.c @@ -264,6 +264,14 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { "Lenovo ideapad D330-10IGM"), }, }, + { + /* Lenovo IdeaPad Duet 3 10IGL5 with 1200x1920 portrait screen */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, + "IdeaPad Duet 3 10IGL5"), + }, + }, {}, }; From 903b91cea77acc79a6b58553023d6ea4d0aa3dd7 Mon Sep 17 00:00:00 2001 From: Souradeep Chowdhury Date: Wed, 22 Feb 2023 08:27:49 +0900 Subject: [PATCH 0599/1017] bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC support [ Upstream commit 6c40624930c58529185a257380442547580ed837 ] The Data Capture and Compare(DCC) is a debugging tool that uses the bootconfig for configuring the register values during boot-time. Increase the max nodes supported by bootconfig to cater to the requirements of the Data Capture and Compare Driver. Link: https://lore.kernel.org/all/1674536682-18404-1-git-send-email-quic_schowdhu@quicinc.com/ Signed-off-by: Souradeep Chowdhury Acked-by: Masami Hiramatsu (Google) Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Sasha Levin --- include/linux/bootconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h index 2696eb0fc149..df9cbf02d030 100644 --- a/include/linux/bootconfig.h +++ b/include/linux/bootconfig.h @@ -29,7 +29,7 @@ struct xbc_node { /* Maximum size of boot config is 32KB - 1 */ #define XBC_DATA_MAX (XBC_VALUE - 1) -#define XBC_NODE_MAX 1024 +#define XBC_NODE_MAX 8192 #define XBC_KEYLEN_MAX 256 #define XBC_DEPTH_MAX 16 From 754e81ff44061dda68da0fd4ef51bd1aa9fbf2cf Mon Sep 17 00:00:00 2001 From: Liang He Date: Thu, 5 Jan 2023 14:10:55 +0800 Subject: [PATCH 0600/1017] mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak [ Upstream commit 4414a7ab80cebf715045e3c4d465feefbad21139 ] In arizona_clk32k_enable(), we should use pm_runtime_resume_and_get() as pm_runtime_get_sync() will increase the refcnt even when it returns an error. Signed-off-by: Liang He Acked-by: Charles Keepax Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20230105061055.1509261-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/mfd/arizona-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 000cb82023e3..afdc49083625 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -45,7 +45,7 @@ int arizona_clk32k_enable(struct arizona *arizona) if (arizona->clk32k_ref == 1) { switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: - ret = pm_runtime_get_sync(arizona->dev); + ret = pm_runtime_resume_and_get(arizona->dev); if (ret != 0) goto err_ref; ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]); From 76752888edcc3d01dbdf8886bc65af6767803471 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 14:04:29 -0500 Subject: [PATCH 0601/1017] IB/hfi1: Update RMT size calculation [ Upstream commit 892ede5a77f337831609fb9c248ac60948061894 ] Fix possible RMT overflow: Use the correct netdev size. Don't allow adjusted user contexts to go negative. Fix QOS calculation: Send kernel context count as an argument since dd->n_krcv_queues is not yet set up in earliest call. Do not include the control context in the QOS calculation. Use the same sized variable to find the max of krcvq[] entries. Update the RMT count explanation to make more sense. Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167329106946.1472990.18385495251650939054.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/hfi1/chip.c | 59 +++++++++++++++++-------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index 88476a1a601a..4b41f35668b2 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -1097,7 +1097,7 @@ static void read_link_down_reason(struct hfi1_devdata *dd, u8 *ldr); static void handle_temp_err(struct hfi1_devdata *dd); static void dc_shutdown(struct hfi1_devdata *dd); static void dc_start(struct hfi1_devdata *dd); -static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp, +static int qos_rmt_entries(unsigned int n_krcv_queues, unsigned int *mp, unsigned int *np); static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd); static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms); @@ -13403,7 +13403,6 @@ static int set_up_context_variables(struct hfi1_devdata *dd) int ret; unsigned ngroups; int rmt_count; - int user_rmt_reduced; u32 n_usr_ctxts; u32 send_contexts = chip_send_contexts(dd); u32 rcv_contexts = chip_rcv_contexts(dd); @@ -13462,28 +13461,34 @@ static int set_up_context_variables(struct hfi1_devdata *dd) (num_kernel_contexts + n_usr_ctxts), &node_affinity.real_cpu_mask); /* - * The RMT entries are currently allocated as shown below: - * 1. QOS (0 to 128 entries); - * 2. FECN (num_kernel_context - 1 + num_user_contexts + - * num_netdev_contexts); - * 3. netdev (num_netdev_contexts). - * It should be noted that FECN oversubscribe num_netdev_contexts - * entries of RMT because both netdev and PSM could allocate any receive - * context between dd->first_dyn_alloc_text and dd->num_rcv_contexts, - * and PSM FECN must reserve an RMT entry for each possible PSM receive - * context. + * RMT entries are allocated as follows: + * 1. QOS (0 to 128 entries) + * 2. FECN (num_kernel_context - 1 [a] + num_user_contexts + + * num_netdev_contexts [b]) + * 3. netdev (NUM_NETDEV_MAP_ENTRIES) + * + * Notes: + * [a] Kernel contexts (except control) are included in FECN if kernel + * TID_RDMA is active. + * [b] Netdev and user contexts are randomly allocated from the same + * context pool, so FECN must cover all contexts in the pool. */ - rmt_count = qos_rmt_entries(dd, NULL, NULL) + (num_netdev_contexts * 2); - if (HFI1_CAP_IS_KSET(TID_RDMA)) - rmt_count += num_kernel_contexts - 1; - if (rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) { - user_rmt_reduced = NUM_MAP_ENTRIES - rmt_count; - dd_dev_err(dd, - "RMT size is reducing the number of user receive contexts from %u to %d\n", - n_usr_ctxts, - user_rmt_reduced); - /* recalculate */ - n_usr_ctxts = user_rmt_reduced; + rmt_count = qos_rmt_entries(num_kernel_contexts - 1, NULL, NULL) + + (HFI1_CAP_IS_KSET(TID_RDMA) ? num_kernel_contexts - 1 + : 0) + + n_usr_ctxts + + num_netdev_contexts + + NUM_NETDEV_MAP_ENTRIES; + if (rmt_count > NUM_MAP_ENTRIES) { + int over = rmt_count - NUM_MAP_ENTRIES; + /* try to squish user contexts, minimum of 1 */ + if (over >= n_usr_ctxts) { + dd_dev_err(dd, "RMT overflow: reduce the requested number of contexts\n"); + return -EINVAL; + } + dd_dev_err(dd, "RMT overflow: reducing # user contexts from %u to %u\n", + n_usr_ctxts, n_usr_ctxts - over); + n_usr_ctxts -= over; } /* the first N are kernel contexts, the rest are user/netdev contexts */ @@ -14340,15 +14345,15 @@ static void clear_rsm_rule(struct hfi1_devdata *dd, u8 rule_index) } /* return the number of RSM map table entries that will be used for QOS */ -static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp, +static int qos_rmt_entries(unsigned int n_krcv_queues, unsigned int *mp, unsigned int *np) { int i; unsigned int m, n; - u8 max_by_vl = 0; + uint max_by_vl = 0; /* is QOS active at all? */ - if (dd->n_krcv_queues <= MIN_KERNEL_KCTXTS || + if (n_krcv_queues < MIN_KERNEL_KCTXTS || num_vls == 1 || krcvqsset <= 1) goto no_qos; @@ -14406,7 +14411,7 @@ static void init_qos(struct hfi1_devdata *dd, struct rsm_map_table *rmt) if (!rmt) goto bail; - rmt_entries = qos_rmt_entries(dd, &m, &n); + rmt_entries = qos_rmt_entries(dd->n_krcv_queues - 1, &m, &n); if (rmt_entries == 0) goto bail; qpns_per_vl = 1 << m; From d8aa2e1ae6426d7cbddf1735aed1a63ddf0e6909 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 20 Sep 2022 16:04:55 +0200 Subject: [PATCH 0602/1017] media: uvcvideo: Handle cameras with invalid descriptors [ Upstream commit 41ddb251c68ac75c101d3a50a68c4629c9055e4c ] If the source entity does not contain any pads, do not create a link. Reported-by: syzbot Signed-off-by: Ricardo Ribalda Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index ca3a9c2eec27..7c9895377118 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -37,7 +37,7 @@ static int uvc_mc_create_links(struct uvc_video_chain *chain, continue; remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]); - if (remote == NULL) + if (remote == NULL || remote->num_pads == 0) return -EINVAL; source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) From 23f9bead358de7a25c815e81c62243b48a186fc0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 25 Oct 2022 16:41:01 +0200 Subject: [PATCH 0603/1017] media: uvcvideo: Handle errors from calls to usb_string [ Upstream commit 4867bb590ae445bcfaa711a86b603c97e94574b3 ] On a Webcam from Quanta, we see the following error. usb 3-5: New USB device found, idVendor=0408, idProduct=30d2, bcdDevice= 0.03 usb 3-5: New USB device strings: Mfr=3, Product=1, SerialNumber=2 usb 3-5: Product: USB2.0 HD UVC WebCam usb 3-5: Manufacturer: Quanta usb 3-5: SerialNumber: 0x0001 ... uvcvideo: Found UVC 1.10 device USB2.0 HD UVC WebCam (0408:30d2) uvcvideo: Failed to initialize entity for entity 5 uvcvideo: Failed to register entities (-22). The Webcam reports an entity of type UVC_VC_EXTENSION_UNIT. It reports a string index of '7' associated with that entity. The attempt to read that string from the camera fails with error -32 (-EPIPE). usb_string() returns that error, but it is ignored. As result, the entity name is empty. This later causes v4l2_device_register_subdev() to return -EINVAL, and no entities are registered as result. While this appears to be a firmware problem with the camera, the kernel should still handle the situation gracefully. To do that, check the return value from usb_string(). If it reports an error, assign the entity's default name. Signed-off-by: Guenter Roeck Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_driver.c | 48 ++++++++++++------------------ 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 282f3d2388cc..2be18fa7982d 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1121,10 +1121,8 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, + n; memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); - if (buffer[24+p+2*n] != 0) - usb_string(udev, buffer[24+p+2*n], unit->name, - sizeof(unit->name)); - else + if (buffer[24+p+2*n] == 0 || + usb_string(udev, buffer[24+p+2*n], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Extension %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1249,15 +1247,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev, memcpy(term->media.bmTransportModes, &buffer[10+n], p); } - if (buffer[7] != 0) - usb_string(udev, buffer[7], term->name, - sizeof(term->name)); - else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) - sprintf(term->name, "Camera %u", buffer[3]); - else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) - sprintf(term->name, "Media %u", buffer[3]); - else - sprintf(term->name, "Input %u", buffer[3]); + if (buffer[7] == 0 || + usb_string(udev, buffer[7], term->name, sizeof(term->name)) < 0) { + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) + sprintf(term->name, "Camera %u", buffer[3]); + if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) + sprintf(term->name, "Media %u", buffer[3]); + else + sprintf(term->name, "Input %u", buffer[3]); + } list_add_tail(&term->list, &dev->entities); break; @@ -1289,10 +1287,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev, memcpy(term->baSourceID, &buffer[7], 1); - if (buffer[8] != 0) - usb_string(udev, buffer[8], term->name, - sizeof(term->name)); - else + if (buffer[8] == 0 || + usb_string(udev, buffer[8], term->name, sizeof(term->name)) < 0) sprintf(term->name, "Output %u", buffer[3]); list_add_tail(&term->list, &dev->entities); @@ -1314,10 +1310,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev, memcpy(unit->baSourceID, &buffer[5], p); - if (buffer[5+p] != 0) - usb_string(udev, buffer[5+p], unit->name, - sizeof(unit->name)); - else + if (buffer[5+p] == 0 || + usb_string(udev, buffer[5+p], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Selector %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1347,10 +1341,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev, if (dev->uvc_version >= 0x0110) unit->processing.bmVideoStandards = buffer[9+n]; - if (buffer[8+n] != 0) - usb_string(udev, buffer[8+n], unit->name, - sizeof(unit->name)); - else + if (buffer[8+n] == 0 || + usb_string(udev, buffer[8+n], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Processing %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1378,10 +1370,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev, unit->extension.bmControls = (u8 *)unit + sizeof(*unit); memcpy(unit->extension.bmControls, &buffer[23+p], n); - if (buffer[23+p+n] != 0) - usb_string(udev, buffer[23+p+n], unit->name, - sizeof(unit->name)); - else + if (buffer[23+p+n] == 0 || + usb_string(udev, buffer[23+p+n], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Extension %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); From 78b1fdc47e4e0a1ea1846f9b5913bfec0be00bea Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Wed, 4 Jan 2023 11:45:23 +0100 Subject: [PATCH 0604/1017] media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910 [ Upstream commit 136effa754b57632f99574fc4a3433e0cfc031d9 ] Logitech B910 and C910 firmware are unable to recover from a USB autosuspend. When it resumes, the device is in a state where it only produces invalid frames. Eg: $ echo 0xFFFF > /sys/module/uvcvideo/parameters/trace # enable verbose log $ yavta -c1 -n1 --file='frame#.jpg' --format MJPEG --size=1920x1080 /dev/video1 [350438.435219] uvcvideo: uvc_v4l2_open [350438.529794] uvcvideo: Resuming interface 2 [350438.529801] uvcvideo: Resuming interface 3 [350438.529991] uvcvideo: Trying format 0x47504a4d (MJPG): 1920x1080. [350438.529996] uvcvideo: Using default frame interval 33333.3 us (30.0 fps). [350438.551496] uvcvideo: uvc_v4l2_mmap [350438.555890] uvcvideo: Device requested 3060 B/frame bandwidth. [350438.555896] uvcvideo: Selecting alternate setting 11 (3060 B/frame bandwidth). [350438.556362] uvcvideo: Allocated 5 URB buffers of 32x3060 bytes each. [350439.316468] uvcvideo: Marking buffer as bad (error bit set). [350439.316475] uvcvideo: Frame complete (EOF found). [350439.316477] uvcvideo: EOF in empty payload. [350439.316484] uvcvideo: frame 1 stats: 149/261/417 packets, 1/149/417 pts (early initial), 416/417 scr, last pts/stc/sof 2976325734/2978107243/249 [350439.384510] uvcvideo: Marking buffer as bad (error bit set). [350439.384516] uvcvideo: Frame complete (EOF found). [350439.384518] uvcvideo: EOF in empty payload. [350439.384525] uvcvideo: frame 2 stats: 265/379/533 packets, 1/265/533 pts (early initial), 532/533 scr, last pts/stc/sof 2979524454/2981305193/316 [350439.448472] uvcvideo: Marking buffer as bad (error bit set). [350439.448478] uvcvideo: Frame complete (EOF found). [350439.448480] uvcvideo: EOF in empty payload. [350439.448487] uvcvideo: frame 3 stats: 265/377/533 packets, 1/265/533 pts (early initial), 532/533 scr, last pts/stc/sof 2982723174/2984503144/382 ...(loop)... The devices can leave this invalid state if the alternate setting of the streaming interface is toggled. This patch adds a quirk for this device so it can be autosuspended properly. lsusb -v: Bus 001 Device 049: ID 046d:0821 Logitech, Inc. HD Webcam C910 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 239 Miscellaneous Device bDeviceSubClass 2 bDeviceProtocol 1 Interface Association bMaxPacketSize0 64 idVendor 0x046d Logitech, Inc. idProduct 0x0821 HD Webcam C910 bcdDevice 0.10 iManufacturer 0 iProduct 0 iSerial 1 390022B0 bNumConfigurations 1 Signed-off-by: Ricardo Ribalda Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_driver.c | 18 ++++++++++++++++++ drivers/media/usb/uvc/uvc_video.c | 11 +++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 30 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 2be18fa7982d..6334f99f1854 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2555,6 +2555,24 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, + /* Logitech, Webcam C910 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x0821, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)}, + /* Logitech, Webcam B910 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x0823, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)}, /* Logitech Quickcam Fusion */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index f6373d678d25..d5a4e967883c 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1903,6 +1903,17 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream, uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u " "(%u B/frame bandwidth).\n", altsetting, best_psize); + /* + * Some devices, namely the Logitech C910 and B910, are unable + * to recover from a USB autosuspend, unless the alternate + * setting of the streaming interface is toggled. + */ + if (stream->dev->quirks & UVC_QUIRK_WAKE_AUTOSUSPEND) { + usb_set_interface(stream->dev->udev, intfnum, + altsetting); + usb_set_interface(stream->dev->udev, intfnum, 0); + } + ret = usb_set_interface(stream->dev->udev, intfnum, altsetting); if (ret < 0) return ret; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index c884020b2878..284200becbbd 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -203,6 +203,7 @@ #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 #define UVC_QUIRK_FORCE_Y8 0x00000800 #define UVC_QUIRK_FORCE_BPP 0x00001000 +#define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 From c4d96503d67b2c4de9772521cac84e5f25218c7c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 5 Jan 2023 22:17:04 -0800 Subject: [PATCH 0605/1017] media: uvcvideo: Silence memcpy() run-time false positive warnings [ Upstream commit b839212988575c701aab4d3d9ca15e44c87e383c ] The memcpy() in uvc_video_decode_meta() intentionally copies across the length and flags members and into the trailing buf flexible array. Split the copy so that the compiler can better reason about (the lack of) buffer overflows here. Avoid the run-time false positive warning: memcpy: detected field-spanning write (size 12) of single field "&meta->length" at drivers/media/usb/uvc/uvc_video.c:1355 (size 1) Additionally fix a typo in the documentation for struct uvc_meta_buf. Reported-by: ionut_n2001@yahoo.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=216810 Signed-off-by: Kees Cook Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_video.c | 4 +++- include/uapi/linux/uvcvideo.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index d5a4e967883c..03dfe96bceba 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1308,7 +1308,9 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, if (has_scr) memcpy(stream->clock.last_scr, scr, 6); - memcpy(&meta->length, mem, length); + meta->length = mem[0]; + meta->flags = mem[1]; + memcpy(meta->buf, &mem[2], length - 2); meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof); uvc_trace(UVC_TRACE_FRAME, diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h index f80f05b3c423..214092366193 100644 --- a/include/uapi/linux/uvcvideo.h +++ b/include/uapi/linux/uvcvideo.h @@ -86,7 +86,7 @@ struct uvc_xu_control_query { * struct. The first two fields are added by the driver, they can be used for * clock synchronisation. The rest is an exact copy of a UVC payload header. * Only complete objects with complete buffers are included. Therefore it's - * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large. + * always sizeof(meta->ns) + sizeof(meta->sof) + meta->length bytes large. */ struct uvc_meta_buf { __u64 ns; From e8a5efd5aefcc7de0f06983dd6038e4ce3a57632 Mon Sep 17 00:00:00 2001 From: Yuan Can Date: Thu, 19 Jan 2023 08:31:19 +0000 Subject: [PATCH 0606/1017] staging: emxx_udc: Add checks for dma_alloc_coherent() [ Upstream commit f6510a93cfd8c6c79b4dda0f2967cdc6df42eff4 ] As the dma_alloc_coherent may return NULL, the return value needs to be checked to avoid NULL poineter dereference. Signed-off-by: Yuan Can Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230119083119.16956-1-yuancan@huawei.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/emxx_udc/emxx_udc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index 3897f8e8f5e0..6870a33d4ccf 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -2591,10 +2591,15 @@ static int nbu2ss_ep_queue(struct usb_ep *_ep, req->unaligned = false; if (req->unaligned) { - if (!ep->virt_buf) + if (!ep->virt_buf) { ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE, &ep->phys_buf, GFP_ATOMIC | GFP_DMA); + if (!ep->virt_buf) { + spin_unlock_irqrestore(&udc->lock, flags); + return -ENOMEM; + } + } if (ep->epnum > 0) { if (ep->direct == USB_DIR_IN) memcpy(ep->virt_buf, req->req.buf, From 84ea44dc3e4ecb2632586238014bf6722aa5843b Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Fri, 9 Dec 2022 12:27:36 +0100 Subject: [PATCH 0607/1017] tty: fix out-of-bounds access in tty_driver_lookup_tty() [ Upstream commit db4df8e9d79e7d37732c1a1b560958e8dadfefa1 ] When specifying an invalid console= device like console=tty3270, tty_driver_lookup_tty() returns the tty struct without checking whether index is a valid number. To reproduce: qemu-system-x86_64 -enable-kvm -nographic -serial mon:stdio \ -kernel ../linux-build-x86/arch/x86/boot/bzImage \ -append "console=ttyS0 console=tty3270" This crashes with: [ 0.770599] BUG: kernel NULL pointer dereference, address: 00000000000000ef [ 0.771265] #PF: supervisor read access in kernel mode [ 0.771773] #PF: error_code(0x0000) - not-present page [ 0.772609] Oops: 0000 [#1] PREEMPT SMP PTI [ 0.774878] RIP: 0010:tty_open+0x268/0x6f0 [ 0.784013] chrdev_open+0xbd/0x230 [ 0.784444] ? cdev_device_add+0x80/0x80 [ 0.784920] do_dentry_open+0x1e0/0x410 [ 0.785389] path_openat+0xca9/0x1050 [ 0.785813] do_filp_open+0xaa/0x150 [ 0.786240] file_open_name+0x133/0x1b0 [ 0.786746] filp_open+0x27/0x50 [ 0.787244] console_on_rootfs+0x14/0x4d [ 0.787800] kernel_init_freeable+0x1e4/0x20d [ 0.788383] ? rest_init+0xc0/0xc0 [ 0.788881] kernel_init+0x11/0x120 [ 0.789356] ret_from_fork+0x22/0x30 Signed-off-by: Sven Schnelle Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20221209112737.3222509-2-svens@linux.ibm.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/tty_io.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 669aef77a0bd..c37d2657308c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1237,14 +1237,16 @@ static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, { struct tty_struct *tty; - if (driver->ops->lookup) + if (driver->ops->lookup) { if (!file) tty = ERR_PTR(-EIO); else tty = driver->ops->lookup(driver, file, idx); - else + } else { + if (idx >= driver->num) + return ERR_PTR(-EINVAL); tty = driver->ttys[idx]; - + } if (!IS_ERR(tty)) tty_kref_get(tty); return tty; From 0cb1f78d886bc3da43c714029ab35027c4e3208d Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Wed, 14 Dec 2022 11:11:35 +0800 Subject: [PATCH 0608/1017] tty: serial: fsl_lpuart: disable the CTS when send break signal [ Upstream commit c4c81db5cf8bc53d6160c3abf26d382c841aa434 ] LPUART IP has a bug that it treats the CTS as higher priority than the break signal, which cause the break signal sending through UARTCTRL_SBK may impacted by the CTS input if the HW flow control is enabled. Add this workaround patch to fix the IP bug, we can disable CTS before asserting SBK to avoid any interference from CTS, and re-enable it when break off. Such as for the bluetooth chip power save feature, host can let the BT chip get into sleep state by sending a UART break signal, and wake it up by turning off the UART break. If the BT chip enters the sleep mode successfully, it will pull up the CTS line, if the BT chip is woken up, it will pull down the CTS line. If without this workaround patch, the UART TX pin cannot send the break signal successfully as it affected by the BT CTS pin. After adding this patch, the BT power save feature can work well. Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20221214031137.28815-2-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/fsl_lpuart.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 223695947b65..9cb0e8673f82 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1448,12 +1448,32 @@ static void lpuart_break_ctl(struct uart_port *port, int break_state) static void lpuart32_break_ctl(struct uart_port *port, int break_state) { - unsigned long temp; + unsigned long temp, modem; + struct tty_struct *tty; + unsigned int cflag = 0; + + tty = tty_port_tty_get(&port->state->port); + if (tty) { + cflag = tty->termios.c_cflag; + tty_kref_put(tty); + } temp = lpuart32_read(port, UARTCTRL) & ~UARTCTRL_SBK; + modem = lpuart32_read(port, UARTMODIR); - if (break_state != 0) + if (break_state != 0) { temp |= UARTCTRL_SBK; + /* + * LPUART CTS has higher priority than SBK, need to disable CTS before + * asserting SBK to avoid any interference if flow control is enabled. + */ + if (cflag & CRTSCTS && modem & UARTMODIR_TXCTSE) + lpuart32_write(port, modem & ~UARTMODIR_TXCTSE, UARTMODIR); + } else { + /* Re-enable the CTS when break off. */ + if (cflag & CRTSCTS && !(modem & UARTMODIR_TXCTSE)) + lpuart32_write(port, modem | UARTMODIR_TXCTSE, UARTMODIR); + } lpuart32_write(port, temp, UARTCTRL); } From 17b96b5c19bec791b433890549e44ca523dc82aa Mon Sep 17 00:00:00 2001 From: Isaac True Date: Wed, 30 Nov 2022 11:55:30 +0100 Subject: [PATCH 0609/1017] serial: sc16is7xx: setup GPIO controller later in probe [ Upstream commit c8f71b49ee4d28930c4a6798d1969fa91dc4ef3e ] The GPIO controller component of the sc16is7xx driver is setup too early, which can result in a race condition where another device tries to utilise the GPIO lines before the sc16is7xx device has finished initialising. This issue manifests itself as an Oops when the GPIO lines are configured: Unable to handle kernel read from unreadable memory at virtual address ... pc : sc16is7xx_gpio_direction_output+0x68/0x108 [sc16is7xx] lr : sc16is7xx_gpio_direction_output+0x4c/0x108 [sc16is7xx] ... Call trace: sc16is7xx_gpio_direction_output+0x68/0x108 [sc16is7xx] gpiod_direction_output_raw_commit+0x64/0x318 gpiod_direction_output+0xb0/0x170 create_gpio_led+0xec/0x198 gpio_led_probe+0x16c/0x4f0 platform_drv_probe+0x5c/0xb0 really_probe+0xe8/0x448 driver_probe_device+0xe8/0x138 __device_attach_driver+0x94/0x118 bus_for_each_drv+0x8c/0xe0 __device_attach+0x100/0x1b8 device_initial_probe+0x28/0x38 bus_probe_device+0xa4/0xb0 deferred_probe_work_func+0x90/0xe0 process_one_work+0x1c4/0x480 worker_thread+0x54/0x430 kthread+0x138/0x150 ret_from_fork+0x10/0x1c This patch moves the setup of the GPIO controller functions to later in the probe function, ensuring the sc16is7xx device has already finished initialising by the time other devices try to make use of the GPIO lines. The error handling has also been reordered to reflect the new initialisation order. Co-developed-by: Wen-chien Jesse Sung Signed-off-by: Wen-chien Jesse Sung Signed-off-by: Isaac True Link: https://lore.kernel.org/r/20221130105529.698385-1-isaac.true@canonical.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/sc16is7xx.c | 51 +++++++++++++++++----------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 04b4ed5d0634..7ece8d1a23cb 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1243,25 +1243,6 @@ static int sc16is7xx_probe(struct device *dev, } sched_set_fifo(s->kworker_task); -#ifdef CONFIG_GPIOLIB - if (devtype->nr_gpio) { - /* Setup GPIO cotroller */ - s->gpio.owner = THIS_MODULE; - s->gpio.parent = dev; - s->gpio.label = dev_name(dev); - s->gpio.direction_input = sc16is7xx_gpio_direction_input; - s->gpio.get = sc16is7xx_gpio_get; - s->gpio.direction_output = sc16is7xx_gpio_direction_output; - s->gpio.set = sc16is7xx_gpio_set; - s->gpio.base = -1; - s->gpio.ngpio = devtype->nr_gpio; - s->gpio.can_sleep = 1; - ret = gpiochip_add_data(&s->gpio, s); - if (ret) - goto out_thread; - } -#endif - /* reset device, purging any pending irq / data */ regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT, SC16IS7XX_IOCONTROL_SRESET_BIT); @@ -1327,6 +1308,25 @@ static int sc16is7xx_probe(struct device *dev, s->p[u].irda_mode = true; } +#ifdef CONFIG_GPIOLIB + if (devtype->nr_gpio) { + /* Setup GPIO cotroller */ + s->gpio.owner = THIS_MODULE; + s->gpio.parent = dev; + s->gpio.label = dev_name(dev); + s->gpio.direction_input = sc16is7xx_gpio_direction_input; + s->gpio.get = sc16is7xx_gpio_get; + s->gpio.direction_output = sc16is7xx_gpio_direction_output; + s->gpio.set = sc16is7xx_gpio_set; + s->gpio.base = -1; + s->gpio.ngpio = devtype->nr_gpio; + s->gpio.can_sleep = 1; + ret = gpiochip_add_data(&s->gpio, s); + if (ret) + goto out_thread; + } +#endif + /* * Setup interrupt. We first try to acquire the IRQ line as level IRQ. * If that succeeds, we can allow sharing the interrupt as well. @@ -1346,18 +1346,19 @@ static int sc16is7xx_probe(struct device *dev, if (!ret) return 0; -out_ports: - for (i--; i >= 0; i--) { - uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); - clear_bit(s->p[i].port.line, &sc16is7xx_lines); - } - #ifdef CONFIG_GPIOLIB if (devtype->nr_gpio) gpiochip_remove(&s->gpio); out_thread: #endif + +out_ports: + for (i--; i >= 0; i--) { + uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); + clear_bit(s->p[i].port.line, &sc16is7xx_lines); + } + kthread_stop(s->kworker_task); out_clk: From 160494b66fe09577f30cf454f785f364c8c70c5d Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 12 Dec 2022 23:49:33 +0200 Subject: [PATCH 0610/1017] mei: bus-fixup:upon error print return values of send and receive [ Upstream commit 4b8659e2c258e4fdac9ccdf06cc20c0677894ef9 ] For easier debugging, upon error, print also return values from __mei_cl_recv() and __mei_cl_send() functions. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20221212214933.275434-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/mei/bus-fixup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 4e30fa98fe7d..c4c1275581ec 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -172,7 +172,7 @@ static int mei_fwver(struct mei_cl_device *cldev) ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), MEI_CL_IO_TX_BLOCKING); if (ret < 0) { - dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n"); + dev_err(&cldev->dev, "Could not send ReqFWVersion cmd ret = %d\n", ret); return ret; } @@ -184,7 +184,7 @@ static int mei_fwver(struct mei_cl_device *cldev) * Should be at least one version block, * error out if nothing found */ - dev_err(&cldev->dev, "Could not read FW version\n"); + dev_err(&cldev->dev, "Could not read FW version ret = %d\n", bytes_recv); return -EIO; } @@ -332,7 +332,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), MEI_CL_IO_TX_BLOCKING); if (ret < 0) { - dev_err(bus->dev, "Could not send IF version cmd\n"); + dev_err(bus->dev, "Could not send IF version cmd ret = %d\n", ret); return ret; } @@ -346,7 +346,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, ret = 0; bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0); if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) { - dev_err(bus->dev, "Could not read IF version\n"); + dev_err(bus->dev, "Could not read IF version ret = %d\n", bytes_recv); ret = -EIO; goto err; } From 8db64cea4788d972dcc9e064ad93c935ed67e4a8 Mon Sep 17 00:00:00 2001 From: Yulong Zhang Date: Tue, 17 Jan 2023 10:51:47 +0800 Subject: [PATCH 0611/1017] tools/iio/iio_utils:fix memory leak [ Upstream commit f2edf0c819a4823cd6c288801ce737e8d4fcde06 ] 1. fopen sysfs without fclose. 2. asprintf filename without free. 3. if asprintf return error,do not need to free the buffer. Signed-off-by: Yulong Zhang Link: https://lore.kernel.org/r/20230117025147.69890-1-yulong.zhang@metoak.net Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- tools/iio/iio_utils.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c index d66b18c54606..48360994c2a1 100644 --- a/tools/iio/iio_utils.c +++ b/tools/iio/iio_utils.c @@ -262,6 +262,7 @@ int iioutils_get_param_float(float *output, const char *param_name, if (fscanf(sysfsfp, "%f", output) != 1) ret = errno ? -errno : -ENODATA; + fclose(sysfsfp); break; } error_free_filename: @@ -342,9 +343,9 @@ int build_channel_array(const char *device_dir, } sysfsfp = fopen(filename, "r"); + free(filename); if (!sysfsfp) { ret = -errno; - free(filename); goto error_close_dir; } @@ -354,7 +355,6 @@ int build_channel_array(const char *device_dir, if (fclose(sysfsfp)) perror("build_channel_array(): Failed to close file"); - free(filename); goto error_close_dir; } if (ret == 1) @@ -362,11 +362,9 @@ int build_channel_array(const char *device_dir, if (fclose(sysfsfp)) { ret = -errno; - free(filename); goto error_close_dir; } - free(filename); } *ci_array = malloc(sizeof(**ci_array) * (*counter)); @@ -392,9 +390,9 @@ int build_channel_array(const char *device_dir, } sysfsfp = fopen(filename, "r"); + free(filename); if (!sysfsfp) { ret = -errno; - free(filename); count--; goto error_cleanup_array; } @@ -402,20 +400,17 @@ int build_channel_array(const char *device_dir, errno = 0; if (fscanf(sysfsfp, "%i", ¤t_enabled) != 1) { ret = errno ? -errno : -ENODATA; - free(filename); count--; goto error_cleanup_array; } if (fclose(sysfsfp)) { ret = -errno; - free(filename); count--; goto error_cleanup_array; } if (!current_enabled) { - free(filename); count--; continue; } @@ -426,7 +421,6 @@ int build_channel_array(const char *device_dir, strlen(ent->d_name) - strlen("_en")); if (!current->name) { - free(filename); ret = -ENOMEM; count--; goto error_cleanup_array; @@ -436,7 +430,6 @@ int build_channel_array(const char *device_dir, ret = iioutils_break_up_name(current->name, ¤t->generic_name); if (ret) { - free(filename); free(current->name); count--; goto error_cleanup_array; @@ -447,17 +440,16 @@ int build_channel_array(const char *device_dir, scan_el_dir, current->name); if (ret < 0) { - free(filename); ret = -ENOMEM; goto error_cleanup_array; } sysfsfp = fopen(filename, "r"); + free(filename); if (!sysfsfp) { ret = -errno; - fprintf(stderr, "failed to open %s\n", - filename); - free(filename); + fprintf(stderr, "failed to open %s/%s_index\n", + scan_el_dir, current->name); goto error_cleanup_array; } @@ -467,17 +459,14 @@ int build_channel_array(const char *device_dir, if (fclose(sysfsfp)) perror("build_channel_array(): Failed to close file"); - free(filename); goto error_cleanup_array; } if (fclose(sysfsfp)) { ret = -errno; - free(filename); goto error_cleanup_array; } - free(filename); /* Find the scale */ ret = iioutils_get_param_float(¤t->scale, "scale", From 3357e90d3c3648807b317b8948bd400cb56fc255 Mon Sep 17 00:00:00 2001 From: Harshit Mogalapalli Date: Thu, 26 Jan 2023 07:21:46 -0800 Subject: [PATCH 0612/1017] iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_status_word() [ Upstream commit e56d2c34ce9dc122b1a618172ec0e05e50adb9e9 ] Smatch Warns: drivers/iio/accel/mma9551_core.c:357 mma9551_read_status_word() error: uninitialized symbol 'v'. When (offset >= 1 << 12) is true mma9551_transfer() will return -EINVAL without 'v' being initialized, so check for the error and return. Note: Not a bug as such because the caller checks return value and doesn't not use this parameter in the problem case. Signed-off-by: Harshit Mogalapalli Link: https://lore.kernel.org/r/20230126152147.3585874-1-harshit.m.mogalapalli@oracle.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/accel/mma9551_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c index 666e7a04a7d7..aa16d6678494 100644 --- a/drivers/iio/accel/mma9551_core.c +++ b/drivers/iio/accel/mma9551_core.c @@ -354,9 +354,12 @@ int mma9551_read_status_word(struct i2c_client *client, u8 app_id, ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, reg, NULL, 0, (u8 *)&v, 2); + if (ret < 0) + return ret; + *val = be16_to_cpu(v); - return ret; + return 0; } EXPORT_SYMBOL(mma9551_read_status_word); From 09ca779ac04cd50ee0d27acd6faf7b2224a6b65a Mon Sep 17 00:00:00 2001 From: Harshit Mogalapalli Date: Thu, 26 Jan 2023 07:36:09 -0800 Subject: [PATCH 0613/1017] iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_config_word() [ Upstream commit 64a68158738ec8f520347144352f7a09bdb9e169 ] Smatch Warns: drivers/iio/accel/mma9551_core.c:299 mma9551_read_config_word() error: uninitialized symbol 'v'. When (offset >= 1 << 12) is true mma9551_transfer() will return -EINVAL without 'v' being initialized, so check for the error and return. Note: No actual bug as caller checks the return value and does not use the parameter in the problem case. Signed-off-by: Harshit Mogalapalli Link: https://lore.kernel.org/r/20230126153610.3586243-1-harshit.m.mogalapalli@oracle.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/accel/mma9551_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c index aa16d6678494..9bb5c2fea08c 100644 --- a/drivers/iio/accel/mma9551_core.c +++ b/drivers/iio/accel/mma9551_core.c @@ -296,9 +296,12 @@ int mma9551_read_config_word(struct i2c_client *client, u8 app_id, ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, reg, NULL, 0, (u8 *)&v, 2); + if (ret < 0) + return ret; + *val = be16_to_cpu(v); - return ret; + return 0; } EXPORT_SYMBOL(mma9551_read_config_word); From 654ae539254d10042869fdc77ad04c09e7eff1fd Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Wed, 1 Feb 2023 12:30:18 +0800 Subject: [PATCH 0614/1017] PCI: loongson: Prevent LS7A MRRS increases [ Upstream commit 8b3517f88ff2983f52698893519227c10aac90b2 ] Except for isochronous-configured devices, software may set Max_Read_Request_Size (MRRS) to any value up to 4096. If a device issues a read request with size greater than the completer's Max_Payload_Size (MPS), the completer is required to break the response into multiple completions. Instead of correctly responding with multiple completions to a large read request, some LS7A Root Ports respond with a Completer Abort. To prevent this, the MRRS must be limited to an implementation-specific value. The OS cannot detect that value, so rely on BIOS to configure MRRS before booting, and quirk the Root Ports so we never set an MRRS larger than that BIOS value for any downstream device. N.B. Hot-added devices are not configured by BIOS, and they power up with MRRS = 512 bytes, so these devices will be limited to 512 bytes. If the LS7A limit is smaller, those hot-added devices may not work correctly, but per [1], hotplug is not supported with this chipset revision. [1] https://lore.kernel.org/r/073638a7-ae68-2847-ac3d-29e5e760d6af@loongson.cn [bhelgaas: commit log] Link: https://bugzilla.kernel.org/show_bug.cgi?id=216884 Link: https://lore.kernel.org/r/20230201043018.778499-3-chenhuacai@loongson.cn Signed-off-by: Huacai Chen Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/controller/pci-loongson.c | 42 +++++++++------------------ drivers/pci/pci.c | 10 +++++++ include/linux/pci.h | 1 + 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 48169b1e3817..dc7b4e4293ce 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -60,37 +60,23 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_LPC, system_bus_quirk); -static void loongson_mrrs_quirk(struct pci_dev *dev) +static void loongson_mrrs_quirk(struct pci_dev *pdev) { - struct pci_bus *bus = dev->bus; - struct pci_dev *bridge; - static const struct pci_device_id bridge_devids[] = { - { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_0) }, - { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_1) }, - { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_2) }, - { 0, }, - }; + /* + * Some Loongson PCIe ports have h/w limitations of maximum read + * request size. They can't handle anything larger than this. So + * force this limit on any devices attached under these ports. + */ + struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); - /* look for the matching bridge */ - while (!pci_is_root_bus(bus)) { - bridge = bus->self; - bus = bus->parent; - /* - * Some Loongson PCIe ports have a h/w limitation of - * 256 bytes maximum read request size. They can't handle - * anything larger than this. So force this limit on - * any devices attached under these ports. - */ - if (pci_match_id(bridge_devids, bridge)) { - if (pcie_get_readrq(dev) > 256) { - pci_info(dev, "limiting MRRS to 256\n"); - pcie_set_readrq(dev, 256); - } - break; - } - } + bridge->no_inc_mrrs = 1; } -DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_0, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_1, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_2, loongson_mrrs_quirk); static void __iomem *cfg1_map(struct loongson_pci *priv, int bus, unsigned int devfn, int where) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 845851e23352..744a2e05635b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5739,6 +5739,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) { u16 v; int ret; + struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); if (rq < 128 || rq > 4096 || !is_power_of_2(rq)) return -EINVAL; @@ -5757,6 +5758,15 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) v = (ffs(rq) - 8) << 12; + if (bridge->no_inc_mrrs) { + int max_mrrs = pcie_get_readrq(dev); + + if (rq > max_mrrs) { + pci_info(dev, "can't set Max_Read_Request_Size to %d; max is %d\n", rq, max_mrrs); + return -EINVAL; + } + } + ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_READRQ, v); diff --git a/include/linux/pci.h b/include/linux/pci.h index 692ce678c5f1..4cc42ad2f6c5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -539,6 +539,7 @@ struct pci_host_bridge { struct msi_controller *msi; unsigned int ignore_reset_delay:1; /* For entire hierarchy */ unsigned int no_ext_tags:1; /* No Extended Tags */ + unsigned int no_inc_mrrs:1; /* No Increase MRRS */ unsigned int native_aer:1; /* OS may use PCIe AER */ unsigned int native_pcie_hotplug:1; /* OS may use PCIe hotplug */ unsigned int native_shpc_hotplug:1; /* OS may use SHPC hotplug */ From 426cbe9a0a688533eb286e1298bd9e66be7f806f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 4 Feb 2023 10:36:52 -0800 Subject: [PATCH 0615/1017] usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer math [ Upstream commit 0fbd2cda92cdb00f72080665554a586f88bca821 ] Walking the dram->cs array was seen as accesses beyond the first array item by the compiler. Instead, use the array index directly. This allows for run-time bounds checking under CONFIG_UBSAN_BOUNDS as well. Seen with GCC 13 with -fstrict-flex-arrays: In function 'xhci_mvebu_mbus_config', inlined from 'xhci_mvebu_mbus_init_quirk' at ../drivers/usb/host/xhci-mvebu.c:66:2: ../drivers/usb/host/xhci-mvebu.c:37:28: warning: array subscript 0 is outside array bounds of 'const struct mbus_dram_window[0]' [-Warray-bounds=] 37 | writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | | ~~^~~~~~ Cc: Mathias Nyman Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20230204183651.never.663-kees@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-mvebu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 8ca1a235d164..eabccf25796b 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -33,7 +33,7 @@ static void xhci_mvebu_mbus_config(void __iomem *base, /* Program each DRAM CS in a seperate window */ for (win = 0; win < dram->num_cs; win++) { - const struct mbus_dram_window *cs = dram->cs + win; + const struct mbus_dram_window *cs = &dram->cs[win]; writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | (dram->mbus_dram_target_id << 4) | 1, From 961f93d63da72f5fcaa6793fb2dcbc995c119a8e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 4 Feb 2023 10:35:46 -0800 Subject: [PATCH 0616/1017] USB: ene_usb6250: Allocate enough memory for full object [ Upstream commit ce33e64c1788912976b61314b56935abd4bc97ef ] The allocation of PageBuffer is 512 bytes in size, but the dereferencing of struct ms_bootblock_idi (also size 512) happens at a calculated offset within the allocation, which means the object could potentially extend beyond the end of the allocation. Avoid this case by just allocating enough space to catch any accesses beyond the end. Seen with GCC 13: ../drivers/usb/storage/ene_ub6250.c: In function 'ms_lib_process_bootblock': ../drivers/usb/storage/ene_ub6250.c:1050:44: warning: array subscript 'struct ms_bootblock_idi[0]' is partly outside array bounds of 'unsigned char[512]' [-Warray-bounds=] 1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF) | ^~ ../include/uapi/linux/byteorder/little_endian.h:37:51: note: in definition of macro '__le16_to_cpu' 37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) | ^ ../drivers/usb/storage/ene_ub6250.c:1050:29: note: in expansion of macro 'le16_to_cpu' 1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF) | ^~~~~~~~~~~ In file included from ../drivers/usb/storage/ene_ub6250.c:5: In function 'kmalloc', inlined from 'ms_lib_process_bootblock' at ../drivers/usb/storage/ene_ub6250.c:942:15: ../include/linux/slab.h:580:24: note: at offset [256, 512] into object of size 512 allocated by 'kmalloc_trace' 580 | return kmalloc_trace( | ^~~~~~~~~~~~~~ 581 | kmalloc_caches[kmalloc_type(flags)][index], | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 582 | flags, size); | ~~~~~~~~~~~~ Cc: Alan Stern Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20230204183546.never.849-kees@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/storage/ene_ub6250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index c9ce1c25c80c..737398f1b896 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -938,7 +938,7 @@ static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageDa struct ms_lib_type_extdat ExtraData; struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; - PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); + PageBuffer = kzalloc(MS_BYTES_PER_PAGE * 2, GFP_KERNEL); if (PageBuffer == NULL) return (u32)-1; From 56495e8d3cb4522b8e72347755d5c02e64ac30df Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Thu, 2 Feb 2023 11:41:37 +0000 Subject: [PATCH 0617/1017] usb: uvc: Enumerate valid values for color matching [ Upstream commit e16cab9c1596e251761d2bfb5e1467950d616963 ] The color matching descriptors defined in the UVC Specification contain 3 fields with discrete numeric values representing particular settings. Enumerate those values so that later code setting them can be more readable. Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Scally Link: https://lore.kernel.org/r/20230202114142.300858-2-dan.scally@ideasonboard.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/uapi/linux/usb/video.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index bfdae12cdacf..c58854fb7d94 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -179,6 +179,36 @@ #define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3) #define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4) +/* 3.9.2.6 Color Matching Descriptor Values */ +enum uvc_color_primaries_values { + UVC_COLOR_PRIMARIES_UNSPECIFIED, + UVC_COLOR_PRIMARIES_BT_709_SRGB, + UVC_COLOR_PRIMARIES_BT_470_2_M, + UVC_COLOR_PRIMARIES_BT_470_2_B_G, + UVC_COLOR_PRIMARIES_SMPTE_170M, + UVC_COLOR_PRIMARIES_SMPTE_240M, +}; + +enum uvc_transfer_characteristics_values { + UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED, + UVC_TRANSFER_CHARACTERISTICS_BT_709, + UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M, + UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G, + UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M, + UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M, + UVC_TRANSFER_CHARACTERISTICS_LINEAR, + UVC_TRANSFER_CHARACTERISTICS_SRGB, +}; + +enum uvc_matrix_coefficients { + UVC_MATRIX_COEFFICIENTS_UNSPECIFIED, + UVC_MATRIX_COEFFICIENTS_BT_709, + UVC_MATRIX_COEFFICIENTS_FCC, + UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G, + UVC_MATRIX_COEFFICIENTS_SMPTE_170M, + UVC_MATRIX_COEFFICIENTS_SMPTE_240M, +}; + /* ------------------------------------------------------------------------ * UVC structures */ From 877aacda14698b6217951c30eb4033ce53f50a33 Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Mon, 6 Feb 2023 16:17:52 +0000 Subject: [PATCH 0618/1017] usb: gadget: uvc: Make bSourceID read/write [ Upstream commit b3c839bd8a07d303bc59a900d55dd35c7826562c ] At the moment, the UVC function graph is hardcoded IT -> PU -> OT. To add XU support we need the ability to insert the XU descriptors into the chain. To facilitate that, make the output terminal's bSourceID attribute writeable so that we can configure its source. Signed-off-by: Daniel Scally Link: https://lore.kernel.org/r/20230206161802.892954-2-dan.scally@ideasonboard.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- .../ABI/testing/configfs-usb-gadget-uvc | 2 +- drivers/usb/gadget/function/uvc_configfs.c | 59 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc index ac5e11af79a8..4b1813994bd0 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uvc +++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc @@ -51,7 +51,7 @@ Date: Dec 2014 KernelVersion: 4.0 Description: Default output terminal descriptors - All attributes read only: + All attributes read only except bSourceID: ============== ============================================= iTerminal index of string descriptor diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 00fb58e50a15..7bb11d532b19 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -505,11 +505,68 @@ UVC_ATTR_RO(uvcg_default_output_, cname, aname) UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, 8); UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, 16); UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, 8); -UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, 8); UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, 8); #undef UVCG_DEFAULT_OUTPUT_ATTR +static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item, + char *page) +{ + struct config_group *group = to_config_group(item); + struct f_uvc_opts *opts; + struct config_item *opts_item; + struct mutex *su_mutex = &group->cg_subsys->su_mutex; + struct uvc_output_terminal_descriptor *cd; + int result; + + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ + + opts_item = group->cg_item.ci_parent->ci_parent-> + ci_parent->ci_parent; + opts = to_f_uvc_opts(opts_item); + cd = &opts->uvc_output_terminal; + + mutex_lock(&opts->lock); + result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID)); + mutex_unlock(&opts->lock); + + mutex_unlock(su_mutex); + + return result; +} + +static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, + const char *page, size_t len) +{ + struct config_group *group = to_config_group(item); + struct f_uvc_opts *opts; + struct config_item *opts_item; + struct mutex *su_mutex = &group->cg_subsys->su_mutex; + struct uvc_output_terminal_descriptor *cd; + int result; + u8 num; + + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ + + opts_item = group->cg_item.ci_parent->ci_parent-> + ci_parent->ci_parent; + opts = to_f_uvc_opts(opts_item); + cd = &opts->uvc_output_terminal; + + result = kstrtou8(page, 0, &num); + if (result) + return result; + + mutex_lock(&opts->lock); + cd->bSourceID = num; + mutex_unlock(&opts->lock); + + mutex_unlock(su_mutex); + + return len; +} +UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID); + static struct configfs_attribute *uvcg_default_output_attrs[] = { &uvcg_default_output_attr_b_terminal_id, &uvcg_default_output_attr_w_terminal_type, From fdca189e522850ee122a409ed7e693795e31fb58 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 31 Jan 2023 11:24:03 +0200 Subject: [PATCH 0619/1017] PCI: Align extra resources for hotplug bridges properly [ Upstream commit 08f0a15ee8adb4846b08ca5d5c175fbf0f652bc9 ] After division the extra resource space per hotplug bridge may not be aligned according to the window alignment, so align it before passing it down for further distribution. Link: https://lore.kernel.org/r/20230131092405.29121-2-mika.westerberg@linux.intel.com Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/setup-bus.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 2ce636937c6e..4a6b698b5dd1 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -2004,6 +2004,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, * resource space between hotplug bridges. */ for_each_pci_bridge(dev, bus) { + struct resource *res; struct pci_bus *b; b = dev->subordinate; @@ -2015,16 +2016,28 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, * hotplug-capable downstream ports taking alignment into * account. */ - io.end = io.start + io_per_hp - 1; - mmio.end = mmio.start + mmio_per_hp - 1; - mmio_pref.end = mmio_pref.start + mmio_pref_per_hp - 1; + res = &dev->resource[PCI_BRIDGE_IO_WINDOW]; + align = pci_resource_alignment(dev, res); + io.end = align ? io.start + ALIGN_DOWN(io_per_hp, align) - 1 + : io.start + io_per_hp - 1; + + res = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; + align = pci_resource_alignment(dev, res); + mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_hp, align) - 1 + : mmio.start + mmio_per_hp - 1; + + res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; + align = pci_resource_alignment(dev, res); + mmio_pref.end = align ? mmio_pref.start + + ALIGN_DOWN(mmio_pref_per_hp, align) - 1 + : mmio_pref.start + mmio_pref_per_hp - 1; pci_bus_distribute_available_resources(b, add_list, io, mmio, mmio_pref); - io.start += io_per_hp; - mmio.start += mmio_per_hp; - mmio_pref.start += mmio_pref_per_hp; + io.start += io.end + 1; + mmio.start += mmio.end + 1; + mmio_pref.start += mmio_pref.end + 1; } } From b2301851e7e3f5935f317a840763fb4ccaac55cb Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 31 Jan 2023 11:24:04 +0200 Subject: [PATCH 0620/1017] PCI: Take other bus devices into account when distributing resources [ Upstream commit 9db0b9b6a14249ef65a5f1e5e3b37762af96f425 ] A PCI bridge may reside on a bus with other devices as well. The resource distribution code does not take this into account and therefore it expands the bridge resource windows too much, not leaving space for the other devices (or functions of a multifunction device). This leads to an issue that Jonathan reported when running QEMU with the following topology (QEMU parameters): -device pcie-root-port,port=0,id=root_port13,chassis=0,slot=2 \ -device x3130-upstream,id=sw1,bus=root_port13,multifunction=on \ -device e1000,bus=root_port13,addr=0.1 \ -device xio3130-downstream,id=fun1,bus=sw1,chassis=0,slot=3 \ -device e1000,bus=fun1 The first e1000 NIC here is another function in the switch upstream port. This leads to following errors: pci 0000:00:04.0: bridge window [mem 0x10200000-0x103fffff] to [bus 02-04] pci 0000:02:00.0: bridge window [mem 0x10200000-0x103fffff] to [bus 03-04] pci 0000:02:00.1: BAR 0: failed to assign [mem size 0x00020000] e1000 0000:02:00.1: can't ioremap BAR 0: [??? 0x00000000 flags 0x0] Fix this by taking into account bridge windows, device BARs and SR-IOV PF BARs on the bus (PF BARs include space for VF BARS so only account PF BARs), including the ones belonging to bridges themselves if it has any. Link: https://lore.kernel.org/linux-pci/20221014124553.0000696f@huawei.com/ Link: https://lore.kernel.org/linux-pci/6053736d-1923-41e7-def9-7585ce1772d9@ixsystems.com/ Link: https://lore.kernel.org/r/20230131092405.29121-3-mika.westerberg@linux.intel.com Reported-by: Jonathan Cameron Reported-by: Alexander Motin Signed-off-by: Mika Westerberg Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/setup-bus.c | 178 ++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 71 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4a6b698b5dd1..16d291e10627 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1878,12 +1878,67 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res, add_size = size - new_size; pci_dbg(bridge, "bridge window %pR shrunken by %pa\n", res, &add_size); + } else { + return; } res->end = res->start + new_size - 1; remove_from_list(add_list, res); } +static void remove_dev_resource(struct resource *avail, struct pci_dev *dev, + struct resource *res) +{ + resource_size_t size, align, tmp; + + size = resource_size(res); + if (!size) + return; + + align = pci_resource_alignment(dev, res); + align = align ? ALIGN(avail->start, align) - avail->start : 0; + tmp = align + size; + avail->start = min(avail->start + tmp, avail->end + 1); +} + +static void remove_dev_resources(struct pci_dev *dev, struct resource *io, + struct resource *mmio, + struct resource *mmio_pref) +{ + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *res = &dev->resource[i]; + + if (resource_type(res) == IORESOURCE_IO) { + remove_dev_resource(io, dev, res); + } else if (resource_type(res) == IORESOURCE_MEM) { + + /* + * Make sure prefetchable memory is reduced from + * the correct resource. Specifically we put 32-bit + * prefetchable memory in non-prefetchable window + * if there is an 64-bit pretchable window. + * + * See comments in __pci_bus_size_bridges() for + * more information. + */ + if ((res->flags & IORESOURCE_PREFETCH) && + ((res->flags & IORESOURCE_MEM_64) == + (mmio_pref->flags & IORESOURCE_MEM_64))) + remove_dev_resource(mmio_pref, dev, res); + else + remove_dev_resource(mmio, dev, res); + } + } +} + +/* + * io, mmio and mmio_pref contain the total amount of bridge window space + * available. This includes the minimal space needed to cover all the + * existing devices on the bus and the possible extra space that can be + * shared with the bridges. + */ static void pci_bus_distribute_available_resources(struct pci_bus *bus, struct list_head *add_list, struct resource io, @@ -1893,7 +1948,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, unsigned int normal_bridges = 0, hotplug_bridges = 0; struct resource *io_res, *mmio_res, *mmio_pref_res; struct pci_dev *dev, *bridge = bus->self; - resource_size_t io_per_hp, mmio_per_hp, mmio_pref_per_hp, align; + resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align; io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW]; mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW]; @@ -1937,100 +1992,81 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, normal_bridges++; } - /* - * There is only one bridge on the bus so it gets all available - * resources which it can then distribute to the possible hotplug - * bridges below. - */ - if (hotplug_bridges + normal_bridges == 1) { - dev = list_first_entry(&bus->devices, struct pci_dev, bus_list); - if (dev->subordinate) - pci_bus_distribute_available_resources(dev->subordinate, - add_list, io, mmio, mmio_pref); - return; - } - - if (hotplug_bridges == 0) + if (!(hotplug_bridges + normal_bridges)) return; /* - * Calculate the total amount of extra resource space we can - * pass to bridges below this one. This is basically the - * extra space reduced by the minimal required space for the - * non-hotplug bridges. + * Calculate the amount of space we can forward from "bus" to any + * downstream buses, i.e., the space left over after assigning the + * BARs and windows on "bus". */ - for_each_pci_bridge(dev, bus) { - resource_size_t used_size; - struct resource *res; - - if (dev->is_hotplug_bridge) - continue; - - /* - * Reduce the available resource space by what the - * bridge and devices below it occupy. - */ - res = &dev->resource[PCI_BRIDGE_IO_WINDOW]; - align = pci_resource_alignment(dev, res); - align = align ? ALIGN(io.start, align) - io.start : 0; - used_size = align + resource_size(res); - if (!res->parent) - io.start = min(io.start + used_size, io.end + 1); - - res = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; - align = pci_resource_alignment(dev, res); - align = align ? ALIGN(mmio.start, align) - mmio.start : 0; - used_size = align + resource_size(res); - if (!res->parent) - mmio.start = min(mmio.start + used_size, mmio.end + 1); - - res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; - align = pci_resource_alignment(dev, res); - align = align ? ALIGN(mmio_pref.start, align) - - mmio_pref.start : 0; - used_size = align + resource_size(res); - if (!res->parent) - mmio_pref.start = min(mmio_pref.start + used_size, - mmio_pref.end + 1); + list_for_each_entry(dev, &bus->devices, bus_list) { + if (!dev->is_virtfn) + remove_dev_resources(dev, &io, &mmio, &mmio_pref); } - io_per_hp = div64_ul(resource_size(&io), hotplug_bridges); - mmio_per_hp = div64_ul(resource_size(&mmio), hotplug_bridges); - mmio_pref_per_hp = div64_ul(resource_size(&mmio_pref), - hotplug_bridges); - /* - * Go over devices on this bus and distribute the remaining - * resource space between hotplug bridges. + * If there is at least one hotplug bridge on this bus it gets all + * the extra resource space that was left after the reductions + * above. + * + * If there are no hotplug bridges the extra resource space is + * split between non-hotplug bridges. This is to allow possible + * hotplug bridges below them to get the extra space as well. */ + if (hotplug_bridges) { + io_per_b = div64_ul(resource_size(&io), hotplug_bridges); + mmio_per_b = div64_ul(resource_size(&mmio), hotplug_bridges); + mmio_pref_per_b = div64_ul(resource_size(&mmio_pref), + hotplug_bridges); + } else { + io_per_b = div64_ul(resource_size(&io), normal_bridges); + mmio_per_b = div64_ul(resource_size(&mmio), normal_bridges); + mmio_pref_per_b = div64_ul(resource_size(&mmio_pref), + normal_bridges); + } + for_each_pci_bridge(dev, bus) { struct resource *res; struct pci_bus *b; b = dev->subordinate; - if (!b || !dev->is_hotplug_bridge) + if (!b) + continue; + if (hotplug_bridges && !dev->is_hotplug_bridge) continue; - /* - * Distribute available extra resources equally between - * hotplug-capable downstream ports taking alignment into - * account. - */ res = &dev->resource[PCI_BRIDGE_IO_WINDOW]; + + /* + * Make sure the split resource space is properly aligned + * for bridge windows (align it down to avoid going above + * what is available). + */ align = pci_resource_alignment(dev, res); - io.end = align ? io.start + ALIGN_DOWN(io_per_hp, align) - 1 - : io.start + io_per_hp - 1; + io.end = align ? io.start + ALIGN_DOWN(io_per_b, align) - 1 + : io.start + io_per_b - 1; + + /* + * The x_per_b holds the extra resource space that can be + * added for each bridge but there is the minimal already + * reserved as well so adjust x.start down accordingly to + * cover the whole space. + */ + io.start -= resource_size(res); res = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; align = pci_resource_alignment(dev, res); - mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_hp, align) - 1 - : mmio.start + mmio_per_hp - 1; + mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_b, align) - 1 + : mmio.start + mmio_per_b - 1; + mmio.start -= resource_size(res); res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; align = pci_resource_alignment(dev, res); mmio_pref.end = align ? mmio_pref.start + - ALIGN_DOWN(mmio_pref_per_hp, align) - 1 - : mmio_pref.start + mmio_pref_per_hp - 1; + ALIGN_DOWN(mmio_pref_per_b, align) - 1 + : mmio_pref.start + mmio_pref_per_b - 1; + mmio_pref.start -= resource_size(res); pci_bus_distribute_available_resources(b, add_list, io, mmio, mmio_pref); From dd9981a11d74ff2eb253bb5c459876f8bd3c6c36 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Feb 2023 16:16:33 +0100 Subject: [PATCH 0621/1017] kernel/fail_function: fix memory leak with using debugfs_lookup() [ Upstream commit 2bb3669f576559db273efe49e0e69f82450efbca ] When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once. Cc: Andrew Morton Reviewed-by: Yang Yingliang Link: https://lore.kernel.org/r/20230202151633.2310897-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- kernel/fail_function.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/fail_function.c b/kernel/fail_function.c index b0b1ad93fa95..8f3795d8ac5b 100644 --- a/kernel/fail_function.c +++ b/kernel/fail_function.c @@ -163,10 +163,7 @@ static void fei_debugfs_add_attr(struct fei_attr *attr) static void fei_debugfs_remove_attr(struct fei_attr *attr) { - struct dentry *dir; - - dir = debugfs_lookup(attr->kp.symbol_name, fei_debugfs_dir); - debugfs_remove_recursive(dir); + debugfs_lookup_and_remove(attr->kp.symbol_name, fei_debugfs_dir); } static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs) From faa050d2ff8820f450b69b84645e74b6934ed5ad Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 11 Feb 2023 10:33:21 +0800 Subject: [PATCH 0622/1017] PCI: loongson: Add more devices that need MRRS quirk [ Upstream commit c768f8c5f40fcdc6f058cc2f02592163d6c6716c ] Loongson-2K SOC and LS7A2000 chipset add new PCI IDs that need MRRS quirk. Add them. Link: https://lore.kernel.org/r/20230211023321.3530080-1-chenhuacai@loongson.cn Signed-off-by: Huacai Chen Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/controller/pci-loongson.c | 33 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index dc7b4e4293ce..e73e18a73833 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -13,9 +13,14 @@ #include "../pci.h" /* Device IDs */ -#define DEV_PCIE_PORT_0 0x7a09 -#define DEV_PCIE_PORT_1 0x7a19 -#define DEV_PCIE_PORT_2 0x7a29 +#define DEV_LS2K_PCIE_PORT0 0x1a05 +#define DEV_LS7A_PCIE_PORT0 0x7a09 +#define DEV_LS7A_PCIE_PORT1 0x7a19 +#define DEV_LS7A_PCIE_PORT2 0x7a29 +#define DEV_LS7A_PCIE_PORT3 0x7a39 +#define DEV_LS7A_PCIE_PORT4 0x7a49 +#define DEV_LS7A_PCIE_PORT5 0x7a59 +#define DEV_LS7A_PCIE_PORT6 0x7a69 #define DEV_LS2K_APB 0x7a02 #define DEV_LS7A_CONF 0x7a10 @@ -38,11 +43,11 @@ static void bridge_class_quirk(struct pci_dev *dev) dev->class = PCI_CLASS_BRIDGE_PCI << 8; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_0, bridge_class_quirk); + DEV_LS7A_PCIE_PORT0, bridge_class_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_1, bridge_class_quirk); + DEV_LS7A_PCIE_PORT1, bridge_class_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_2, bridge_class_quirk); + DEV_LS7A_PCIE_PORT2, bridge_class_quirk); static void system_bus_quirk(struct pci_dev *pdev) { @@ -72,11 +77,21 @@ static void loongson_mrrs_quirk(struct pci_dev *pdev) bridge->no_inc_mrrs = 1; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_0, loongson_mrrs_quirk); + DEV_LS2K_PCIE_PORT0, loongson_mrrs_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_1, loongson_mrrs_quirk); + DEV_LS7A_PCIE_PORT0, loongson_mrrs_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_2, loongson_mrrs_quirk); + DEV_LS7A_PCIE_PORT1, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_PCIE_PORT2, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_PCIE_PORT3, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_PCIE_PORT4, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_PCIE_PORT5, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_PCIE_PORT6, loongson_mrrs_quirk); static void __iomem *cfg1_map(struct loongson_pci *priv, int bus, unsigned int devfn, int where) From 01923e3196ee60b9357624c120b8426c7261ae15 Mon Sep 17 00:00:00 2001 From: Mengyuan Lou Date: Tue, 7 Feb 2023 18:24:19 +0800 Subject: [PATCH 0623/1017] PCI: Add ACS quirk for Wangxun NICs [ Upstream commit a2b9b123ccac913e9f9b80337d687a2fe786a634 ] Wangxun has verified there is no peer-to-peer between functions for the below selection of SFxxx, RP1000 and RP2000 NICS. They may be multi-function devices, but the hardware does not advertise ACS capability. Add an ACS quirk for these devices so the functions can be in independent IOMMU groups. Link: https://lore.kernel.org/r/20230207102419.44326-1-mengyuanlou@net-swift.com Signed-off-by: Mengyuan Lou Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/quirks.c | 22 ++++++++++++++++++++++ include/linux/pci_ids.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f30c42f0ac31..c1ebd5e12b06 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4797,6 +4797,26 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags) PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } +/* + * Wangxun 10G/1G NICs have no ACS capability, and on multi-function + * devices, peer-to-peer transactions are not be used between the functions. + * So add an ACS quirk for below devices to isolate functions. + * SFxxx 1G NICs(em). + * RP1000/RP2000 10G NICs(sp). + */ +static int pci_quirk_wangxun_nic_acs(struct pci_dev *dev, u16 acs_flags) +{ + switch (dev->device) { + case 0x0100 ... 0x010F: + case 0x1001: + case 0x2001: + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); + } + + return false; +} + static const struct pci_dev_acs_enabled { u16 vendor; u16 device; @@ -4942,6 +4962,8 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs }, /* Zhaoxin Root/Downstream Ports */ { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, + /* Wangxun nics */ + { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, { 0 } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 69e310173fbc..2e1935917c24 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -3033,6 +3033,8 @@ #define PCI_DEVICE_ID_INTEL_VMD_9A0B 0x9a0b #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 +#define PCI_VENDOR_ID_WANGXUN 0x8088 + #define PCI_VENDOR_ID_SCALEMP 0x8686 #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010 From 4d2423f15b36a7a11075faa46ce7327c4375fd63 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 13 Feb 2023 11:57:09 +0800 Subject: [PATCH 0624/1017] phy: rockchip-typec: Fix unsigned comparison with less than zero [ Upstream commit f765c59c5a72546a2d74a92ae5d0eb0329d8e247 ] The dp and ufp are defined as bool type, the return value type of function extcon_get_state should be int, so the type of dp and ufp are modified to int. ./drivers/phy/rockchip/phy-rockchip-typec.c:827:12-14: WARNING: Unsigned expression compared with zero: dp > 0. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=3962 Signed-off-by: Jiapeng Chong Link: https://lore.kernel.org/r/20230213035709.99027-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/rockchip/phy-rockchip-typec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 70a31251b202..20f787d5ec58 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -808,9 +808,8 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy) struct extcon_dev *edev = tcphy->extcon; union extcon_property_value property; unsigned int id; - bool ufp, dp; u8 mode; - int ret; + int ret, ufp, dp; if (!edev) return MODE_DFP_USB; From e5ca5b71363a0a4902f8968191e8ddf939b5018e Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Fri, 2 Dec 2022 16:18:11 +0000 Subject: [PATCH 0625/1017] soundwire: cadence: Remove wasted space in response_buf [ Upstream commit 827c32d0df4bbe0d1c47d79f6a5eabfe9ac75216 ] The response_buf was declared much larger (128 entries) than the number of responses that could ever be written into it. The Cadence IP is configurable up to a maximum of 32 entries, and the datasheet says that RX_FIFO_AVAIL can be 2 larger than this. So allow up to 34 responses. Also add checking in cdns_read_response() to prevent overflowing reponse_buf if RX_FIFO_AVAIL contains an unexpectedly large number. Signed-off-by: Richard Fitzgerald Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221202161812.4186897-3-rf@opensource.cirrus.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/soundwire/cadence_master.c | 7 +++++++ drivers/soundwire/cadence_master.h | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index a3247692ddc0..292c4460eaaa 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -725,8 +725,15 @@ static void cdns_read_response(struct sdw_cdns *cdns) u32 num_resp, cmd_base; int i; + /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ + BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2); + num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT); num_resp &= CDNS_MCP_RX_FIFO_AVAIL; + if (num_resp > ARRAY_SIZE(cdns->response_buf)) { + dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp); + num_resp = ARRAY_SIZE(cdns->response_buf); + } cmd_base = CDNS_MCP_CMD_BASE; diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h index 4d1aab5b5ec2..e7f0108d417c 100644 --- a/drivers/soundwire/cadence_master.h +++ b/drivers/soundwire/cadence_master.h @@ -8,6 +8,12 @@ #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */ #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000) +/* + * The Cadence IP supports up to 32 entries in the FIFO, though implementations + * can configure the IP to have a smaller FIFO. + */ +#define CDNS_MCP_IP_MAX_CMD_LEN 32 + /** * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance * @@ -119,7 +125,12 @@ struct sdw_cdns { struct sdw_bus bus; unsigned int instance; - u32 response_buf[0x80]; + /* + * The datasheet says the RX FIFO AVAIL can be 2 entries more + * than the FIFO capacity, so allow for this. + */ + u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2]; + struct completion tx_complete; struct sdw_defer *defer; From a6549336f574658433e10a34e72f7669cac6afbe Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Fri, 2 Dec 2022 16:18:12 +0000 Subject: [PATCH 0626/1017] soundwire: cadence: Drain the RX FIFO after an IO timeout [ Upstream commit 0603a47bd3a8f439d7844b841eee1819353063e0 ] If wait_for_completion_timeout() times-out in _cdns_xfer_msg() it is possible that something could have been written to the RX FIFO. In this case, we should drain the RX FIFO so that anything in it doesn't carry over and mess up the next transfer. Obviously, if we got to this state something went wrong, and we don't really know the state of everything. The cleanup in this situation cannot be bullet-proof but we should attempt to avoid breaking future transaction, if only to reduce the amount of error noise when debugging the failure from a kernel log. Note that this patch only implements the draining for blocking (non-deferred) transfers. The deferred API doesn't have any proper handling of error conditions and would need some re-design before implementing cleanup. That is a task for a separate patch... Signed-off-by: Richard Fitzgerald Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221202161812.4186897-4-rf@opensource.cirrus.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/soundwire/cadence_master.c | 50 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 292c4460eaaa..18e7d158fcca 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -511,6 +511,29 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns, return SDW_CMD_OK; } +static void cdns_read_response(struct sdw_cdns *cdns) +{ + u32 num_resp, cmd_base; + int i; + + /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ + BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2); + + num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT); + num_resp &= CDNS_MCP_RX_FIFO_AVAIL; + if (num_resp > ARRAY_SIZE(cdns->response_buf)) { + dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp); + num_resp = ARRAY_SIZE(cdns->response_buf); + } + + cmd_base = CDNS_MCP_CMD_BASE; + + for (i = 0; i < num_resp; i++) { + cdns->response_buf[i] = cdns_readl(cdns, cmd_base); + cmd_base += CDNS_MCP_CMD_WORD_LEN; + } +} + static enum sdw_command_response _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, int offset, int count, bool defer) @@ -552,6 +575,10 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd, dev_err(cdns->dev, "IO transfer timed out, cmd %d device %d addr %x len %d\n", cmd, msg->dev_num, msg->addr, msg->len); msg->len = 0; + + /* Drain anything in the RX_FIFO */ + cdns_read_response(cdns); + return SDW_CMD_TIMEOUT; } @@ -720,29 +747,6 @@ EXPORT_SYMBOL(cdns_reset_page_addr); * IRQ handling */ -static void cdns_read_response(struct sdw_cdns *cdns) -{ - u32 num_resp, cmd_base; - int i; - - /* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ - BUILD_BUG_ON(ARRAY_SIZE(cdns->response_buf) < CDNS_MCP_CMD_LEN + 2); - - num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT); - num_resp &= CDNS_MCP_RX_FIFO_AVAIL; - if (num_resp > ARRAY_SIZE(cdns->response_buf)) { - dev_warn(cdns->dev, "RX AVAIL %d too long\n", num_resp); - num_resp = ARRAY_SIZE(cdns->response_buf); - } - - cmd_base = CDNS_MCP_CMD_BASE; - - for (i = 0; i < num_resp; i++) { - cdns->response_buf[i] = cdns_readl(cdns, cmd_base); - cmd_base += CDNS_MCP_CMD_WORD_LEN; - } -} - static int cdns_update_slave_status(struct sdw_cdns *cdns, u32 slave0, u32 slave1) { From 7123a4337bf73132bbfb5437e4dc83ba864a9a1e Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 28 Feb 2023 16:28:57 -0800 Subject: [PATCH 0627/1017] net: tls: avoid hanging tasks on the tx_lock commit f3221361dc85d4de22586ce8441ec2c67b454f5d upstream. syzbot sent a hung task report and Eric explains that adversarial receiver may keep RWIN at 0 for a long time, so we are not guaranteed to make forward progress. Thread which took tx_lock and went to sleep may not release tx_lock for hours. Use interruptible sleep where possible and reschedule the work if it can't take the lock. Testing: existing selftest passes Reported-by: syzbot+9c0268252b8ef967c62e@syzkaller.appspotmail.com Fixes: 79ffe6087e91 ("net/tls: add a TX lock") Link: https://lore.kernel.org/all/000000000000e412e905f5b46201@google.com/ Cc: stable@vger.kernel.org # wait 4 weeks Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20230301002857.2101894-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/tls/tls_sw.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 21f20c3cda97..ac7feadb4390 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -949,7 +949,9 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) MSG_CMSG_COMPAT)) return -EOPNOTSUPP; - mutex_lock(&tls_ctx->tx_lock); + ret = mutex_lock_interruptible(&tls_ctx->tx_lock); + if (ret) + return ret; lock_sock(sk); if (unlikely(msg->msg_controllen)) { @@ -1283,7 +1285,9 @@ int tls_sw_sendpage(struct sock *sk, struct page *page, MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY)) return -EOPNOTSUPP; - mutex_lock(&tls_ctx->tx_lock); + ret = mutex_lock_interruptible(&tls_ctx->tx_lock); + if (ret) + return ret; lock_sock(sk); ret = tls_sw_do_sendpage(sk, page, offset, size, flags); release_sock(sk); @@ -2266,11 +2270,19 @@ static void tx_work_handler(struct work_struct *work) if (!test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) return; - mutex_lock(&tls_ctx->tx_lock); - lock_sock(sk); - tls_tx_records(sk, -1); - release_sock(sk); - mutex_unlock(&tls_ctx->tx_lock); + + if (mutex_trylock(&tls_ctx->tx_lock)) { + lock_sock(sk); + tls_tx_records(sk, -1); + release_sock(sk); + mutex_unlock(&tls_ctx->tx_lock); + } else if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { + /* Someone is holding the tx_lock, they will likely run Tx + * and cancel the work on their way out of the lock section. + * Schedule a long delay just in case. + */ + schedule_delayed_work(&ctx->tx_work.work, msecs_to_jiffies(10)); + } } void tls_sw_write_space(struct sock *sk, struct tls_context *ctx) From 9554af98018cc29aea9a9b277ae10061e7e625f2 Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Thu, 17 Dec 2020 14:31:21 -0800 Subject: [PATCH 0628/1017] x86/resctrl: Apply READ_ONCE/WRITE_ONCE to task_struct.{rmid,closid} commit 6d3b47ddffed70006cf4ba360eef61e9ce097d8f upstream. A CPU's current task can have its {closid, rmid} fields read locally while they are being concurrently written to from another CPU. This can happen anytime __resctrl_sched_in() races with either __rdtgroup_move_task() or rdt_move_group_tasks(). Prevent load / store tearing for those accesses by giving them the READ_ONCE() / WRITE_ONCE() treatment. Signed-off-by: Valentin Schneider Signed-off-by: Reinette Chatre Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/9921fda88ad81afb9885b517fbe864a2bc7c35a9.1608243147.git.reinette.chatre@intel.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/resctrl.h | 11 +++++++---- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 10 +++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h index 07603064df8f..d60ed0668a59 100644 --- a/arch/x86/include/asm/resctrl.h +++ b/arch/x86/include/asm/resctrl.h @@ -56,19 +56,22 @@ static void __resctrl_sched_in(void) struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state); u32 closid = state->default_closid; u32 rmid = state->default_rmid; + u32 tmp; /* * If this task has a closid/rmid assigned, use it. * Else use the closid/rmid assigned to this cpu. */ if (static_branch_likely(&rdt_alloc_enable_key)) { - if (current->closid) - closid = current->closid; + tmp = READ_ONCE(current->closid); + if (tmp) + closid = tmp; } if (static_branch_likely(&rdt_mon_enable_key)) { - if (current->rmid) - rmid = current->rmid; + tmp = READ_ONCE(current->rmid); + if (tmp) + rmid = tmp; } if (closid != state->cur_closid || rmid != state->cur_rmid) { diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index ff26de11b3f1..296647930251 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -563,11 +563,11 @@ static int __rdtgroup_move_task(struct task_struct *tsk, */ if (rdtgrp->type == RDTCTRL_GROUP) { - tsk->closid = rdtgrp->closid; - tsk->rmid = rdtgrp->mon.rmid; + WRITE_ONCE(tsk->closid, rdtgrp->closid); + WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid); } else if (rdtgrp->type == RDTMON_GROUP) { if (rdtgrp->mon.parent->closid == tsk->closid) { - tsk->rmid = rdtgrp->mon.rmid; + WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid); } else { rdt_last_cmd_puts("Can't move task to different control group\n"); return -EINVAL; @@ -2312,8 +2312,8 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, for_each_process_thread(p, t) { if (!from || is_closid_match(t, from) || is_rmid_match(t, from)) { - t->closid = to->closid; - t->rmid = to->mon.rmid; + WRITE_ONCE(t->closid, to->closid); + WRITE_ONCE(t->rmid, to->mon.rmid); /* * Order the closid/rmid stores above before the loads From 411b8ad505f7686de182749cb293a8e887c2dd49 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 7 Mar 2023 13:06:29 -0800 Subject: [PATCH 0629/1017] x86/resctl: fix scheduler confusion with 'current' commit 7fef099702527c3b2c5234a2ea6a24411485a13a upstream. The implementation of 'current' on x86 is very intentionally special: it is a very common thing to look up, and it uses 'this_cpu_read_stable()' to get the current thread pointer efficiently from per-cpu storage. And the keyword in there is 'stable': the current thread pointer never changes as far as a single thread is concerned. Even if when a thread is preempted, or moved to another CPU, or even across an explicit call 'schedule()' that thread will still have the same value for 'current'. It is, after all, the kernel base pointer to thread-local storage. That's why it's stable to begin with, but it's also why it's important enough that we have that special 'this_cpu_read_stable()' access for it. So this is all done very intentionally to allow the compiler to treat 'current' as a value that never visibly changes, so that the compiler can do CSE and combine multiple different 'current' accesses into one. However, there is obviously one very special situation when the currently running thread does actually change: inside the scheduler itself. So the scheduler code paths are special, and do not have a 'current' thread at all. Instead there are _two_ threads: the previous and the next thread - typically called 'prev' and 'next' (or prev_p/next_p) internally. So this is all actually quite straightforward and simple, and not all that complicated. Except for when you then have special code that is run in scheduler context, that code then has to be aware that 'current' isn't really a valid thing. Did you mean 'prev'? Did you mean 'next'? In fact, even if then look at the code, and you use 'current' after the new value has been assigned to the percpu variable, we have explicitly told the compiler that 'current' is magical and always stable. So the compiler is quite free to use an older (or newer) value of 'current', and the actual assignment to the percpu storage is not relevant even if it might look that way. Which is exactly what happened in the resctl code, that blithely used 'current' in '__resctrl_sched_in()' when it really wanted the new process state (as implied by the name: we're scheduling 'into' that new resctl state). And clang would end up just using the old thread pointer value at least in some configurations. This could have happened with gcc too, and purely depends on random compiler details. Clang just seems to have been more aggressive about moving the read of the per-cpu current_task pointer around. The fix is trivial: just make the resctl code adhere to the scheduler rules of using the prev/next thread pointer explicitly, instead of using 'current' in a situation where it just wasn't valid. That same code is then also used outside of the scheduler context (when a thread resctl state is explicitly changed), and then we will just pass in 'current' as that pointer, of course. There is no ambiguity in that case. The fix may be trivial, but noticing and figuring out what went wrong was not. The credit for that goes to Stephane Eranian. Reported-by: Stephane Eranian Link: https://lore.kernel.org/lkml/20230303231133.1486085-1-eranian@google.com/ Link: https://lore.kernel.org/lkml/alpine.LFD.2.01.0908011214330.3304@localhost.localdomain/ Reviewed-by: Nick Desaulniers Tested-by: Tony Luck Tested-by: Stephane Eranian Tested-by: Babu Moger Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/resctrl.h | 12 ++++++------ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 4 ++-- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h index d60ed0668a59..b9ccdf5ea98b 100644 --- a/arch/x86/include/asm/resctrl.h +++ b/arch/x86/include/asm/resctrl.h @@ -51,7 +51,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); * simple as possible. * Must be called with preemption disabled. */ -static void __resctrl_sched_in(void) +static inline void __resctrl_sched_in(struct task_struct *tsk) { struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state); u32 closid = state->default_closid; @@ -63,13 +63,13 @@ static void __resctrl_sched_in(void) * Else use the closid/rmid assigned to this cpu. */ if (static_branch_likely(&rdt_alloc_enable_key)) { - tmp = READ_ONCE(current->closid); + tmp = READ_ONCE(tsk->closid); if (tmp) closid = tmp; } if (static_branch_likely(&rdt_mon_enable_key)) { - tmp = READ_ONCE(current->rmid); + tmp = READ_ONCE(tsk->rmid); if (tmp) rmid = tmp; } @@ -81,17 +81,17 @@ static void __resctrl_sched_in(void) } } -static inline void resctrl_sched_in(void) +static inline void resctrl_sched_in(struct task_struct *tsk) { if (static_branch_likely(&rdt_enable_key)) - __resctrl_sched_in(); + __resctrl_sched_in(tsk); } void resctrl_cpu_detect(struct cpuinfo_x86 *c); #else -static inline void resctrl_sched_in(void) {} +static inline void resctrl_sched_in(struct task_struct *tsk) {} static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {} #endif /* CONFIG_X86_CPU_RESCTRL */ diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 296647930251..1a943743cfe4 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -311,7 +311,7 @@ static void update_cpu_closid_rmid(void *info) * executing task might have its own closid selected. Just reuse * the context switch code. */ - resctrl_sched_in(); + resctrl_sched_in(current); } /* @@ -532,7 +532,7 @@ static void _update_task_closid_rmid(void *task) * Otherwise, the MSR is updated when the task is scheduled in. */ if (task == current) - resctrl_sched_in(); + resctrl_sched_in(task); } static void update_task_closid_rmid(struct task_struct *t) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 98bf8fd18902..3b4c394a1a76 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -214,7 +214,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) switch_fpu_finish(next_p); /* Load the Intel cache allocation PQR MSR. */ - resctrl_sched_in(); + resctrl_sched_in(next_p); return prev_p; } diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index ad3f82a18de9..1d8bc4736fb7 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -629,7 +629,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) } /* Load the Intel cache allocation PQR MSR. */ - resctrl_sched_in(); + resctrl_sched_in(next_p); return prev_p; } From ee4a4282d78d96e07e714c28ca54679713fa2157 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 14 Dec 2022 20:42:56 +0200 Subject: [PATCH 0630/1017] drm/display/dp_mst: Fix down/up message handling after sink disconnect commit 1d082618bbf3b6755b8cc68c0a8122af2842d593 upstream. If the sink gets disconnected during receiving a multi-packet DP MST AUX down-reply/up-request sideband message, the state keeping track of which packets have been received already is not reset. This results in a failed sanity check for the subsequent message packet received after a sink is reconnected (due to the pending message not yet completed with an end-of-message-transfer packet), indicated by the "sideband msg set header failed" error. Fix the above by resetting the up/down message reception state after a disconnect event. Cc: Lyude Paul Cc: # v3.17+ Signed-off-by: Imre Deak Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20221214184258.2869417-1-imre.deak@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_dp_mst_topology.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 0feeac52e4eb..9f40437ee252 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3769,6 +3769,9 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms set_bit(0, &mgr->payload_mask); mgr->vcpi_mask = 0; mgr->payload_id_table_cleared = false; + + memset(&mgr->down_rep_recv, 0, sizeof(mgr->down_rep_recv)); + memset(&mgr->up_req_recv, 0, sizeof(mgr->up_req_recv)); } out_unlock: From d90967f850b1f2ff600d2dcc4261487ffd23e523 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 14 Dec 2022 20:42:57 +0200 Subject: [PATCH 0631/1017] drm/display/dp_mst: Fix down message handling after a packet reception error commit 1241aedb6b5c7a5a8ad73e5eb3a41cfe18a3e00e upstream. After an error during receiving a packet for a multi-packet DP MST sideband message, the state tracking which packets have been received already is not reset. This prevents the reception of subsequent down messages (due to the pending message not yet completed with an end-of-message-transfer packet). Fix the above by resetting the reception state after a packet error. Cc: Lyude Paul Cc: # v3.17+ Signed-off-by: Imre Deak Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20221214184258.2869417-2-imre.deak@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_dp_mst_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 9f40437ee252..b5e15933cb5f 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3988,7 +3988,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) struct drm_dp_sideband_msg_rx *msg = &mgr->down_rep_recv; if (!drm_dp_get_one_sb_msg(mgr, false, &mstb)) - goto out; + goto out_clear_reply; /* Multi-packet message transmission, don't clear the reply */ if (!msg->have_eomt) From 7474be26b032f682b2166beb4a92c533f4de6a76 Mon Sep 17 00:00:00 2001 From: Nguyen Dinh Phi Date: Fri, 8 Oct 2021 03:04:24 +0800 Subject: [PATCH 0632/1017] Bluetooth: hci_sock: purge socket queues in the destruct() callback commit 709fca500067524381e28a5f481882930eebac88 upstream. The receive path may take the socket right before hci_sock_release(), but it may enqueue the packets to the socket queues after the call to skb_queue_purge(), therefore the socket can be destroyed without clear its queues completely. Moving these skb_queue_purge() to the hci_sock_destruct() will fix this issue, because nothing is referencing the socket at this point. Signed-off-by: Nguyen Dinh Phi Reported-by: syzbot+4c4ffd1e1094dae61035@syzkaller.appspotmail.com Signed-off-by: Marcel Holtmann Signed-off-by: Fedor Pchelkin Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_sock.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 71d18d3295f5..73779af2fed6 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -888,10 +888,6 @@ static int hci_sock_release(struct socket *sock) } sock_orphan(sk); - - skb_queue_purge(&sk->sk_receive_queue); - skb_queue_purge(&sk->sk_write_queue); - release_sock(sk); sock_put(sk); return 0; @@ -2012,6 +2008,12 @@ done: return err; } +static void hci_sock_destruct(struct sock *sk) +{ + skb_queue_purge(&sk->sk_receive_queue); + skb_queue_purge(&sk->sk_write_queue); +} + static const struct proto_ops hci_sock_ops = { .family = PF_BLUETOOTH, .owner = THIS_MODULE, @@ -2065,6 +2067,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol, sock->state = SS_UNCONNECTED; sk->sk_state = BT_OPEN; + sk->sk_destruct = hci_sock_destruct; bt_sock_link(&hci_sk_list, sk); return 0; From 0a1d0c79eaec745b6e9cafa0a55a2c762e93eeb9 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 13 Feb 2023 20:45:48 +0000 Subject: [PATCH 0633/1017] tcp: Fix listen() regression in 5.10.163 commit fdaf88531cfd17b2a710cceb3141ef6f9085ff40 upstream. When we backport dadd0dcaa67d ("net/ulp: prevent ULP without clone op from entering the LISTEN status"), we have accidentally backported a part of 7a7160edf1bf ("net: Return errno in sk->sk_prot->get_port().") and removed err = -EADDRINUSE in inet_csk_listen_start(). Thus, listen() no longer returns -EADDRINUSE even if ->get_port() failed as reported in [0]. We set -EADDRINUSE to err just before ->get_port() to fix the regression. [0]: https://lore.kernel.org/stable/EF8A45D0-768A-4CD5-9A8A-0FA6E610ABF7@winter.cafe/ Reported-by: Winter Signed-off-by: Kuniyuki Iwashima Signed-off-by: Greg Kroah-Hartman --- net/ipv4/inet_connection_sock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 9ed59147ef66..e05dd87848f7 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -946,6 +946,7 @@ int inet_csk_listen_start(struct sock *sk, int backlog) * It is OK, because this socket enters to hash table only * after validation is complete. */ + err = -EADDRINUSE; inet_sk_state_store(sk, TCP_LISTEN); if (!sk->sk_prot->get_port(sk, inet->inet_num)) { inet->inet_sport = htons(inet->inet_num); From c5fe3fba1b7bfecb6f17f93a433782b8500fe377 Mon Sep 17 00:00:00 2001 From: Harshit Mogalapalli Date: Thu, 2 Mar 2023 09:28:16 -0800 Subject: [PATCH 0634/1017] drm/virtio: Fix error code in virtio_gpu_object_shmem_init() In virtio_gpu_object_shmem_init() we are passing NULL to PTR_ERR, which is returning 0/success. Fix this by storing error value in 'ret' variable before assigning shmem->pages to NULL. Found using static analysis with Smatch. Fixes: 64b88afbd92f ("drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling") Signed-off-by: Harshit Mogalapalli Reviewed-by: Dmitry Osipenko Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/virtio/virtgpu_object.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 168148686001..49fa59e09187 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -159,8 +159,9 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base); if (IS_ERR(shmem->pages)) { drm_gem_shmem_unpin(&bo->base.base); + ret = PTR_ERR(shmem->pages); shmem->pages = NULL; - return PTR_ERR(shmem->pages); + return ret; } if (use_dma_api) { From 9d83b69e934db163fa60456dab1f01fd23f579ec Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Wed, 23 Dec 2020 14:35:20 +0100 Subject: [PATCH 0635/1017] media: uvcvideo: Provide sync and async uvc_ctrl_status_event commit d9c8763e61295be0a21dc04ad9c379d5d17c3d86 upstream. Split the functionality of void uvc_ctrl_status_event_work in two, so it can be called by functions outside interrupt context and not part of an URB. Signed-off-by: Ricardo Ribalda Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_ctrl.c | 25 +++++++++++++++---------- drivers/media/usb/uvc/uvc_status.c | 3 ++- drivers/media/usb/uvc/uvcvideo.h | 4 +++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index f479d8971dfb..327ffc232993 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1275,17 +1275,12 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); } -static void uvc_ctrl_status_event_work(struct work_struct *work) +void uvc_ctrl_status_event(struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data) { - struct uvc_device *dev = container_of(work, struct uvc_device, - async_ctrl.work); - struct uvc_ctrl_work *w = &dev->async_ctrl; - struct uvc_video_chain *chain = w->chain; struct uvc_control_mapping *mapping; - struct uvc_control *ctrl = w->ctrl; struct uvc_fh *handle; unsigned int i; - int ret; mutex_lock(&chain->ctrl_mutex); @@ -1293,7 +1288,7 @@ static void uvc_ctrl_status_event_work(struct work_struct *work) ctrl->handle = NULL; list_for_each_entry(mapping, &ctrl->info.mappings, list) { - s32 value = __uvc_ctrl_get_value(mapping, w->data); + s32 value = __uvc_ctrl_get_value(mapping, data); /* * handle may be NULL here if the device sends auto-update @@ -1312,6 +1307,16 @@ static void uvc_ctrl_status_event_work(struct work_struct *work) } mutex_unlock(&chain->ctrl_mutex); +} + +static void uvc_ctrl_status_event_work(struct work_struct *work) +{ + struct uvc_device *dev = container_of(work, struct uvc_device, + async_ctrl.work); + struct uvc_ctrl_work *w = &dev->async_ctrl; + int ret; + + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); /* Resubmit the URB. */ w->urb->interval = dev->int_ep->desc.bInterval; @@ -1321,8 +1326,8 @@ static void uvc_ctrl_status_event_work(struct work_struct *work) ret); } -bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, - struct uvc_control *ctrl, const u8 *data) +bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data) { struct uvc_device *dev = chain->dev; struct uvc_ctrl_work *w = &dev->async_ctrl; diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index 2bdb0ff203f8..3e26d82a906d 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c @@ -179,7 +179,8 @@ static bool uvc_event_control(struct urb *urb, switch (status->bAttribute) { case UVC_CTRL_VALUE_CHANGE: - return uvc_ctrl_status_event(urb, chain, ctrl, status->bValue); + return uvc_ctrl_status_event_async(urb, chain, ctrl, + status->bValue); case UVC_CTRL_INFO_CHANGE: case UVC_CTRL_FAILURE_CHANGE: diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 284200becbbd..8a590e0895fb 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -839,7 +839,9 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, int uvc_ctrl_init_device(struct uvc_device *dev); void uvc_ctrl_cleanup_device(struct uvc_device *dev); int uvc_ctrl_restore_values(struct uvc_device *dev); -bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, +bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data); +void uvc_ctrl_status_event(struct uvc_video_chain *chain, struct uvc_control *ctrl, const u8 *data); int uvc_ctrl_begin(struct uvc_video_chain *chain); From 331c18e8ac810eec0058834a3a5fd35b54d7a7f9 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Thu, 5 Jan 2023 15:31:29 +0100 Subject: [PATCH 0636/1017] media: uvcvideo: Fix race condition with usb_kill_urb commit 619d9b710cf06f7a00a17120ca92333684ac45a8 upstream. usb_kill_urb warranties that all the handlers are finished when it returns, but does not protect against threads that might be handling asynchronously the urb. For UVC, the function uvc_ctrl_status_event_async() takes care of control changes asynchronously. If the code is executed in the following order: CPU 0 CPU 1 ===== ===== uvc_status_complete() uvc_status_stop() uvc_ctrl_status_event_work() uvc_status_start() -> FAIL Then uvc_status_start will keep failing and this error will be shown: <4>[ 5.540139] URB 0000000000000000 submitted while active drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528 Let's improve the current situation, by not re-submiting the urb if we are stopping the status event. Also process the queued work (if any) during stop. CPU 0 CPU 1 ===== ===== uvc_status_complete() uvc_status_stop() uvc_status_start() uvc_ctrl_status_event_work() -> FAIL Hopefully, with the usb layer protection this should be enough to cover all the cases. Cc: stable@vger.kernel.org Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives") Reviewed-by: Yunke Cao Signed-off-by: Ricardo Ribalda Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_ctrl.c | 5 ++++ drivers/media/usb/uvc/uvc_status.c | 37 ++++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 43 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 327ffc232993..5e0acabed37a 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -6,6 +6,7 @@ * Laurent Pinchart (laurent.pinchart@ideasonboard.com) */ +#include #include #include #include @@ -1318,6 +1319,10 @@ static void uvc_ctrl_status_event_work(struct work_struct *work) uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + /* The barrier is needed to synchronize with uvc_status_stop(). */ + if (smp_load_acquire(&dev->flush_status)) + return; + /* Resubmit the URB. */ w->urb->interval = dev->int_ep->desc.bInterval; ret = usb_submit_urb(w->urb, GFP_KERNEL); diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index 3e26d82a906d..73725051cc16 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c @@ -6,6 +6,7 @@ * Laurent Pinchart (laurent.pinchart@ideasonboard.com) */ +#include #include #include #include @@ -310,5 +311,41 @@ int uvc_status_start(struct uvc_device *dev, gfp_t flags) void uvc_status_stop(struct uvc_device *dev) { + struct uvc_ctrl_work *w = &dev->async_ctrl; + + /* + * Prevent the asynchronous control handler from requeing the URB. The + * barrier is needed so the flush_status change is visible to other + * CPUs running the asynchronous handler before usb_kill_urb() is + * called below. + */ + smp_store_release(&dev->flush_status, true); + + /* + * Cancel any pending asynchronous work. If any status event was queued, + * process it synchronously. + */ + if (cancel_work_sync(&w->work)) + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + + /* Kill the urb. */ usb_kill_urb(dev->int_urb); + + /* + * The URB completion handler may have queued asynchronous work. This + * won't resubmit the URB as flush_status is set, but it needs to be + * cancelled before returning or it could then race with a future + * uvc_status_start() call. + */ + if (cancel_work_sync(&w->work)) + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + + /* + * From this point, there are no events on the queue and the status URB + * is dead. No events will be queued until uvc_status_start() is called. + * The barrier is needed to make sure that flush_status is visible to + * uvc_ctrl_status_event_work() when uvc_status_start() will be called + * again. + */ + smp_store_release(&dev->flush_status, false); } diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 8a590e0895fb..c75990c0957e 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -670,6 +670,7 @@ struct uvc_device { /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; + bool flush_status; u8 *status; struct input_dev *input; char input_phys[64]; From f73bbfb47ff10d8a6288bd37a833fb987cc5a6f2 Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Wed, 8 Mar 2023 17:14:56 +0100 Subject: [PATCH 0637/1017] Revert "scsi: mpt3sas: Fix return value check of dma_get_required_mask()" This reverts commit e0e0747de0ea3dd87cdbb0393311e17471a9baf1. As noted in 1a2dcbdde82e ("scsi: mpt3sas: re-do lost mpt3sas DMA mask fix") in mainline there was a mis-merge in commit 62e6e5940c0c ("Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi"). causing that the fix needed to be redone later on again. To make series of patches apply cleanly to the stable series where e0e0747de0ea ("scsi: mpt3sas: Fix return value check of dma_get_required_mask()") was backported, revert the aforementioned commit. No upstream commit exists for this commit. Link: https://lore.kernel.org/regressions/yq1sfehmjnb.fsf@ca-mkp.ca.oracle.com/ Signed-off-by: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 2ad75c9a9088..c7830f7ad19d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2825,7 +2825,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma || - dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32)) + dma_get_required_mask(&pdev->dev) <= 32) ioc->dma_mask = 32; /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) From 2392303df240e7d036df8872ada176734e108036 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Thu, 25 Aug 2022 13:24:54 +0530 Subject: [PATCH 0638/1017] scsi: mpt3sas: Don't change DMA mask while reallocating pools commit 9df650963bf6d6c2c3fcd325d8c44ca2b99554fe upstream. When a pool crosses the 4GB boundary region then before reallocating pools change the coherent DMA mask to 32 bits and keep the normal DMA mask set to 63/64 bits. Link: https://lore.kernel.org/r/20220825075457.16422-2-sreekanth.reddy@broadcom.com Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen Signed-off-by: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mpt3sas/mpt3sas_base.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index c7830f7ad19d..eb37460ce109 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2822,19 +2822,26 @@ static int _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) { struct sysinfo s; + u64 coherent_dma_mask, dma_mask; - if (ioc->is_mcpu_endpoint || - sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma || - dma_get_required_mask(&pdev->dev) <= 32) + if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 || + dma_get_required_mask(&pdev->dev) <= 32) { ioc->dma_mask = 32; + coherent_dma_mask = dma_mask = DMA_BIT_MASK(32); /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ - else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) + } else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) { ioc->dma_mask = 63; - else + coherent_dma_mask = dma_mask = DMA_BIT_MASK(63); + } else { ioc->dma_mask = 64; + coherent_dma_mask = dma_mask = DMA_BIT_MASK(64); + } - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)) || - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask))) + if (ioc->use_32bit_dma) + coherent_dma_mask = DMA_BIT_MASK(32); + + if (dma_set_mask(&pdev->dev, dma_mask) || + dma_set_coherent_mask(&pdev->dev, coherent_dma_mask)) return -ENODEV; if (ioc->dma_mask > 32) { From 747652f9c5037cc27544c1fe44c4125876e4ef34 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Tue, 13 Sep 2022 17:35:38 +0530 Subject: [PATCH 0639/1017] scsi: mpt3sas: re-do lost mpt3sas DMA mask fix commit 1a2dcbdde82e3a5f1db9b2f4c48aa1aeba534fb2 upstream. This is a re-do of commit e0e0747de0ea ("scsi: mpt3sas: Fix return value check of dma_get_required_mask()"), which I ended up undoing in a mis-merge in commit 62e6e5940c0c ("Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi"). The original commit message was scsi: mpt3sas: Fix return value check of dma_get_required_mask() Fix the incorrect return value check of dma_get_required_mask(). Due to this incorrect check, the driver was always setting the DMA mask to 63 bit. Link: https://lore.kernel.org/r/20220913120538.18759-2-sreekanth.reddy@broadcom.com Fixes: ba27c5cf286d ("scsi: mpt3sas: Don't change the DMA coherent mask after allocations") Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen and this fix was lost when I mis-merged the conflict with commit 9df650963bf6 ("scsi: mpt3sas: Don't change DMA mask while reallocating pools"). Reported-by: Juergen Gross Fixes: 62e6e5940c0c ("Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi") Link: https://lore.kernel.org/all/CAHk-=wjaK-TxrNaGtFDpL9qNHL1MVkWXO1TT6vObD5tXMSC4Zg@mail.gmail.com Signed-off-by: Linus Torvalds Signed-off-by: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index eb37460ce109..2ab72f8818ee 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2825,7 +2825,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) u64 coherent_dma_mask, dma_mask; if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 || - dma_get_required_mask(&pdev->dev) <= 32) { + dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32)) { ioc->dma_mask = 32; coherent_dma_mask = dma_mask = DMA_BIT_MASK(32); /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ From 1dfc0a52f768d481de6bb672904cd382ead7ca0e Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 28 Oct 2022 14:46:55 +0530 Subject: [PATCH 0640/1017] scsi: mpt3sas: Remove usage of dma_get_required_mask() API commit 06e472acf964649a58b7de35fc9cdc3151acb970 upstream. Remove the usage of dma_get_required_mask() API. Directly set the DMA mask to 63/64 if the system is a 64bit machine. Signed-off-by: Sreekanth Reddy Link: https://lore.kernel.org/r/20221028091655.17741-2-sreekanth.reddy@broadcom.com Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen Signed-off-by: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mpt3sas/mpt3sas_base.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 2ab72f8818ee..26b15a24300e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2824,8 +2824,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) struct sysinfo s; u64 coherent_dma_mask, dma_mask; - if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 || - dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32)) { + if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4) { ioc->dma_mask = 32; coherent_dma_mask = dma_mask = DMA_BIT_MASK(32); /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ From a5bbea50d622b8f49ab8ee3b0eb283107febcf1a Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 13 Dec 2021 07:21:15 +0000 Subject: [PATCH 0641/1017] malidp: Fix NULL vs IS_ERR() checking commit 15342f930ebebcfe36f2415049736a77d7d2e045 upstream. The get_sg_table() function does not return NULL. It returns error pointers. Signed-off-by: Miaoqian Lin Signed-off-by: Liviu Dudau Link: https://lore.kernel.org/dri-devel/20211213072115.18098-1-linmq006@gmail.com/ Signed-off-by: Stefan Ghinea Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/arm/malidp_planes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index f1e8bc39b16d..24604b410372 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -348,7 +348,7 @@ static bool malidp_check_pages_threshold(struct malidp_plane_state *ms, else sgt = obj->funcs->get_sg_table(obj); - if (!sgt) + if (IS_ERR(sgt)) return false; sgl = sgt->sgl; From 8ecd5dabddc0b70d82ca45e8c664e31fd04eaa92 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 13 Feb 2023 15:09:26 +0800 Subject: [PATCH 0642/1017] usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails commit 7ebb605d2283fb2647b4fa82030307ce00bee436 upstream. If kstrtou8() fails, the mutex_unlock() is missed, move kstrtou8() before mutex_lock() to fix it up. Fixes: 0525210c9840 ("usb: gadget: uvc: Allow definition of XUs in configfs") Fixes: b3c839bd8a07 ("usb: gadget: uvc: Make bSourceID read/write") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230213070926.776447-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/uvc_configfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 7bb11d532b19..2db01170d096 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -546,6 +546,10 @@ static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, int result; u8 num; + result = kstrtou8(page, 0, &num); + if (result) + return result; + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ opts_item = group->cg_item.ci_parent->ci_parent-> @@ -553,10 +557,6 @@ static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, opts = to_f_uvc_opts(opts_item); cd = &opts->uvc_output_terminal; - result = kstrtou8(page, 0, &num); - if (result) - return result; - mutex_lock(&opts->lock); cd->bSourceID = num; mutex_unlock(&opts->lock); From e5f315b55f8e09ac17c968da42f9345f64efcdd2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 11 Mar 2023 16:40:21 +0100 Subject: [PATCH 0643/1017] Linux 5.10.173 Link: https://lore.kernel.org/r/20230310133804.978589368@linuxfoundation.org Tested-by: Jon Hunter Tested-by: Salvatore Bonaccorso Tested-by: Shuah Khan Tested-by: Sudip Mukherjee Link: https://lore.kernel.org/r/20230311091908.975813595@linuxfoundation.org Tested-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5ca862041b71..1a6ea7994079 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 172 +SUBLEVEL = 173 EXTRAVERSION = NAME = Dare mighty things From decf73066f7eae34e434f707698c2c8b3bc62902 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 11 Mar 2023 23:19:14 +0900 Subject: [PATCH 0644/1017] wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext" commit 79d1ed5ca7db67d48e870c979f0e0f6b0947944a upstream. This reverts part of commit 015b8cc5e7c4 ("wifi: cfg80211: Fix use after free for wext") This commit broke WPA offload by unconditionally clearing the crypto modes for non-WEP connections. Drop that part of the patch. Signed-off-by: Hector Martin Reported-by: Ilya Reported-and-tested-by: Janne Grunau Reviewed-by: Eric Curtin Fixes: 015b8cc5e7c4 ("wifi: cfg80211: Fix use after free for wext") Cc: stable@kernel.org Link: https://lore.kernel.org/linux-wireless/ZAx0TWRBlGfv7pNl@kroah.com/T/#m11e6e0915ab8fa19ce8bc9695ab288c0fe018edf Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- net/wireless/sme.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index f4d98ed8fa31..f7e2e172a68d 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -1264,8 +1264,6 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, connect->key = NULL; connect->key_len = 0; connect->key_idx = 0; - connect->crypto.cipher_group = 0; - connect->crypto.n_ciphers_pairwise = 0; } wdev->connect_keys = connkeys; From 1afff6203a734f9e6eacdc356c29b2fabd82f1b6 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 28 Feb 2023 21:28:57 +0100 Subject: [PATCH 0645/1017] staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script commit a98fc23cc2c1e4382a79ff137ca1a93d6a73b451 upstream. Remove function _rtl92e_dm_check_ac_dc_power calling a script /etc/acpi/wireless-rtl-ac-dc-power.sh that is not available. This script is not part of the kernel and it is not available on the www. The result is that this function is just dead code. Signed-off-by: Philipp Hortmann Cc: stable Link: https://lore.kernel.org/r/20230228202857.GA16442@matrix-ESPRIMO-P710 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 27 ---------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 462835684e8b..9a02330864de 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -185,7 +185,6 @@ static void _rtl92e_dm_init_fsync(struct net_device *dev); static void _rtl92e_dm_deinit_fsync(struct net_device *dev); static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev); -static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev); static void _rtl92e_dm_check_fsync(struct net_device *dev); static void _rtl92e_dm_check_rf_ctrl_gpio(void *data); static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t); @@ -238,8 +237,6 @@ void rtl92e_dm_watchdog(struct net_device *dev) if (priv->being_init_adapter) return; - _rtl92e_dm_check_ac_dc_power(dev); - _rtl92e_dm_check_txrateandretrycount(dev); _rtl92e_dm_check_edca_turbo(dev); @@ -257,30 +254,6 @@ void rtl92e_dm_watchdog(struct net_device *dev) _rtl92e_dm_cts_to_self(dev); } -static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev) -{ - struct r8192_priv *priv = rtllib_priv(dev); - static char const ac_dc_script[] = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; - char *argv[] = {(char *)ac_dc_script, DRV_NAME, NULL}; - static char *envp[] = {"HOME=/", - "TERM=linux", - "PATH=/usr/bin:/bin", - NULL}; - - if (priv->ResetProgress == RESET_TYPE_SILENT) { - RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), - "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n"); - return; - } - - if (priv->rtllib->state != RTLLIB_LINKED) - return; - call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC); - - return; -}; - - void rtl92e_init_adaptive_rate(struct net_device *dev) { From c036dae0367852ac08d0810478d7276e47ebc0c6 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Wed, 1 Mar 2023 22:54:41 +0100 Subject: [PATCH 0646/1017] staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh commit fe413a074a93d56f89e322c786aad8639afe76b4 upstream. Remove call_usermodehelper starting /etc/acpi/events/RadioPower.sh that is not available. This script is not part of the kernel and it is not officially available on the www. The result is that this lines are just dead code. Signed-off-by: Philipp Hortmann Cc: stable Link: https://lore.kernel.org/r/20230301215441.GA14049@matrix-ESPRIMO-P710 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index 9a02330864de..916ff5058ae7 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -1773,10 +1773,6 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data) u8 tmp1byte; enum rt_rf_power_state eRfPowerStateToSet; bool bActuallySet = false; - char *argv[3]; - static char const RadioPowerPath[] = "/etc/acpi/events/RadioPower.sh"; - static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", - NULL}; bActuallySet = false; @@ -1808,14 +1804,6 @@ static void _rtl92e_dm_check_rf_ctrl_gpio(void *data) mdelay(1000); priv->bHwRfOffAction = 1; rtl92e_set_rf_state(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); - if (priv->bHwRadioOff) - argv[1] = "RFOFF"; - else - argv[1] = "RFON"; - - argv[0] = (char *)RadioPowerPath; - argv[2] = NULL; - call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC); } } From 955623617f2f505ac08d0efda2bb50c1a52e2c96 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Mar 2023 10:19:37 +0100 Subject: [PATCH 0647/1017] Linux 5.10.174 Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1a6ea7994079..92accf2ddc08 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 173 +SUBLEVEL = 174 EXTRAVERSION = NAME = Dare mighty things From a759905de9cd6ec9ca08ceadf0920272772ed830 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 6 Mar 2023 13:54:50 -0500 Subject: [PATCH 0648/1017] fs: prevent out-of-bounds array speculation when closing a file descriptor commit 609d54441493c99f21c1823dfd66fa7f4c512ff4 upstream. Google-Bug-Id: 114199369 Signed-off-by: Theodore Ts'o Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/file.c b/fs/file.c index 97a0cd31faec..173d318208b8 100644 --- a/fs/file.c +++ b/fs/file.c @@ -677,6 +677,7 @@ static struct file *pick_file(struct files_struct *files, unsigned fd) fdt = files_fdtable(files); if (fd >= fdt->max_fds) goto out_unlock; + fd = array_index_nospec(fd, fdt->max_fds); file = fdt->fd[fd]; if (!file) goto out_unlock; From a1eb8bf1e35f5d274efcfd55e91361a91d85e327 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 8 Mar 2023 11:51:26 +0100 Subject: [PATCH 0649/1017] fork: allow CLONE_NEWTIME in clone3 flags commit a402f1e35313fc7ce2ca60f543c4402c2c7c3544 upstream. Currently, calling clone3() with CLONE_NEWTIME in clone_args->flags fails with -EINVAL. This is because CLONE_NEWTIME intersects with CSIGNAL. However, CSIGNAL was deprecated when clone3 was introduced in commit 7f192e3cd316 ("fork: add clone3"), allowing re-use of that part of clone flags. Fix this by explicitly allowing CLONE_NEWTIME in clone3_args_valid. This is also in line with the respective check in check_unshare_flags which allow CLONE_NEWTIME for unshare(). Fixes: 769071ac9f20 ("ns: Introduce Time Namespace") Cc: Andrey Vagin Cc: Christian Brauner Cc: stable@vger.kernel.org Signed-off-by: Tobias Klauser Reviewed-by: Christian Brauner Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Greg Kroah-Hartman --- kernel/fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/fork.c b/kernel/fork.c index 68efe2a0b4fb..a5bc0c6a00fd 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2726,7 +2726,7 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs) * - make the CLONE_DETACHED bit reuseable for clone3 * - make the CSIGNAL bits reuseable for clone3 */ - if (kargs->flags & (CLONE_DETACHED | CSIGNAL)) + if (kargs->flags & (CLONE_DETACHED | (CSIGNAL & (~CLONE_NEWTIME)))) return false; if ((kargs->flags & (CLONE_SIGHAND | CLONE_CLEAR_SIGHAND)) == From 5462843dc40f23fcdacac0460b75ec4916ef6ae6 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 7 Mar 2023 17:46:43 +0000 Subject: [PATCH 0650/1017] x86/CPU/AMD: Disable XSAVES on AMD family 0x17 commit b0563468eeac88ebc70559d52a0b66efc37e4e9d upstream. AMD Erratum 1386 is summarised as: XSAVES Instruction May Fail to Save XMM Registers to the Provided State Save Area This piece of accidental chronomancy causes the %xmm registers to occasionally reset back to an older value. Ignore the XSAVES feature on all AMD Zen1/2 hardware. The XSAVEC instruction (which works fine) is equivalent on affected parts. [ bp: Typos, move it into the F17h-specific function. ] Reported-by: Tavis Ormandy Signed-off-by: Andrew Cooper Signed-off-by: Borislav Petkov (AMD) Cc: Link: https://lore.kernel.org/r/20230307174643.1240184-1-andrew.cooper3@citrix.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/amd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index ec3fa4dc9031..89a9b7754476 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -932,6 +932,15 @@ void init_spectral_chicken(struct cpuinfo_x86 *c) } } #endif + /* + * Work around Erratum 1386. The XSAVES instruction malfunctions in + * certain circumstances on Zen1/2 uarch, and not all parts have had + * updated microcode at the time of writing (March 2023). + * + * Affected parts all have no supervisor XSAVE states, meaning that + * the XSAVEC instruction (which works fine) is equivalent. + */ + clear_cpu_cap(c, X86_FEATURE_XSAVES); } static void init_amd_zn(struct cpuinfo_x86 *c) From 4279e87da6c88d63796904184b6f027321e370ab Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 6 Mar 2023 10:34:20 -0500 Subject: [PATCH 0651/1017] drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15 commit 0dcdf8498eae2727bb33cef3576991dc841d4343 upstream. Properly skip non-existent registers as well. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2442 Reviewed-by: Hawking Zhang Reviewed-by: Evan Quan Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/soc15.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 7212b9900e0a..994e6635b834 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -382,8 +382,9 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num, *value = 0; for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) { en = &soc15_allowed_read_registers[i]; - if (adev->reg_offset[en->hwip][en->inst] && - reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg] + if (!adev->reg_offset[en->hwip][en->inst]) + continue; + else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) continue; From 3106cb47cded559a8937b26d6cf4740f6f5de76f Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 13 Jan 2023 11:24:09 -0500 Subject: [PATCH 0652/1017] drm/connector: print max_requested_bpc in state debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7d386975f6a495902e679a3a250a7456d7e54765 upstream. This is useful to understand the bpc defaults and support of a driver. Signed-off-by: Harry Wentland Cc: Pekka Paalanen Cc: Sebastian Wick Cc: Vitaly.Prosyak@amd.com Cc: Uma Shankar Cc: Ville Syrjälä Cc: Joshua Ashton Cc: Jani Nikula Cc: dri-devel@lists.freedesktop.org Cc: amd-gfx@lists.freedesktop.org Reviewed-By: Joshua Ashton Link: https://patchwork.freedesktop.org/patch/msgid/20230113162428.33874-3-harry.wentland@amd.com Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_atomic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 58527f151984..98b659981f1a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1010,6 +1010,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name); drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)"); drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware); + drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) if (state->writeback_job && state->writeback_job->fb) From d0632ff49bd1a7d56f33ef2b935acbb6d00c9310 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 2 Feb 2023 16:55:03 -0800 Subject: [PATCH 0653/1017] ext4: fix cgroup writeback accounting with fs-layer encryption commit ffec85d53d0f39ee4680a2cf0795255e000e1feb upstream. When writing a page from an encrypted file that is using filesystem-layer encryption (not inline encryption), ext4 encrypts the pagecache page into a bounce page, then writes the bounce page. It also passes the bounce page to wbc_account_cgroup_owner(). That's incorrect, because the bounce page is a newly allocated temporary page that doesn't have the memory cgroup of the original pagecache page. This makes wbc_account_cgroup_owner() not account the I/O to the owner of the pagecache page as it should. Fix this by always passing the pagecache page to wbc_account_cgroup_owner(). Fixes: 001e4a8775f6 ("ext4: implement cgroup writeback support") Cc: stable@vger.kernel.org Reported-by: Matthew Wilcox (Oracle) Signed-off-by: Eric Biggers Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20230203005503.141557-1-ebiggers@kernel.org Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/page-io.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 4569075a7da0..a94cc7b22d7e 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -416,7 +416,8 @@ static void io_submit_init_bio(struct ext4_io_submit *io, static void io_submit_add_bh(struct ext4_io_submit *io, struct inode *inode, - struct page *page, + struct page *pagecache_page, + struct page *bounce_page, struct buffer_head *bh) { int ret; @@ -430,10 +431,11 @@ submit_and_retry: io_submit_init_bio(io, bh); io->io_bio->bi_write_hint = inode->i_write_hint; } - ret = bio_add_page(io->io_bio, page, bh->b_size, bh_offset(bh)); + ret = bio_add_page(io->io_bio, bounce_page ?: pagecache_page, + bh->b_size, bh_offset(bh)); if (ret != bh->b_size) goto submit_and_retry; - wbc_account_cgroup_owner(io->io_wbc, page, bh->b_size); + wbc_account_cgroup_owner(io->io_wbc, pagecache_page, bh->b_size); io->io_next_block++; } @@ -551,8 +553,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, do { if (!buffer_async_write(bh)) continue; - io_submit_add_bh(io, inode, - bounce_page ? bounce_page : page, bh); + io_submit_add_bh(io, inode, page, bounce_page, bh); nr_submitted++; clear_buffer_dirty(bh); } while ((bh = bh->b_this_page) != head); From 8706c972fcfa8c9533f37989c808a18bfa058ccd Mon Sep 17 00:00:00 2001 From: Eric Whitney Date: Fri, 10 Feb 2023 12:32:44 -0500 Subject: [PATCH 0654/1017] ext4: fix RENAME_WHITEOUT handling for inline directories commit c9f62c8b2dbf7240536c0cc9a4529397bb8bf38e upstream. A significant number of xfstests can cause ext4 to log one or more warning messages when they are run on a test file system where the inline_data feature has been enabled. An example: "EXT4-fs warning (device vdc): ext4_dirblock_csum_set:425: inode #16385: comm fsstress: No space for directory leaf checksum. Please run e2fsck -D." The xfstests include: ext4/057, 058, and 307; generic/013, 051, 068, 070, 076, 078, 083, 232, 269, 270, 390, 461, 475, 476, 482, 579, 585, 589, 626, 631, and 650. In this situation, the warning message indicates a bug in the code that performs the RENAME_WHITEOUT operation on a directory entry that has been stored inline. It doesn't detect that the directory is stored inline, and incorrectly attempts to compute a dirent block checksum on the whiteout inode when creating it. This attempt fails as a result of the integrity checking in get_dirent_tail (usually due to a failure to match the EXT4_FT_DIR_CSUM magic cookie), and the warning message is then emitted. Fix this by simply collecting the inlined data state at the time the search for the source directory entry is performed. Existing code handles the rest, and this is sufficient to eliminate all spurious warning messages produced by the tests above. Go one step further and do the same in the code that resets the source directory entry in the event of failure. The inlined state should be present in the "old" struct, but given the possibility of a race there's no harm in taking a conservative approach and getting that information again since the directory entry is being reread anyway. Fixes: b7ff91fd030d ("ext4: find old entry again if failed to rename whiteout") Cc: stable@kernel.org Signed-off-by: Eric Whitney Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230210173244.679890-1-enwlinux@gmail.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/namei.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 7ec7c9c16a39..6f335d58183e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1512,11 +1512,10 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, int has_inline_data = 1; ret = ext4_find_inline_entry(dir, fname, res_dir, &has_inline_data); - if (has_inline_data) { - if (inlined) - *inlined = 1; + if (inlined) + *inlined = has_inline_data; + if (has_inline_data) goto cleanup_and_exit; - } } if ((namelen <= 2) && (name[0] == '.') && @@ -3698,7 +3697,8 @@ static void ext4_resetent(handle_t *handle, struct ext4_renament *ent, * so the old->de may no longer valid and need to find it again * before reset old inode info. */ - old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); + old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, + &old.inlined); if (IS_ERR(old.bh)) retval = PTR_ERR(old.bh); if (!old.bh) @@ -3863,7 +3863,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, return retval; } - old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); + old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, + &old.inlined); if (IS_ERR(old.bh)) return PTR_ERR(old.bh); /* From 1d2366624b4c19a2ba6baf67fe57f4a1b0f67c05 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 16 Feb 2023 10:55:48 -0800 Subject: [PATCH 0655/1017] ext4: fix another off-by-one fsmap error on 1k block filesystems commit c993799baf9c5861f8df91beb80e1611b12efcbd upstream. Apparently syzbot figured out that issuing this FSMAP call: struct fsmap_head cmd = { .fmh_count = ...; .fmh_keys = { { .fmr_device = /* ext4 dev */, .fmr_physical = 0, }, { .fmr_device = /* ext4 dev */, .fmr_physical = 0, }, }, ... }; ret = ioctl(fd, FS_IOC_GETFSMAP, &cmd); Produces this crash if the underlying filesystem is a 1k-block ext4 filesystem: kernel BUG at fs/ext4/ext4.h:3331! invalid opcode: 0000 [#1] PREEMPT SMP CPU: 3 PID: 3227965 Comm: xfs_io Tainted: G W O 6.2.0-rc8-achx Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 RIP: 0010:ext4_mb_load_buddy_gfp+0x47c/0x570 [ext4] RSP: 0018:ffffc90007c03998 EFLAGS: 00010246 RAX: ffff888004978000 RBX: ffffc90007c03a20 RCX: ffff888041618000 RDX: 0000000000000000 RSI: 00000000000005a4 RDI: ffffffffa0c99b11 RBP: ffff888012330000 R08: ffffffffa0c2b7d0 R09: 0000000000000400 R10: ffffc90007c03950 R11: 0000000000000000 R12: 0000000000000001 R13: 00000000ffffffff R14: 0000000000000c40 R15: ffff88802678c398 FS: 00007fdf2020c880(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd318a5fe8 CR3: 000000007f80f001 CR4: 00000000001706e0 Call Trace: ext4_mballoc_query_range+0x4b/0x210 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] ext4_getfsmap_datadev+0x713/0x890 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] ext4_getfsmap+0x2b7/0x330 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] ext4_ioc_getfsmap+0x153/0x2b0 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] __ext4_ioctl+0x2a7/0x17e0 [ext4 dfa189daddffe8fecd3cdfd00564e0f265a8ab80] __x64_sys_ioctl+0x82/0xa0 do_syscall_64+0x2b/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x7fdf20558aff RSP: 002b:00007ffd318a9e30 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00000000000200c0 RCX: 00007fdf20558aff RDX: 00007fdf1feb2010 RSI: 00000000c0c0583b RDI: 0000000000000003 RBP: 00005625c0634be0 R08: 00005625c0634c40 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fdf1feb2010 R13: 00005625be70d994 R14: 0000000000000800 R15: 0000000000000000 For GETFSMAP calls, the caller selects a physical block device by writing its block number into fsmap_head.fmh_keys[01].fmr_device. To query mappings for a subrange of the device, the starting byte of the range is written to fsmap_head.fmh_keys[0].fmr_physical and the last byte of the range goes in fsmap_head.fmh_keys[1].fmr_physical. IOWs, to query what mappings overlap with bytes 3-14 of /dev/sda, you'd set the inputs as follows: fmh_keys[0] = { .fmr_device = major(8, 0), .fmr_physical = 3}, fmh_keys[1] = { .fmr_device = major(8, 0), .fmr_physical = 14}, Which would return you whatever is mapped in the 12 bytes starting at physical offset 3. The crash is due to insufficient range validation of keys[1] in ext4_getfsmap_datadev. On 1k-block filesystems, block 0 is not part of the filesystem, which means that s_first_data_block is nonzero. ext4_get_group_no_and_offset subtracts this quantity from the blocknr argument before cracking it into a group number and a block number within a group. IOWs, block group 0 spans blocks 1-8192 (1-based) instead of 0-8191 (0-based) like what happens with larger blocksizes. The net result of this encoding is that blocknr < s_first_data_block is not a valid input to this function. The end_fsb variable is set from the keys that are copied from userspace, which means that in the above example, its value is zero. That leads to an underflow here: blocknr = blocknr - le32_to_cpu(es->s_first_data_block); The division then operates on -1: offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)) >> EXT4_SB(sb)->s_cluster_bits; Leaving an impossibly large group number (2^32-1) in blocknr. ext4_getfsmap_check_keys checked that keys[0].fmr_physical and keys[1].fmr_physical are in increasing order, but ext4_getfsmap_datadev adjusts keys[0].fmr_physical to be at least s_first_data_block. This implies that we have to check it again after the adjustment, which is the piece that I forgot. Reported-by: syzbot+6be2b977c89f79b6b153@syzkaller.appspotmail.com Fixes: 4a4956249dac ("ext4: fix off-by-one fsmap error on 1k block filesystems") Link: https://syzkaller.appspot.com/bug?id=79d5768e9bfe362911ac1a5057a36fc6b5c30002 Cc: stable@vger.kernel.org Signed-off-by: Darrick J. Wong Link: https://lore.kernel.org/r/Y+58NPTH7VNGgzdd@magnolia Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fsmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c index 4493ef0c715e..cdf9bfe10137 100644 --- a/fs/ext4/fsmap.c +++ b/fs/ext4/fsmap.c @@ -486,6 +486,8 @@ static int ext4_getfsmap_datadev(struct super_block *sb, keys[0].fmr_physical = bofs; if (keys[1].fmr_physical >= eofs) keys[1].fmr_physical = eofs - 1; + if (keys[1].fmr_physical < keys[0].fmr_physical) + return 0; start_fsb = keys[0].fmr_physical; end_fsb = keys[1].fmr_physical; From d72a6c31393da918c8004233f53b601efd732be5 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Tue, 7 Mar 2023 09:52:52 +0800 Subject: [PATCH 0656/1017] ext4: move where set the MAY_INLINE_DATA flag is set commit 1dcdce5919115a471bf4921a57f20050c545a236 upstream. The only caller of ext4_find_inline_data_nolock() that needs setting of EXT4_STATE_MAY_INLINE_DATA flag is ext4_iget_extra_inode(). In ext4_write_inline_data_end() we just need to update inode->i_inline_off. Since we are going to add one more caller that does not need to set EXT4_STATE_MAY_INLINE_DATA, just move setting of EXT4_STATE_MAY_INLINE_DATA out to ext4_iget_extra_inode(). Signed-off-by: Ye Bin Cc: stable@kernel.org Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230307015253.2232062-2-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inline.c | 1 - fs/ext4/inode.c | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 77377befbb1c..61cb50e8fcb7 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -157,7 +157,6 @@ int ext4_find_inline_data_nolock(struct inode *inode) (void *)ext4_raw_inode(&is.iloc)); EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE + le32_to_cpu(is.s.here->e_value_size); - ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); } out: brelse(is.iloc.bh); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 355343cf4609..1a654a1f3f46 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4639,8 +4639,13 @@ static inline int ext4_iget_extra_inode(struct inode *inode, if (EXT4_INODE_HAS_XATTR_SPACE(inode) && *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { + int err; + ext4_set_inode_state(inode, EXT4_STATE_XATTR); - return ext4_find_inline_data_nolock(inode); + err = ext4_find_inline_data_nolock(inode); + if (!err && ext4_has_inline_data(inode)) + ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); + return err; } else EXT4_I(inode)->i_inline_off = 0; return 0; From a9bd94f67b27739bbe8583c52256502bd4cc7e83 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Tue, 7 Mar 2023 09:52:53 +0800 Subject: [PATCH 0657/1017] ext4: fix WARNING in ext4_update_inline_data commit 2b96b4a5d9443ca4cad58b0040be455803c05a42 upstream. Syzbot found the following issue: EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 without journal. Quota mode: none. fscrypt: AES-256-CTS-CBC using implementation "cts-cbc-aes-aesni" fscrypt: AES-256-XTS using implementation "xts-aes-aesni" ------------[ cut here ]------------ WARNING: CPU: 0 PID: 5071 at mm/page_alloc.c:5525 __alloc_pages+0x30a/0x560 mm/page_alloc.c:5525 Modules linked in: CPU: 1 PID: 5071 Comm: syz-executor263 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:__alloc_pages+0x30a/0x560 mm/page_alloc.c:5525 RSP: 0018:ffffc90003c2f1c0 EFLAGS: 00010246 RAX: ffffc90003c2f220 RBX: 0000000000000014 RCX: 0000000000000000 RDX: 0000000000000028 RSI: 0000000000000000 RDI: ffffc90003c2f248 RBP: ffffc90003c2f2d8 R08: dffffc0000000000 R09: ffffc90003c2f220 R10: fffff52000785e49 R11: 1ffff92000785e44 R12: 0000000000040d40 R13: 1ffff92000785e40 R14: dffffc0000000000 R15: 1ffff92000785e3c FS: 0000555556c0d300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f95d5e04138 CR3: 00000000793aa000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: __alloc_pages_node include/linux/gfp.h:237 [inline] alloc_pages_node include/linux/gfp.h:260 [inline] __kmalloc_large_node+0x95/0x1e0 mm/slab_common.c:1113 __do_kmalloc_node mm/slab_common.c:956 [inline] __kmalloc+0xfe/0x190 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] kzalloc include/linux/slab.h:720 [inline] ext4_update_inline_data+0x236/0x6b0 fs/ext4/inline.c:346 ext4_update_inline_dir fs/ext4/inline.c:1115 [inline] ext4_try_add_inline_entry+0x328/0x990 fs/ext4/inline.c:1307 ext4_add_entry+0x5a4/0xeb0 fs/ext4/namei.c:2385 ext4_add_nondir+0x96/0x260 fs/ext4/namei.c:2772 ext4_create+0x36c/0x560 fs/ext4/namei.c:2817 lookup_open fs/namei.c:3413 [inline] open_last_lookups fs/namei.c:3481 [inline] path_openat+0x12ac/0x2dd0 fs/namei.c:3711 do_filp_open+0x264/0x4f0 fs/namei.c:3741 do_sys_openat2+0x124/0x4e0 fs/open.c:1310 do_sys_open fs/open.c:1326 [inline] __do_sys_openat fs/open.c:1342 [inline] __se_sys_openat fs/open.c:1337 [inline] __x64_sys_openat+0x243/0x290 fs/open.c:1337 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Above issue happens as follows: ext4_iget ext4_find_inline_data_nolock ->i_inline_off=164 i_inline_size=60 ext4_try_add_inline_entry __ext4_mark_inode_dirty ext4_expand_extra_isize_ea ->i_extra_isize=32 s_want_extra_isize=44 ext4_xattr_shift_entries ->after shift i_inline_off is incorrect, actually is change to 176 ext4_try_add_inline_entry ext4_update_inline_dir get_max_inline_xattr_value_size if (EXT4_I(inode)->i_inline_off) entry = (struct ext4_xattr_entry *)((void *)raw_inode + EXT4_I(inode)->i_inline_off); free += EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)); ->As entry is incorrect, then 'free' may be negative ext4_update_inline_data value = kzalloc(len, GFP_NOFS); -> len is unsigned int, maybe very large, then trigger warning when 'kzalloc()' To resolve the above issue we need to update 'i_inline_off' after 'ext4_xattr_shift_entries()'. We do not need to set EXT4_STATE_MAY_INLINE_DATA flag here, since ext4_mark_inode_dirty() already sets this flag if needed. Setting EXT4_STATE_MAY_INLINE_DATA when it is needed may trigger a BUG_ON in ext4_writepages(). Reported-by: syzbot+d30838395804afc2fa6f@syzkaller.appspotmail.com Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230307015253.2232062-3-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/xattr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b80ad5a7b05c..60e122761352 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2804,6 +2804,9 @@ shift: (void *)header, total_ino); EXT4_I(inode)->i_extra_isize = new_extra_isize; + if (ext4_has_inline_data(inode)) + error = ext4_find_inline_data_nolock(inode); + cleanup: if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) { ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.", From 3f00c476da8fe7c4c34ea16abb55d74127120413 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Wed, 8 Mar 2023 11:26:43 +0800 Subject: [PATCH 0658/1017] ext4: zero i_disksize when initializing the bootloader inode commit f5361da1e60d54ec81346aee8e3d8baf1be0b762 upstream. If the boot loader inode has never been used before, the EXT4_IOC_SWAP_BOOT inode will initialize it, including setting the i_size to 0. However, if the "never before used" boot loader has a non-zero i_size, then i_disksize will be non-zero, and the inconsistency between i_size and i_disksize can trigger a kernel warning: WARNING: CPU: 0 PID: 2580 at fs/ext4/file.c:319 CPU: 0 PID: 2580 Comm: bb Not tainted 6.3.0-rc1-00004-g703695902cfa RIP: 0010:ext4_file_write_iter+0xbc7/0xd10 Call Trace: vfs_write+0x3b1/0x5c0 ksys_write+0x77/0x160 __x64_sys_write+0x22/0x30 do_syscall_64+0x39/0x80 Reproducer: 1. create corrupted image and mount it: mke2fs -t ext4 /tmp/foo.img 200 debugfs -wR "sif <5> size 25700" /tmp/foo.img mount -t ext4 /tmp/foo.img /mnt cd /mnt echo 123 > file 2. Run the reproducer program: posix_memalign(&buf, 1024, 1024) fd = open("file", O_RDWR | O_DIRECT); ioctl(fd, EXT4_IOC_SWAP_BOOT); write(fd, buf, 1024); Fix this by setting i_disksize as well as i_size to zero when initiaizing the boot loader inode. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217159 Cc: stable@kernel.org Signed-off-by: Zhihao Cheng Link: https://lore.kernel.org/r/20230308032643.641113-1-chengzhihao1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 240d792db9f7..53bdc67a815f 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -180,6 +180,7 @@ static long swap_inode_boot_loader(struct super_block *sb, ei_bl->i_flags = 0; inode_set_iversion(inode_bl, 1); i_size_write(inode_bl, 0); + EXT4_I(inode_bl)->i_disksize = inode_bl->i_size; inode_bl->i_mode = S_IFREG; if (ext4_has_feature_extents(sb)) { ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS); From 7786bfd8f7ab94f5c1ceb3e721aeccb76e24f414 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Tue, 7 Mar 2023 00:26:50 +0300 Subject: [PATCH 0659/1017] nfc: change order inside nfc_se_io error path commit 7d834b4d1ab66c48e8c0810fdeadaabb80fa2c81 upstream. cb_context should be freed on the error path in nfc_se_io as stated by commit 25ff6f8a5a3b ("nfc: fix memory leak of se_io context in nfc_genl_se_io"). Make the error path in nfc_se_io unwind everything in reverse order, i.e. free the cb_context after unlocking the device. Suggested-by: Krzysztof Kozlowski Signed-off-by: Fedor Pchelkin Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230306212650.230322-1-pchelkin@ispras.ru Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/nfc/netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 3f4785be066a..e0e116865511 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -1446,8 +1446,8 @@ static int nfc_se_io(struct nfc_dev *dev, u32 se_idx, return rc; error: - kfree(cb_context); device_unlock(&dev->dev); + kfree(cb_context); return rc; } From fe80a53eabdb256a0610c7681ca8823435c963ac Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 23 Jan 2023 14:29:15 +0100 Subject: [PATCH 0660/1017] udf: Fix off-by-one error when discarding preallocation [ Upstream commit f54aa97fb7e5329a373f9df4e5e213ced4fc8759 ] The condition determining whether the preallocation can be used had an off-by-one error so we didn't discard preallocation when new allocation was just following it. This can then confuse code in inode_getblk(). CC: stable@vger.kernel.org Fixes: 16d055656814 ("udf: Discard preallocation before extending file with a hole") Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 81876284a83c..d114774ecdea 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -442,7 +442,7 @@ static int udf_get_block(struct inode *inode, sector_t block, * Block beyond EOF and prealloc extents? Just discard preallocation * as it is not useful and complicates things. */ - if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents) + if (((loff_t)block) << inode->i_blkbits >= iinfo->i_lenExtents) udf_discard_prealloc(inode); udf_clear_extent_cache(inode); phys = inode_getblk(inode, block, &err, &new); From 6414597815d57c15cc083df1ad0d043b724b7418 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 22 Mar 2021 04:21:30 +0100 Subject: [PATCH 0661/1017] irq: Fix typos in comments [ Upstream commit a359f757965aafd0f58570de95dc6bc06cf12a9c ] Fix ~36 single-word typos in the IRQ, irqchip and irqdomain code comments. Signed-off-by: Ingo Molnar Cc: Thomas Gleixner Cc: Marc Zyngier Cc: Borislav Petkov Cc: Peter Zijlstra Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar Stable-dep-of: 6e6f75c9c98d ("irqdomain: Look for existing mapping only once") Signed-off-by: Sasha Levin --- drivers/irqchip/irq-aspeed-vic.c | 4 ++-- drivers/irqchip/irq-bcm7120-l2.c | 2 +- drivers/irqchip/irq-csky-apb-intc.c | 2 +- drivers/irqchip/irq-gic-v2m.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 10 +++++----- drivers/irqchip/irq-gic-v3.c | 2 +- drivers/irqchip/irq-loongson-pch-pic.c | 2 +- drivers/irqchip/irq-meson-gpio.c | 2 +- drivers/irqchip/irq-mtk-cirq.c | 2 +- drivers/irqchip/irq-mxs.c | 4 ++-- drivers/irqchip/irq-sun4i.c | 2 +- drivers/irqchip/irq-ti-sci-inta.c | 2 +- drivers/irqchip/irq-vic.c | 4 ++-- drivers/irqchip/irq-xilinx-intc.c | 2 +- include/linux/irq.h | 4 ++-- include/linux/irqdesc.h | 2 +- kernel/irq/chip.c | 2 +- kernel/irq/dummychip.c | 2 +- kernel/irq/irqdesc.c | 2 +- kernel/irq/irqdomain.c | 8 ++++---- kernel/irq/manage.c | 6 +++--- kernel/irq/msi.c | 2 +- kernel/irq/timings.c | 2 +- 23 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/irqchip/irq-aspeed-vic.c b/drivers/irqchip/irq-aspeed-vic.c index 6567ed782f82..58717cd44f99 100644 --- a/drivers/irqchip/irq-aspeed-vic.c +++ b/drivers/irqchip/irq-aspeed-vic.c @@ -71,7 +71,7 @@ static void vic_init_hw(struct aspeed_vic *vic) writel(0, vic->base + AVIC_INT_SELECT); writel(0, vic->base + AVIC_INT_SELECT + 4); - /* Some interrupts have a programable high/low level trigger + /* Some interrupts have a programmable high/low level trigger * (4 GPIO direct inputs), for now we assume this was configured * by firmware. We read which ones are edge now. */ @@ -203,7 +203,7 @@ static int __init avic_of_init(struct device_node *node, } vic->base = regs; - /* Initialize soures, all masked */ + /* Initialize sources, all masked */ vic_init_hw(vic); /* Ready to receive interrupts */ diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 7d776c905b7d..1c2c5bd5a9fc 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -310,7 +310,7 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, if (data->can_wake) { /* This IRQ chip can wake the system, set all - * relevant child interupts in wake_enabled mask + * relevant child interrupts in wake_enabled mask */ gc->wake_enabled = 0xffffffff; gc->wake_enabled &= ~gc->unused; diff --git a/drivers/irqchip/irq-csky-apb-intc.c b/drivers/irqchip/irq-csky-apb-intc.c index 5a2ec43b7ddd..ab91afa86755 100644 --- a/drivers/irqchip/irq-csky-apb-intc.c +++ b/drivers/irqchip/irq-csky-apb-intc.c @@ -176,7 +176,7 @@ gx_intc_init(struct device_node *node, struct device_node *parent) writel(0x0, reg_base + GX_INTC_NEN63_32); /* - * Initial mask reg with all unmasked, because we only use enalbe reg + * Initial mask reg with all unmasked, because we only use enable reg */ writel(0x0, reg_base + GX_INTC_NMASK31_00); writel(0x0, reg_base + GX_INTC_NMASK63_32); diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index fbec07d634ad..4116b48e60af 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -371,7 +371,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode, * the MSI data is the absolute value within the range from * spi_start to (spi_start + num_spis). * - * Broadom NS2 GICv2m implementation has an erratum where the MSI data + * Broadcom NS2 GICv2m implementation has an erratum where the MSI data * is 'spi_number - 32' * * Reading that register fails on the Graviton implementation diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index d8cb5bcd6b10..5ec091c64d47 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1492,7 +1492,7 @@ static void its_vlpi_set_doorbell(struct irq_data *d, bool enable) * * Ideally, we'd issue a VMAPTI to set the doorbell to its LPI * value or to 1023, depending on the enable bit. But that - * would be issueing a mapping for an /existing/ DevID+EventID + * would be issuing a mapping for an /existing/ DevID+EventID * pair, which is UNPREDICTABLE. Instead, let's issue a VMOVI * to the /same/ vPE, using this opportunity to adjust the * doorbell. Mouahahahaha. We loves it, Precious. @@ -3122,7 +3122,7 @@ static void its_cpu_init_lpis(void) /* * It's possible for CPU to receive VLPIs before it is - * sheduled as a vPE, especially for the first CPU, and the + * scheduled as a vPE, especially for the first CPU, and the * VLPI with INTID larger than 2^(IDbits+1) will be considered * as out of range and dropped by GIC. * So we initialize IDbits to known value to avoid VLPI drop. @@ -3613,7 +3613,7 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq, /* * If all interrupts have been freed, start mopping the - * floor. This is conditionned on the device not being shared. + * floor. This is conditioned on the device not being shared. */ if (!its_dev->shared && bitmap_empty(its_dev->event_map.lpi_map, @@ -4187,7 +4187,7 @@ static int its_sgi_set_affinity(struct irq_data *d, { /* * There is no notion of affinity for virtual SGIs, at least - * not on the host (since they can only be targetting a vPE). + * not on the host (since they can only be targeting a vPE). * Tell the kernel we've done whatever it asked for. */ irq_data_update_effective_affinity(d, mask_val); @@ -4232,7 +4232,7 @@ static int its_sgi_get_irqchip_state(struct irq_data *d, /* * Locking galore! We can race against two different events: * - * - Concurent vPE affinity change: we must make sure it cannot + * - Concurrent vPE affinity change: we must make sure it cannot * happen, or we'll talk to the wrong redistributor. This is * identical to what happens with vLPIs. * diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 4c8f18f0cecf..2805969e4f15 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1456,7 +1456,7 @@ static int gic_irq_domain_translate(struct irq_domain *d, /* * Make it clear that broken DTs are... broken. - * Partitionned PPIs are an unfortunate exception. + * Partitioned PPIs are an unfortunate exception. */ WARN_ON(*type == IRQ_TYPE_NONE && fwspec->param[0] != GIC_IRQ_TYPE_PARTITION); diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c index 90e1ad6e3612..a4eb8a2181c7 100644 --- a/drivers/irqchip/irq-loongson-pch-pic.c +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -180,7 +180,7 @@ static void pch_pic_reset(struct pch_pic *priv) int i; for (i = 0; i < PIC_COUNT; i++) { - /* Write vectore ID */ + /* Write vectored ID */ writeb(priv->ht_vec_base + i, priv->base + PCH_INT_HTVEC(i)); /* Hardcode route to HT0 Lo */ writeb(1, priv->base + PCH_INT_ROUTE(i)); diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c index bc7aebcc96e9..e50676ce2ec8 100644 --- a/drivers/irqchip/irq-meson-gpio.c +++ b/drivers/irqchip/irq-meson-gpio.c @@ -227,7 +227,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, /* * Get the hwirq number assigned to this channel through - * a pointer the channel_irq table. The added benifit of this + * a pointer the channel_irq table. The added benefit of this * method is that we can also retrieve the channel index with * it, using the table base. */ diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c index 69ba8ce3c178..9bca0918078e 100644 --- a/drivers/irqchip/irq-mtk-cirq.c +++ b/drivers/irqchip/irq-mtk-cirq.c @@ -217,7 +217,7 @@ static void mtk_cirq_resume(void) { u32 value; - /* flush recored interrupts, will send signals to parent controller */ + /* flush recorded interrupts, will send signals to parent controller */ value = readl_relaxed(cirq_data->base + CIRQ_CONTROL); writel_relaxed(value | CIRQ_FLUSH, cirq_data->base + CIRQ_CONTROL); diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index a671938fd97f..d1f5740cd575 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -58,7 +58,7 @@ struct icoll_priv { static struct icoll_priv icoll_priv; static struct irq_domain *icoll_domain; -/* calculate bit offset depending on number of intterupt per register */ +/* calculate bit offset depending on number of interrupt per register */ static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit) { /* @@ -68,7 +68,7 @@ static u32 icoll_intr_bitshift(struct irq_data *d, u32 bit) return bit << ((d->hwirq & 3) << 3); } -/* calculate mem offset depending on number of intterupt per register */ +/* calculate mem offset depending on number of interrupt per register */ static void __iomem *icoll_intr_reg(struct irq_data *d) { /* offset = hwirq / intr_per_reg * 0x10 */ diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index fb78d6623556..9ea94456b178 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c @@ -189,7 +189,7 @@ static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) * 3) spurious irq * So if we immediately get a reading of 0, check the irq-pending reg * to differentiate between 2 and 3. We only do this once to avoid - * the extra check in the common case of 1 hapening after having + * the extra check in the common case of 1 happening after having * read the vector-reg once. */ hwirq = readl(irq_ic_data->irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c index 532d0ae172d9..ca1f593f4d13 100644 --- a/drivers/irqchip/irq-ti-sci-inta.c +++ b/drivers/irqchip/irq-ti-sci-inta.c @@ -78,7 +78,7 @@ struct ti_sci_inta_vint_desc { * struct ti_sci_inta_irq_domain - Structure representing a TISCI based * Interrupt Aggregator IRQ domain. * @sci: Pointer to TISCI handle - * @vint: TISCI resource pointer representing IA inerrupts. + * @vint: TISCI resource pointer representing IA interrupts. * @global_event: TISCI resource pointer representing global events. * @vint_list: List of the vints active in the system * @vint_mutex: Mutex to protect vint_list diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index e46036374227..62f3d29f9042 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -163,7 +163,7 @@ static struct syscore_ops vic_syscore_ops = { }; /** - * vic_pm_init - initicall to register VIC pm + * vic_pm_init - initcall to register VIC pm * * This is called via late_initcall() to register * the resources for the VICs due to the early @@ -397,7 +397,7 @@ static void __init vic_clear_interrupts(void __iomem *base) /* * The PL190 cell from ARM has been modified by ST to handle 64 interrupts. * The original cell has 32 interrupts, while the modified one has 64, - * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case + * replicating two blocks 0x00..0x1f in 0x20..0x3f. In that case * the probe function is called twice, with base set to offset 000 * and 020 within the page. We call this "second block". */ diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c index 1d3d273309bd..8cd1bfc73057 100644 --- a/drivers/irqchip/irq-xilinx-intc.c +++ b/drivers/irqchip/irq-xilinx-intc.c @@ -210,7 +210,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc, /* * Disable all external interrupts until they are - * explicity requested. + * explicitly requested. */ xintc_write(irqc, IER, 0); diff --git a/include/linux/irq.h b/include/linux/irq.h index 607bee9271bd..b89a8ac83d1b 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -116,7 +116,7 @@ enum { * IRQ_SET_MASK_NOCPY - OK, chip did update irq_common_data.affinity * IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to * support stacked irqchips, which indicates skipping - * all descendent irqchips. + * all descendant irqchips. */ enum { IRQ_SET_MASK_OK = 0, @@ -302,7 +302,7 @@ static inline bool irqd_is_level_type(struct irq_data *d) /* * Must only be called of irqchip.irq_set_affinity() or low level - * hieararchy domain allocation functions. + * hierarchy domain allocation functions. */ static inline void irqd_set_single_target(struct irq_data *d) { diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 5745491303e0..fdb22e0f9a91 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -32,7 +32,7 @@ struct pt_regs; * @last_unhandled: aging timer for unhandled count * @irqs_unhandled: stats field for spurious unhandled interrupts * @threads_handled: stats field for deferred spurious detection of threaded handlers - * @threads_handled_last: comparator field for deferred spurious detection of theraded handlers + * @threads_handled_last: comparator field for deferred spurious detection of threaded handlers * @lock: locking for SMP * @affinity_hint: hint to user space for preferred irq affinity * @affinity_notify: context for notification of affinity changes diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 621d8dd157bc..e7d284261d45 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -811,7 +811,7 @@ void handle_edge_irq(struct irq_desc *desc) /* * When another irq arrived while we were handling * one, we could have masked the irq. - * Renable it, if it was not disabled in meantime. + * Reenable it, if it was not disabled in meantime. */ if (unlikely(desc->istate & IRQS_PENDING)) { if (!irqd_irq_disabled(&desc->irq_data) && diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c index 0b0cdf206dc4..7fe6cffe7d0d 100644 --- a/kernel/irq/dummychip.c +++ b/kernel/irq/dummychip.c @@ -13,7 +13,7 @@ /* * What should we do if we get a hw irq event on an illegal vector? - * Each architecture has to answer this themself. + * Each architecture has to answer this themselves. */ static void ack_bad(struct irq_data *data) { diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 9b0914a063f9..6c009a033c73 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -31,7 +31,7 @@ static int __init irq_affinity_setup(char *str) cpulist_parse(str, irq_default_affinity); /* * Set at least the boot cpu. We don't want to end up with - * bugreports caused by random comandline masks + * bugreports caused by random commandline masks */ cpumask_set_cpu(smp_processor_id(), irq_default_affinity); return 1; diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 1720998933f8..fe07888a7d96 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -53,7 +53,7 @@ EXPORT_SYMBOL_GPL(irqchip_fwnode_ops); * @name: Optional user provided domain name * @pa: Optional user-provided physical address * - * Allocate a struct irqchip_fwid, and return a poiner to the embedded + * Allocate a struct irqchip_fwid, and return a pointer to the embedded * fwnode_handle (or NULL on failure). * * Note: The types IRQCHIP_FWNODE_NAMED and IRQCHIP_FWNODE_NAMED_ID are @@ -657,7 +657,7 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); - /* Look for default domain if nececssary */ + /* Look for default domain if necessary */ if (domain == NULL) domain = irq_default_domain; if (domain == NULL) { @@ -893,7 +893,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, { struct irq_data *data; - /* Look for default domain if nececssary */ + /* Look for default domain if necessary */ if (domain == NULL) domain = irq_default_domain; if (domain == NULL) @@ -1423,7 +1423,7 @@ int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, * The whole process to setup an IRQ has been split into two steps. * The first step, __irq_domain_alloc_irqs(), is to allocate IRQ * descriptor and required hardware resources. The second step, - * irq_domain_activate_irq(), is to program hardwares with preallocated + * irq_domain_activate_irq(), is to program the hardware with preallocated * resources. In this way, it's easier to rollback when failing to * allocate resources. */ diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 437b073dc487..0159925054fa 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -341,7 +341,7 @@ static bool irq_set_affinity_deactivated(struct irq_data *data, * If the interrupt is not yet activated, just store the affinity * mask and do not call the chip driver at all. On activation the * driver has to make sure anyway that the interrupt is in a - * useable state so startup works. + * usable state so startup works. */ if (!IS_ENABLED(CONFIG_IRQ_DOMAIN_HIERARCHY) || irqd_is_activated(data) || !irqd_affinity_on_activate(data)) @@ -999,7 +999,7 @@ again: * to IRQS_INPROGRESS and the irq line is masked forever. * * This also serializes the state of shared oneshot handlers - * versus "desc->threads_onehsot |= action->thread_mask;" in + * versus "desc->threads_oneshot |= action->thread_mask;" in * irq_wake_thread(). See the comment there which explains the * serialization. */ @@ -1877,7 +1877,7 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id) /* Last action releases resources */ if (!desc->action) { /* - * Reaquire bus lock as irq_release_resources() might + * Reacquire bus lock as irq_release_resources() might * require it to deallocate resources over the slow bus. */ chip_bus_lock(desc); diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index b47d95b68ac1..4457f3e966d0 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -5,7 +5,7 @@ * * This file is licensed under GPLv2. * - * This file contains common code to support Message Signalled Interrupt for + * This file contains common code to support Message Signaled Interrupts for * PCI compatible and non PCI compatible devices. */ #include diff --git a/kernel/irq/timings.c b/kernel/irq/timings.c index 1f981162648a..00d45b6bd8f8 100644 --- a/kernel/irq/timings.c +++ b/kernel/irq/timings.c @@ -490,7 +490,7 @@ static inline void irq_timings_store(int irq, struct irqt_stat *irqs, u64 ts) /* * The interrupt triggered more than one second apart, that - * ends the sequence as predictible for our purpose. In this + * ends the sequence as predictable for our purpose. In this * case, assume we have the beginning of a sequence and the * timestamp is the first value. As it is impossible to * predict anything at this point, return. From ff762cdbf0c8c9bf0b97684f39af13b3332e77e8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Feb 2023 11:42:46 +0100 Subject: [PATCH 0662/1017] irqdomain: Look for existing mapping only once [ Upstream commit 6e6f75c9c98d2d246d90411ff2b6f0cd271f4cba ] Avoid looking for an existing mapping twice when creating a new mapping using irq_create_fwspec_mapping() by factoring out the actual allocation which is shared with irq_create_mapping_affinity(). The new helper function will also be used to fix a shared-interrupt mapping race, hence the Fixes tag. Fixes: b62b2cf5759b ("irqdomain: Fix handling of type settings for existing mappings") Cc: stable@vger.kernel.org # 4.8 Tested-by: Hsin-Yi Wang Tested-by: Mark-PK Tsai Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-5-johan+linaro@kernel.org Signed-off-by: Sasha Levin --- kernel/irq/irqdomain.c | 74 +++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index fe07888a7d96..d18c25a41673 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -637,44 +637,15 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) } EXPORT_SYMBOL_GPL(irq_create_direct_mapping); -/** - * irq_create_mapping_affinity() - Map a hardware interrupt into linux irq space - * @domain: domain owning this hardware interrupt or NULL for default domain - * @hwirq: hardware irq number in that domain space - * @affinity: irq affinity - * - * Only one mapping per hardware interrupt is permitted. Returns a linux - * irq number. - * If the sense/trigger is to be specified, set_irq_type() should be called - * on the number returned from that call. - */ -unsigned int irq_create_mapping_affinity(struct irq_domain *domain, - irq_hw_number_t hwirq, - const struct irq_affinity_desc *affinity) +static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain, + irq_hw_number_t hwirq, + const struct irq_affinity_desc *affinity) { - struct device_node *of_node; + struct device_node *of_node = irq_domain_get_of_node(domain); int virq; pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); - /* Look for default domain if necessary */ - if (domain == NULL) - domain = irq_default_domain; - if (domain == NULL) { - WARN(1, "%s(, %lx) called with NULL domain\n", __func__, hwirq); - return 0; - } - pr_debug("-> using domain @%p\n", domain); - - of_node = irq_domain_get_of_node(domain); - - /* Check if mapping already exists */ - virq = irq_find_mapping(domain, hwirq); - if (virq) { - pr_debug("-> existing mapping on virq %d\n", virq); - return virq; - } - /* Allocate a virtual interrupt number */ virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node), affinity); @@ -693,6 +664,41 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, return virq; } + +/** + * irq_create_mapping_affinity() - Map a hardware interrupt into linux irq space + * @domain: domain owning this hardware interrupt or NULL for default domain + * @hwirq: hardware irq number in that domain space + * @affinity: irq affinity + * + * Only one mapping per hardware interrupt is permitted. Returns a linux + * irq number. + * If the sense/trigger is to be specified, set_irq_type() should be called + * on the number returned from that call. + */ +unsigned int irq_create_mapping_affinity(struct irq_domain *domain, + irq_hw_number_t hwirq, + const struct irq_affinity_desc *affinity) +{ + int virq; + + /* Look for default domain if necessary */ + if (domain == NULL) + domain = irq_default_domain; + if (domain == NULL) { + WARN(1, "%s(, %lx) called with NULL domain\n", __func__, hwirq); + return 0; + } + + /* Check if mapping already exists */ + virq = irq_find_mapping(domain, hwirq); + if (virq) { + pr_debug("existing mapping on virq %d\n", virq); + return virq; + } + + return __irq_create_mapping_affinity(domain, hwirq, affinity); +} EXPORT_SYMBOL_GPL(irq_create_mapping_affinity); /** @@ -831,7 +837,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) return 0; } else { /* Create mapping */ - virq = irq_create_mapping(domain, hwirq); + virq = __irq_create_mapping_affinity(domain, hwirq, NULL); if (!virq) return virq; } From 8617599c646f8c4623fe8c998fc4f9303c2967d4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Feb 2023 11:42:47 +0100 Subject: [PATCH 0663/1017] irqdomain: Refactor __irq_domain_alloc_irqs() [ Upstream commit d55f7f4c58c07beb5050a834bf57ae2ede599c7e ] Refactor __irq_domain_alloc_irqs() so that it can be called internally while holding the irq_domain_mutex. This will be used to fix a shared-interrupt mapping race, hence the Fixes tag. Fixes: b62b2cf5759b ("irqdomain: Fix handling of type settings for existing mappings") Cc: stable@vger.kernel.org # 4.8 Tested-by: Hsin-Yi Wang Tested-by: Mark-PK Tsai Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-6-johan+linaro@kernel.org Signed-off-by: Sasha Levin --- kernel/irq/irqdomain.c | 90 +++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index d18c25a41673..a1e1433a0775 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1411,6 +1411,52 @@ int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain, return domain->ops->alloc(domain, irq_base, nr_irqs, arg); } +static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, + unsigned int nr_irqs, int node, void *arg, + bool realloc, const struct irq_affinity_desc *affinity) +{ + int i, ret, virq; + + if (realloc && irq_base >= 0) { + virq = irq_base; + } else { + virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node, + affinity); + if (virq < 0) { + pr_debug("cannot allocate IRQ(base %d, count %d)\n", + irq_base, nr_irqs); + return virq; + } + } + + if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) { + pr_debug("cannot allocate memory for IRQ%d\n", virq); + ret = -ENOMEM; + goto out_free_desc; + } + + ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg); + if (ret < 0) + goto out_free_irq_data; + + for (i = 0; i < nr_irqs; i++) { + ret = irq_domain_trim_hierarchy(virq + i); + if (ret) + goto out_free_irq_data; + } + + for (i = 0; i < nr_irqs; i++) + irq_domain_insert_irq(virq + i); + + return virq; + +out_free_irq_data: + irq_domain_free_irq_data(virq, nr_irqs); +out_free_desc: + irq_free_descs(virq, nr_irqs); + return ret; +} + /** * __irq_domain_alloc_irqs - Allocate IRQs from domain * @domain: domain to allocate from @@ -1437,7 +1483,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, unsigned int nr_irqs, int node, void *arg, bool realloc, const struct irq_affinity_desc *affinity) { - int i, ret, virq; + int ret; if (domain == NULL) { domain = irq_default_domain; @@ -1445,49 +1491,11 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, return -EINVAL; } - if (realloc && irq_base >= 0) { - virq = irq_base; - } else { - virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node, - affinity); - if (virq < 0) { - pr_debug("cannot allocate IRQ(base %d, count %d)\n", - irq_base, nr_irqs); - return virq; - } - } - - if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) { - pr_debug("cannot allocate memory for IRQ%d\n", virq); - ret = -ENOMEM; - goto out_free_desc; - } - mutex_lock(&irq_domain_mutex); - ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg); - if (ret < 0) { - mutex_unlock(&irq_domain_mutex); - goto out_free_irq_data; - } - - for (i = 0; i < nr_irqs; i++) { - ret = irq_domain_trim_hierarchy(virq + i); - if (ret) { - mutex_unlock(&irq_domain_mutex); - goto out_free_irq_data; - } - } - - for (i = 0; i < nr_irqs; i++) - irq_domain_insert_irq(virq + i); + ret = irq_domain_alloc_irqs_locked(domain, irq_base, nr_irqs, node, arg, + realloc, affinity); mutex_unlock(&irq_domain_mutex); - return virq; - -out_free_irq_data: - irq_domain_free_irq_data(virq, nr_irqs); -out_free_desc: - irq_free_descs(virq, nr_irqs); return ret; } From 4ab311d51cd99ddc48e828e70fbdf9c076416cf2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Feb 2023 11:42:48 +0100 Subject: [PATCH 0664/1017] irqdomain: Fix mapping-creation race [ Upstream commit 601363cc08da25747feb87c55573dd54de91d66a ] Parallel probing of devices that share interrupts (e.g. when a driver uses asynchronous probing) can currently result in two mappings for the same hardware interrupt to be created due to missing serialisation. Make sure to hold the irq_domain_mutex when creating mappings so that looking for an existing mapping before creating a new one is done atomically. Fixes: 765230b5f084 ("driver-core: add asynchronous probing support for drivers") Fixes: b62b2cf5759b ("irqdomain: Fix handling of type settings for existing mappings") Link: https://lore.kernel.org/r/YuJXMHoT4ijUxnRb@hovoldconsulting.com Cc: stable@vger.kernel.org # 4.8 Cc: Dmitry Torokhov Cc: Jon Hunter Tested-by: Hsin-Yi Wang Tested-by: Mark-PK Tsai Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-7-johan+linaro@kernel.org Signed-off-by: Sasha Levin --- kernel/irq/irqdomain.c | 64 ++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index a1e1433a0775..245e317c7290 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -25,6 +25,9 @@ static DEFINE_MUTEX(irq_domain_mutex); static struct irq_domain *irq_default_domain; +static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, + unsigned int nr_irqs, int node, void *arg, + bool realloc, const struct irq_affinity_desc *affinity); static void irq_domain_check_hierarchy(struct irq_domain *domain); struct irqchip_fwid { @@ -637,9 +640,9 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) } EXPORT_SYMBOL_GPL(irq_create_direct_mapping); -static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain, - irq_hw_number_t hwirq, - const struct irq_affinity_desc *affinity) +static unsigned int irq_create_mapping_affinity_locked(struct irq_domain *domain, + irq_hw_number_t hwirq, + const struct irq_affinity_desc *affinity) { struct device_node *of_node = irq_domain_get_of_node(domain); int virq; @@ -654,7 +657,7 @@ static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain, return 0; } - if (irq_domain_associate(domain, virq, hwirq)) { + if (irq_domain_associate_locked(domain, virq, hwirq)) { irq_free_desc(virq); return 0; } @@ -690,14 +693,20 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, return 0; } + mutex_lock(&irq_domain_mutex); + /* Check if mapping already exists */ virq = irq_find_mapping(domain, hwirq); if (virq) { pr_debug("existing mapping on virq %d\n", virq); - return virq; + goto out; } - return __irq_create_mapping_affinity(domain, hwirq, affinity); + virq = irq_create_mapping_affinity_locked(domain, hwirq, affinity); +out: + mutex_unlock(&irq_domain_mutex); + + return virq; } EXPORT_SYMBOL_GPL(irq_create_mapping_affinity); @@ -799,6 +808,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) if (WARN_ON(type & ~IRQ_TYPE_SENSE_MASK)) type &= IRQ_TYPE_SENSE_MASK; + mutex_lock(&irq_domain_mutex); + /* * If we've already configured this interrupt, * don't do it again, or hell will break loose. @@ -811,7 +822,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) * interrupt number. */ if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq)) - return virq; + goto out; /* * If the trigger type has not been set yet, then set @@ -819,35 +830,45 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) */ if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) { irq_data = irq_get_irq_data(virq); - if (!irq_data) - return 0; + if (!irq_data) { + virq = 0; + goto out; + } irqd_set_trigger_type(irq_data, type); - return virq; + goto out; } pr_warn("type mismatch, failed to map hwirq-%lu for %s!\n", hwirq, of_node_full_name(to_of_node(fwspec->fwnode))); - return 0; + virq = 0; + goto out; } if (irq_domain_is_hierarchy(domain)) { - virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, fwspec); - if (virq <= 0) - return 0; + virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE, + fwspec, false, NULL); + if (virq <= 0) { + virq = 0; + goto out; + } } else { /* Create mapping */ - virq = __irq_create_mapping_affinity(domain, hwirq, NULL); + virq = irq_create_mapping_affinity_locked(domain, hwirq, NULL); if (!virq) - return virq; + goto out; } irq_data = irq_get_irq_data(virq); - if (WARN_ON(!irq_data)) - return 0; + if (WARN_ON(!irq_data)) { + virq = 0; + goto out; + } /* Store trigger type */ irqd_set_trigger_type(irq_data, type); +out: + mutex_unlock(&irq_domain_mutex); return virq; } @@ -1856,6 +1877,13 @@ void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, irq_set_handler_data(virq, handler_data); } +static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, + unsigned int nr_irqs, int node, void *arg, + bool realloc, const struct irq_affinity_desc *affinity) +{ + return -EINVAL; +} + static void irq_domain_check_hierarchy(struct irq_domain *domain) { } From bb7597777c134a6229f74843d307866643a792ed Mon Sep 17 00:00:00 2001 From: Bixuan Cui Date: Thu, 16 Sep 2021 10:52:03 +0800 Subject: [PATCH 0665/1017] irqdomain: Change the type of 'size' in __irq_domain_add() to be consistent [ Upstream commit 20c36ce2164f1774b487d443ece99b754bc6ad43 ] The 'size' is used in struct_size(domain, revmap, size) and its input parameter type is 'size_t'(unsigned int). Changing the size to 'unsigned int' to make the type consistent. Signed-off-by: Bixuan Cui Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210916025203.44841-1-cuibixuan@huawei.com Stable-dep-of: 8932c32c3053 ("irqdomain: Fix domain registration race") Signed-off-by: Sasha Levin --- include/linux/irqdomain.h | 2 +- kernel/irq/irqdomain.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index ea5a337e0f8b..9b9743f7538c 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -256,7 +256,7 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa) } void irq_domain_free_fwnode(struct fwnode_handle *fwnode); -struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, +struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size, irq_hw_number_t hwirq_max, int direct_max, const struct irq_domain_ops *ops, void *host_data); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 245e317c7290..426242c8903d 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -130,7 +130,7 @@ EXPORT_SYMBOL_GPL(irq_domain_free_fwnode); * Allocates and initializes an irq_domain structure. * Returns pointer to IRQ domain, or NULL on failure. */ -struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, +struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size, irq_hw_number_t hwirq_max, int direct_max, const struct irq_domain_ops *ops, void *host_data) From aeab1f1a60ae19ab7bc509f2b6c9ae5a60761ca9 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 13 Feb 2023 11:42:49 +0100 Subject: [PATCH 0666/1017] irqdomain: Fix domain registration race [ Upstream commit 8932c32c3053accd50702b36e944ac2016cd103c ] Hierarchical domains created using irq_domain_create_hierarchy() are currently added to the domain list before having been fully initialised. This specifically means that a racing allocation request might fail to allocate irq data for the inner domains of a hierarchy in case the parent domain pointer has not yet been set up. Note that this is not really any issue for irqchip drivers that are registered early (e.g. via IRQCHIP_DECLARE() or IRQCHIP_ACPI_DECLARE()) but could potentially cause trouble with drivers that are registered later (e.g. modular drivers using IRQCHIP_PLATFORM_DRIVER_BEGIN(), gpiochip drivers, etc.). Fixes: afb7da83b9f4 ("irqdomain: Introduce helper function irq_domain_add_hierarchy()") Cc: stable@vger.kernel.org # 3.19 Signed-off-by: Marc Zyngier [ johan: add commit message ] Signed-off-by: Johan Hovold Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230213104302.17307-8-johan+linaro@kernel.org Signed-off-by: Sasha Levin --- kernel/irq/irqdomain.c | 62 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 426242c8903d..fd3f7c16c299 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -117,23 +117,12 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode) } EXPORT_SYMBOL_GPL(irq_domain_free_fwnode); -/** - * __irq_domain_add() - Allocate a new irq_domain data structure - * @fwnode: firmware node for the interrupt controller - * @size: Size of linear map; 0 for radix mapping only - * @hwirq_max: Maximum number of interrupts supported by controller - * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no - * direct mapping - * @ops: domain callbacks - * @host_data: Controller private data pointer - * - * Allocates and initializes an irq_domain structure. - * Returns pointer to IRQ domain, or NULL on failure. - */ -struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size, - irq_hw_number_t hwirq_max, int direct_max, - const struct irq_domain_ops *ops, - void *host_data) +static struct irq_domain *__irq_domain_create(struct fwnode_handle *fwnode, + unsigned int size, + irq_hw_number_t hwirq_max, + int direct_max, + const struct irq_domain_ops *ops, + void *host_data) { struct irqchip_fwid *fwid; struct irq_domain *domain; @@ -210,12 +199,44 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int s domain->revmap_direct_max_irq = direct_max; irq_domain_check_hierarchy(domain); + return domain; +} + +static void __irq_domain_publish(struct irq_domain *domain) +{ mutex_lock(&irq_domain_mutex); debugfs_add_domain_dir(domain); list_add(&domain->link, &irq_domain_list); mutex_unlock(&irq_domain_mutex); pr_debug("Added domain %s\n", domain->name); +} + +/** + * __irq_domain_add() - Allocate a new irq_domain data structure + * @fwnode: firmware node for the interrupt controller + * @size: Size of linear map; 0 for radix mapping only + * @hwirq_max: Maximum number of interrupts supported by controller + * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no + * direct mapping + * @ops: domain callbacks + * @host_data: Controller private data pointer + * + * Allocates and initializes an irq_domain structure. + * Returns pointer to IRQ domain, or NULL on failure. + */ +struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size, + irq_hw_number_t hwirq_max, int direct_max, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain *domain; + + domain = __irq_domain_create(fwnode, size, hwirq_max, direct_max, + ops, host_data); + if (domain) + __irq_domain_publish(domain); + return domain; } EXPORT_SYMBOL_GPL(__irq_domain_add); @@ -1110,12 +1131,15 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent, struct irq_domain *domain; if (size) - domain = irq_domain_create_linear(fwnode, size, ops, host_data); + domain = __irq_domain_create(fwnode, size, size, 0, ops, host_data); else - domain = irq_domain_create_tree(fwnode, ops, host_data); + domain = __irq_domain_create(fwnode, 0, ~0, 0, ops, host_data); + if (domain) { domain->parent = parent; domain->flags |= flags; + + __irq_domain_publish(domain); } return domain; From c424b1819120093d34852c5893c507a4bc0b5a98 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 20 Mar 2021 10:09:16 +0800 Subject: [PATCH 0667/1017] iommu/vt-d: Fix lockdep splat in intel_pasid_get_entry() [ Upstream commit 803766cbf85fb8edbf896729bbefc2d38dcf1e0a ] The pasid_lock is used to synchronize different threads from modifying a same pasid directory entry at the same time. It causes below lockdep splat. [ 83.296538] ======================================================== [ 83.296538] WARNING: possible irq lock inversion dependency detected [ 83.296539] 5.12.0-rc3+ #25 Tainted: G W [ 83.296539] -------------------------------------------------------- [ 83.296540] bash/780 just changed the state of lock: [ 83.296540] ffffffff82b29c98 (device_domain_lock){..-.}-{2:2}, at: iommu_flush_dev_iotlb.part.0+0x32/0x110 [ 83.296547] but this lock took another, SOFTIRQ-unsafe lock in the past: [ 83.296547] (pasid_lock){+.+.}-{2:2} [ 83.296548] and interrupts could create inverse lock ordering between them. [ 83.296549] other info that might help us debug this: [ 83.296549] Chain exists of: device_domain_lock --> &iommu->lock --> pasid_lock [ 83.296551] Possible interrupt unsafe locking scenario: [ 83.296551] CPU0 CPU1 [ 83.296552] ---- ---- [ 83.296552] lock(pasid_lock); [ 83.296553] local_irq_disable(); [ 83.296553] lock(device_domain_lock); [ 83.296554] lock(&iommu->lock); [ 83.296554] [ 83.296554] lock(device_domain_lock); [ 83.296555] *** DEADLOCK *** Fix it by replacing the pasid_lock with an atomic exchange operation. Reported-and-tested-by: Dave Jiang Signed-off-by: Lu Baolu Link: https://lore.kernel.org/r/20210320020916.640115-1-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel Stable-dep-of: 194b3348bdbb ("iommu/vt-d: Fix PASID directory pointer coherency") Signed-off-by: Sasha Levin --- drivers/iommu/intel/pasid.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index 86fd49ae7f61..f821153390e5 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -24,7 +24,6 @@ /* * Intel IOMMU system wide PASID name space: */ -static DEFINE_SPINLOCK(pasid_lock); u32 intel_pasid_max_id = PASID_MAX; int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid) @@ -259,19 +258,25 @@ struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid) dir_index = pasid >> PASID_PDE_SHIFT; index = pasid & PASID_PTE_MASK; - spin_lock(&pasid_lock); +retry: entries = get_pasid_table_from_pde(&dir[dir_index]); if (!entries) { entries = alloc_pgtable_page(info->iommu->node); - if (!entries) { - spin_unlock(&pasid_lock); + if (!entries) return NULL; - } - WRITE_ONCE(dir[dir_index].val, - (u64)virt_to_phys(entries) | PASID_PTE_PRESENT); + /* + * The pasid directory table entry won't be freed after + * allocation. No worry about the race with free and + * clear. However, this entry might be populated by others + * while we are preparing it. Use theirs with a retry. + */ + if (cmpxchg64(&dir[dir_index].val, 0ULL, + (u64)virt_to_phys(entries) | PASID_PTE_PRESENT)) { + free_pgtable_page(entries); + goto retry; + } } - spin_unlock(&pasid_lock); return &entries[index]; } From 7e00b52c8cdd9d3a985d63d72ecae7bde6314883 Mon Sep 17 00:00:00 2001 From: Jacob Pan Date: Thu, 16 Feb 2023 21:08:15 +0800 Subject: [PATCH 0668/1017] iommu/vt-d: Fix PASID directory pointer coherency [ Upstream commit 194b3348bdbb7db65375c72f3f774aee4cc6614e ] On platforms that do not support IOMMU Extended capability bit 0 Page-walk Coherency, CPU caches are not snooped when IOMMU is accessing any translation structures. IOMMU access goes only directly to memory. Intel IOMMU code was missing a flush for the PASID table directory that resulted in the unrecoverable fault as shown below. This patch adds clflush calls whenever allocating and updating a PASID table directory to ensure cache coherency. On the reverse direction, there's no need to clflush the PASID directory pointer when we deactivate a context entry in that IOMMU hardware will not see the old PASID directory pointer after we clear the context entry. PASID directory entries are also never freed once allocated. DMAR: DRHD: handling fault status reg 3 DMAR: [DMA Read NO_PASID] Request device [00:0d.2] fault addr 0x1026a4000 [fault reason 0x51] SM: Present bit in Directory Entry is clear DMAR: Dump dmar1 table entries for IOVA 0x1026a4000 DMAR: scalable mode root entry: hi 0x0000000102448001, low 0x0000000101b3e001 DMAR: context entry: hi 0x0000000000000000, low 0x0000000101b4d401 DMAR: pasid dir entry: 0x0000000101b4e001 DMAR: pasid table entry[0]: 0x0000000000000109 DMAR: pasid table entry[1]: 0x0000000000000001 DMAR: pasid table entry[2]: 0x0000000000000000 DMAR: pasid table entry[3]: 0x0000000000000000 DMAR: pasid table entry[4]: 0x0000000000000000 DMAR: pasid table entry[5]: 0x0000000000000000 DMAR: pasid table entry[6]: 0x0000000000000000 DMAR: pasid table entry[7]: 0x0000000000000000 DMAR: PTE not present at level 4 Cc: Fixes: 0bbeb01a4faf ("iommu/vt-d: Manage scalalble mode PASID tables") Reviewed-by: Kevin Tian Reported-by: Sukumar Ghorai Signed-off-by: Ashok Raj Signed-off-by: Jacob Pan Link: https://lore.kernel.org/r/20230209212843.1788125-1-jacob.jun.pan@linux.intel.com Signed-off-by: Lu Baolu Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/intel/pasid.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index f821153390e5..80d6412e2c54 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -186,6 +186,9 @@ int intel_pasid_alloc_table(struct device *dev) attach_out: device_attach_pasid_table(info, pasid_table); + if (!ecap_coherent(info->iommu->ecap)) + clflush_cache_range(pasid_table->table, size); + return 0; } @@ -276,6 +279,10 @@ retry: free_pgtable_page(entries); goto retry; } + if (!ecap_coherent(info->iommu->ecap)) { + clflush_cache_range(entries, VTD_PAGE_SIZE); + clflush_cache_range(&dir[dir_index].val, sizeof(*dir)); + } } return &entries[index]; From 030b1c4217a4f504c7d0795a2bd86b7181e56f11 Mon Sep 17 00:00:00 2001 From: Pierre Gondois Date: Wed, 15 Feb 2023 17:10:47 +0100 Subject: [PATCH 0669/1017] arm64: efi: Make efi_rt_lock a raw_spinlock [ Upstream commit 0e68b5517d3767562889f1d83fdb828c26adb24f ] Running a rt-kernel base on 6.2.0-rc3-rt1 on an Ampere Altra outputs the following: BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 9, name: kworker/u320:0 preempt_count: 2, expected: 0 RCU nest depth: 0, expected: 0 3 locks held by kworker/u320:0/9: #0: ffff3fff8c27d128 ((wq_completion)efi_rts_wq){+.+.}-{0:0}, at: process_one_work (./include/linux/atomic/atomic-long.h:41) #1: ffff80000861bdd0 ((work_completion)(&efi_rts_work.work)){+.+.}-{0:0}, at: process_one_work (./include/linux/atomic/atomic-long.h:41) #2: ffffdf7e1ed3e460 (efi_rt_lock){+.+.}-{3:3}, at: efi_call_rts (drivers/firmware/efi/runtime-wrappers.c:101) Preemption disabled at: efi_virtmap_load (./arch/arm64/include/asm/mmu_context.h:248) CPU: 0 PID: 9 Comm: kworker/u320:0 Tainted: G W 6.2.0-rc3-rt1 Hardware name: WIWYNN Mt.Jade Server System B81.03001.0005/Mt.Jade Motherboard, BIOS 1.08.20220218 (SCP: 1.08.20220218) 2022/02/18 Workqueue: efi_rts_wq efi_call_rts Call trace: dump_backtrace (arch/arm64/kernel/stacktrace.c:158) show_stack (arch/arm64/kernel/stacktrace.c:165) dump_stack_lvl (lib/dump_stack.c:107 (discriminator 4)) dump_stack (lib/dump_stack.c:114) __might_resched (kernel/sched/core.c:10134) rt_spin_lock (kernel/locking/rtmutex.c:1769 (discriminator 4)) efi_call_rts (drivers/firmware/efi/runtime-wrappers.c:101) [...] This seems to come from commit ff7a167961d1 ("arm64: efi: Execute runtime services from a dedicated stack") which adds a spinlock. This spinlock is taken through: efi_call_rts() \-efi_call_virt() \-efi_call_virt_pointer() \-arch_efi_call_virt_setup() Make 'efi_rt_lock' a raw_spinlock to avoid being preempted. [ardb: The EFI runtime services are called with a different set of translation tables, and are permitted to use the SIMD registers. The context switch code preserves/restores neither, and so EFI calls must be made with preemption disabled, rather than only disabling migration.] Fixes: ff7a167961d1 ("arm64: efi: Execute runtime services from a dedicated stack") Signed-off-by: Pierre Gondois Cc: # v6.1+ Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin --- arch/arm64/include/asm/efi.h | 6 +++--- arch/arm64/kernel/efi.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 16892f0d05ad..538b6a1b198b 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -25,7 +25,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); ({ \ efi_virtmap_load(); \ __efi_fpsimd_begin(); \ - spin_lock(&efi_rt_lock); \ + raw_spin_lock(&efi_rt_lock); \ }) #define arch_efi_call_virt(p, f, args...) \ @@ -37,12 +37,12 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define arch_efi_call_virt_teardown() \ ({ \ - spin_unlock(&efi_rt_lock); \ + raw_spin_unlock(&efi_rt_lock); \ __efi_fpsimd_end(); \ efi_virtmap_unload(); \ }) -extern spinlock_t efi_rt_lock; +extern raw_spinlock_t efi_rt_lock; efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 72f432d23ec5..3ee3b3daca47 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -144,7 +144,7 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f) return s; } -DEFINE_SPINLOCK(efi_rt_lock); +DEFINE_RAW_SPINLOCK(efi_rt_lock); asmlinkage u64 *efi_rt_stack_top __ro_after_init; From f9fdb3e7b0758516fbc5ae12e3ec23d9060f7035 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Tue, 20 Sep 2022 13:00:37 -0700 Subject: [PATCH 0670/1017] RISC-V: Avoid dereferening NULL regs in die() [ Upstream commit f2913d006fcdb61719635e093d1b5dd0dafecac7 ] I don't think we can actually die() without a regs pointer, but the compiler was warning about a NULL check after a dereference. It seems prudent to just avoid the possibly-NULL dereference, given that when die()ing the system is already toast so who knows how we got there. Reported-by: kernel test robot Reported-by: Dan Carpenter Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20220920200037.6727-1-palmer@rivosinc.com Signed-off-by: Palmer Dabbelt Stable-dep-of: 130aee3fd998 ("riscv: Avoid enabling interrupts in die()") Signed-off-by: Sasha Levin --- arch/riscv/kernel/traps.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 23fe03ca7ec7..bc6b30f3add8 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -31,6 +31,7 @@ void die(struct pt_regs *regs, const char *str) { static int die_counter; int ret; + long cause; oops_enter(); @@ -40,11 +41,13 @@ void die(struct pt_regs *regs, const char *str) pr_emerg("%s [#%d]\n", str, ++die_counter); print_modules(); - show_regs(regs); + if (regs) + show_regs(regs); - ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV); + cause = regs ? regs->cause : -1; + ret = notify_die(DIE_OOPS, str, regs, 0, cause, SIGSEGV); - if (regs && kexec_should_crash(current)) + if (kexec_should_crash(current)) crash_kexec(regs); bust_spinlocks(0); From 713c335e5a8f1e65dbe9980ed77d8ae4c0364c34 Mon Sep 17 00:00:00 2001 From: Mattias Nissler Date: Wed, 15 Feb 2023 14:48:28 +0000 Subject: [PATCH 0671/1017] riscv: Avoid enabling interrupts in die() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 130aee3fd9981297ff9354e5d5609cd59aafbbea ] While working on something else, I noticed that the kernel would start accepting interrupts again after crashing in an interrupt handler. Since the kernel is already in inconsistent state, enabling interrupts is dangerous and opens up risk of kernel state deteriorating further. Interrupts do get enabled via what looks like an unintended side effect of spin_unlock_irq, so switch to the more cautious spin_lock_irqsave/spin_unlock_irqrestore instead. Fixes: 76d2a0493a17 ("RISC-V: Init and Halt Code") Signed-off-by: Mattias Nissler Reviewed-by: Björn Töpel Link: https://lore.kernel.org/r/20230215144828.3370316-1-mnissler@rivosinc.com Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/kernel/traps.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index bc6b30f3add8..227253fde33c 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -32,10 +32,11 @@ void die(struct pt_regs *regs, const char *str) static int die_counter; int ret; long cause; + unsigned long flags; oops_enter(); - spin_lock_irq(&die_lock); + spin_lock_irqsave(&die_lock, flags); console_verbose(); bust_spinlocks(1); @@ -52,7 +53,7 @@ void die(struct pt_regs *regs, const char *str) bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - spin_unlock_irq(&die_lock); + spin_unlock_irqrestore(&die_lock, flags); oops_exit(); if (in_interrupt()) From e993e3ea9550d5b604748ada728386ca25372aae Mon Sep 17 00:00:00 2001 From: Liao Chang Date: Sun, 29 Jan 2023 17:42:42 +0800 Subject: [PATCH 0672/1017] riscv: Add header include guards to insn.h [ Upstream commit 8ac6e619d9d51b3eb5bae817db8aa94e780a0db4 ] Add header include guards to insn.h to prevent repeating declaration of any identifiers in insn.h. Fixes: edde5584c7ab ("riscv: Add SW single-step support for KDB") Signed-off-by: Liao Chang Reviewed-by: Andrew Jones Fixes: c9c1af3f186a ("RISC-V: rename parse_asm.h to insn.h") Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20230129094242.282620-1-liaochang1@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/include/asm/parse_asm.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/riscv/include/asm/parse_asm.h b/arch/riscv/include/asm/parse_asm.h index 7fee806805c1..ad254da85e61 100644 --- a/arch/riscv/include/asm/parse_asm.h +++ b/arch/riscv/include/asm/parse_asm.h @@ -3,6 +3,9 @@ * Copyright (C) 2020 SiFive */ +#ifndef _ASM_RISCV_INSN_H +#define _ASM_RISCV_INSN_H + #include /* The bit field of immediate value in I-type instruction */ @@ -217,3 +220,5 @@ static inline bool is_ ## INSN_NAME ## _insn(long insn) \ (RVC_X(x_, RVC_B_IMM_5_OPOFF, RVC_B_IMM_5_MASK) << RVC_B_IMM_5_OFF) | \ (RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF) | \ (RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); }) + +#endif /* _ASM_RISCV_INSN_H */ From 6b223e32d66ca9db1f252f433514783d8b22a8e1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 10 Feb 2023 12:52:00 -0800 Subject: [PATCH 0673/1017] scsi: core: Remove the /proc/scsi/${proc_name} directory earlier [ Upstream commit fc663711b94468f4e1427ebe289c9f05669699c9 ] Remove the /proc/scsi/${proc_name} directory earlier to fix a race condition between unloading and reloading kernel modules. This fixes a bug introduced in 2009 by commit 77c019768f06 ("[SCSI] fix /proc memory leak in the SCSI core"). Fix the following kernel warning: proc_dir_entry 'scsi/scsi_debug' already registered WARNING: CPU: 19 PID: 27986 at fs/proc/generic.c:376 proc_register+0x27d/0x2e0 Call Trace: proc_mkdir+0xb5/0xe0 scsi_proc_hostdir_add+0xb5/0x170 scsi_host_alloc+0x683/0x6c0 sdebug_driver_probe+0x6b/0x2d0 [scsi_debug] really_probe+0x159/0x540 __driver_probe_device+0xdc/0x230 driver_probe_device+0x4f/0x120 __device_attach_driver+0xef/0x180 bus_for_each_drv+0xe5/0x130 __device_attach+0x127/0x290 device_initial_probe+0x17/0x20 bus_probe_device+0x110/0x130 device_add+0x673/0xc80 device_register+0x1e/0x30 sdebug_add_host_helper+0x1a7/0x3b0 [scsi_debug] scsi_debug_init+0x64f/0x1000 [scsi_debug] do_one_initcall+0xd7/0x470 do_init_module+0xe7/0x330 load_module+0x122a/0x12c0 __do_sys_finit_module+0x124/0x1a0 __x64_sys_finit_module+0x46/0x50 do_syscall_64+0x38/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Link: https://lore.kernel.org/r/20230210205200.36973-3-bvanassche@acm.org Cc: Alan Stern Cc: Yi Zhang Cc: stable@vger.kernel.org Fixes: 77c019768f06 ("[SCSI] fix /proc memory leak in the SCSI core") Reported-by: Yi Zhang Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/hosts.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index d664c4650b2d..fae032324210 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -180,6 +180,7 @@ void scsi_remove_host(struct Scsi_Host *shost) scsi_forget_host(shost); mutex_unlock(&shost->scan_mutex); scsi_proc_host_rm(shost); + scsi_proc_hostdir_rm(shost->hostt); spin_lock_irqsave(shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_DEL)) @@ -321,6 +322,7 @@ static void scsi_host_dev_release(struct device *dev) struct Scsi_Host *shost = dev_to_shost(dev); struct device *parent = dev->parent; + /* In case scsi_remove_host() has not been called. */ scsi_proc_hostdir_rm(shost->hostt); /* Wait for functions invoked through call_rcu(&shost->rcu, ...) */ From 0c440f14558bfacd22c6935ae1fd4b2a09e96b5d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 26 Jan 2023 12:22:21 +0100 Subject: [PATCH 0674/1017] ext4: Fix possible corruption when moving a directory [ Upstream commit 0813299c586b175d7edb25f56412c54b812d0379 ] When we are renaming a directory to a different directory, we need to update '..' entry in the moved directory. However nothing prevents moved directory from being modified and even converted from the inline format to the normal format. When such race happens the rename code gets confused and we crash. Fix the problem by locking the moved directory. CC: stable@vger.kernel.org Fixes: 32f7f22c0b52 ("ext4: let ext4_rename handle inline dir") Signed-off-by: Jan Kara Link: https://lore.kernel.org/r/20230126112221.11866-1-jack@suse.cz Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/namei.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 6f335d58183e..17590bb76914 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3923,9 +3923,16 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir)) goto end_rename; } + /* + * We need to protect against old.inode directory getting + * converted from inline directory format into a normal one. + */ + inode_lock_nested(old.inode, I_MUTEX_NONDIR2); retval = ext4_rename_dir_prepare(handle, &old); - if (retval) + if (retval) { + inode_unlock(old.inode); goto end_rename; + } } /* * If we're renaming a file within an inline_data dir and adding or @@ -4050,6 +4057,8 @@ end_rename: } else { ext4_journal_stop(handle); } + if (old.dir_bh) + inode_unlock(old.inode); release_bh: brelse(old.dir_bh); brelse(old.bh); From 9ca74e5e75ea29399cbec3102bb195a1d899fa4a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Jun 2022 20:46:06 +1000 Subject: [PATCH 0675/1017] drm/nouveau/kms/nv50-: remove unused functions [ Upstream commit 89ed996b888faaf11c69bb4cbc19f21475c9050e ] Signed-off-by: Ben Skeggs Reviewed-by: Dave Airlie Signed-off-by: Dave Airlie Stable-dep-of: 3638a820c5c3 ("drm/nouveau/kms/nv50: fix nv50_wndw_new_ prototype") Signed-off-by: Sasha Levin --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 16 ---------------- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 12 ------------ drivers/gpu/drm/nouveau/dispnv50/wndw.h | 2 -- 3 files changed, 30 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index c2d34c91e840..804ea035fa46 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2555,14 +2555,6 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend) { struct nouveau_drm *drm = nouveau_drm(dev); struct drm_encoder *encoder; - struct drm_plane *plane; - - drm_for_each_plane(plane, dev) { - struct nv50_wndw *wndw = nv50_wndw(plane); - if (plane->funcs != &nv50_wndw) - continue; - nv50_wndw_fini(wndw); - } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) @@ -2578,7 +2570,6 @@ nv50_display_init(struct drm_device *dev, bool resume, bool runtime) { struct nv50_core *core = nv50_disp(dev)->core; struct drm_encoder *encoder; - struct drm_plane *plane; if (resume || runtime) core->func->init(core); @@ -2591,13 +2582,6 @@ nv50_display_init(struct drm_device *dev, bool resume, bool runtime) } } - drm_for_each_plane(plane, dev) { - struct nv50_wndw *wndw = nv50_wndw(plane); - if (plane->funcs != &nv50_wndw) - continue; - nv50_wndw_init(wndw); - } - return 0; } diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index f07916ffe42c..831125b4453d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -690,18 +690,6 @@ nv50_wndw_notify(struct nvif_notify *notify) return NVIF_NOTIFY_KEEP; } -void -nv50_wndw_fini(struct nv50_wndw *wndw) -{ - nvif_notify_put(&wndw->notify); -} - -void -nv50_wndw_init(struct nv50_wndw *wndw) -{ - nvif_notify_get(&wndw->notify); -} - static const u64 nv50_cursor_format_modifiers[] = { DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID, diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 3278e2880034..8bed195ae098 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -40,8 +40,6 @@ int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *name, int index, const u32 *format, enum nv50_disp_interlock_type, u32 interlock_data, u32 heads, struct nv50_wndw **); -void nv50_wndw_init(struct nv50_wndw *); -void nv50_wndw_fini(struct nv50_wndw *); void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock, struct nv50_wndw_atom *); void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush, From 8b4a6dd1571783a3129ea5697bb2f16104d1ee13 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Mon, 31 Oct 2022 12:42:29 +0100 Subject: [PATCH 0676/1017] drm/nouveau/kms/nv50: fix nv50_wndw_new_ prototype [ Upstream commit 3638a820c5c3b52f327cebb174fd4274bee08aa7 ] gcc-13 warns about mismatching types for enums. That revealed switched arguments of nv50_wndw_new_(): drivers/gpu/drm/nouveau/dispnv50/wndw.c:696:1: error: conflicting types for 'nv50_wndw_new_' due to enum/integer mismatch; have 'int(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *, int, const u32 *, u32, enum nv50_disp_interlock_type, u32, struct nv50_wndw **)' drivers/gpu/drm/nouveau/dispnv50/wndw.h:36:5: note: previous declaration of 'nv50_wndw_new_' with type 'int(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *, int, const u32 *, enum nv50_disp_interlock_type, u32, u32, struct nv50_wndw **)' It can be barely visible, but the declaration says about the parameters in the middle: enum nv50_disp_interlock_type, u32 interlock_data, u32 heads, While the definition states differently: u32 heads, enum nv50_disp_interlock_type interlock_type, u32 interlock_data, Unify/fix the declaration to match the definition. Fixes: 53e0a3e70de6 ("drm/nouveau/kms/nv50-: simplify tracking of channel interlocks") Cc: Martin Liska Cc: Ben Skeggs Cc: Karol Herbst Cc: Lyude Paul Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Jiri Slaby (SUSE) Signed-off-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20221031114229.10289-1-jirislaby@kernel.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index 8bed195ae098..77bf124319fb 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -38,8 +38,9 @@ struct nv50_wndw { int nv50_wndw_new_(const struct nv50_wndw_func *, struct drm_device *, enum drm_plane_type, const char *name, int index, - const u32 *format, enum nv50_disp_interlock_type, - u32 interlock_data, u32 heads, struct nv50_wndw **); + const u32 *format, u32 heads, + enum nv50_disp_interlock_type, u32 interlock_data, + struct nv50_wndw **); void nv50_wndw_flush_set(struct nv50_wndw *, u32 *interlock, struct nv50_wndw_atom *); void nv50_wndw_flush_clr(struct nv50_wndw *, u32 *interlock, bool flush, From 08c0b54bef78eb74b9e1df32616fc85d5492c66f Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 15 Feb 2023 15:50:48 -0800 Subject: [PATCH 0677/1017] drm/msm: Fix potential invalid ptr free [ Upstream commit 8a86f213f4426f19511a16d886871805b35c3acf ] The error path cleanup expects that chain and syncobj are either NULL or valid pointers. But post_deps was not allocated with __GFP_ZERO. Fixes: ab723b7a992a ("drm/msm: Add syncobj support.") Signed-off-by: Rob Clark Reviewed-by: Dmitry Baryshkov Reviewed-by: Dmitry Osipenko Patchwork: https://patchwork.freedesktop.org/patch/523051/ Link: https://lore.kernel.org/r/20230215235048.1166484-1-robdclark@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_gem_submit.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index aa5c60a7132d..c4e5037512b9 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -494,8 +494,8 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev, int ret = 0; uint32_t i, j; - post_deps = kmalloc_array(nr_syncobjs, sizeof(*post_deps), - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); + post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps), + GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); if (!post_deps) return ERR_PTR(-ENOMEM); @@ -510,7 +510,6 @@ static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev, } post_deps[i].point = syncobj_desc.point; - post_deps[i].chain = NULL; if (syncobj_desc.flags) { ret = -EINVAL; From 00c2020b8bb8914f08b5df63992a7ea3c87cdb45 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 14 Feb 2023 05:09:53 +0300 Subject: [PATCH 0678/1017] drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register [ Upstream commit a7a4c19c36de1e4b99b06e4060ccc8ab837725bc ] Rather than writing CP_PREEMPT_ENABLE_GLOBAL twice, follow the vendor kernel and set CP_PREEMPT_ENABLE_LOCAL register instead. a5xx_submit() will override it during submission, but let's get the sequence correct. Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/522638/ Link: https://lore.kernel.org/r/20230214020956.164473-2-dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 0ca7e53db112..64da65ae6d67 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -144,8 +144,8 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_RING(ring, 1); /* Enable local preemption for finegrain preemption */ - OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); - OUT_RING(ring, 0x02); + OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1); + OUT_RING(ring, 0x1); /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */ OUT_PKT7(ring, CP_YIELD_ENABLE, 1); From 8dde1d9d6f065ea4c03c1d77182ba9e122d516d3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 23 Oct 2020 09:51:15 -0700 Subject: [PATCH 0679/1017] drm/msm: Document and rename preempt_lock [ Upstream commit 77c406038e830a4b6219b14a116cd2a6ac9f4908 ] Before adding another lock, give ring->lock a more descriptive name. Signed-off-by: Rob Clark Reviewed-by: Jordan Crouse Reviewed-by: Kristian H. Kristensen Signed-off-by: Rob Clark Stable-dep-of: b4fb748f0b73 ("drm/msm/a5xx: fix the emptyness check in the preempt code") Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 4 ++-- drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 12 ++++++------ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 ++-- drivers/gpu/drm/msm/msm_ringbuffer.c | 2 +- drivers/gpu/drm/msm/msm_ringbuffer.h | 7 ++++++- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 64da65ae6d67..6f84db97e20e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -36,7 +36,7 @@ void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, OUT_RING(ring, upper_32_bits(shadowptr(a5xx_gpu, ring))); } - spin_lock_irqsave(&ring->lock, flags); + spin_lock_irqsave(&ring->preempt_lock, flags); /* Copy the shadow to the actual register */ ring->cur = ring->next; @@ -44,7 +44,7 @@ void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, /* Make sure to wrap wptr if we need to */ wptr = get_wptr(ring); - spin_unlock_irqrestore(&ring->lock, flags); + spin_unlock_irqrestore(&ring->preempt_lock, flags); /* Make sure everything is posted before making a decision */ mb(); diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index 7e04509c4e1f..183de1139eeb 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -45,9 +45,9 @@ static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) if (!ring) return; - spin_lock_irqsave(&ring->lock, flags); + spin_lock_irqsave(&ring->preempt_lock, flags); wptr = get_wptr(ring); - spin_unlock_irqrestore(&ring->lock, flags); + spin_unlock_irqrestore(&ring->preempt_lock, flags); gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr); } @@ -62,9 +62,9 @@ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu) bool empty; struct msm_ringbuffer *ring = gpu->rb[i]; - spin_lock_irqsave(&ring->lock, flags); + spin_lock_irqsave(&ring->preempt_lock, flags); empty = (get_wptr(ring) == ring->memptrs->rptr); - spin_unlock_irqrestore(&ring->lock, flags); + spin_unlock_irqrestore(&ring->preempt_lock, flags); if (!empty) return ring; @@ -132,9 +132,9 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu) } /* Make sure the wptr doesn't update while we're in motion */ - spin_lock_irqsave(&ring->lock, flags); + spin_lock_irqsave(&ring->preempt_lock, flags); a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring); - spin_unlock_irqrestore(&ring->lock, flags); + spin_unlock_irqrestore(&ring->preempt_lock, flags); /* Set the address of the incoming preemption record */ gpu_write64(gpu, REG_A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_LO, diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index dffc133b8b1c..29b40acedb38 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -65,7 +65,7 @@ static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) OUT_RING(ring, upper_32_bits(shadowptr(a6xx_gpu, ring))); } - spin_lock_irqsave(&ring->lock, flags); + spin_lock_irqsave(&ring->preempt_lock, flags); /* Copy the shadow to the actual register */ ring->cur = ring->next; @@ -73,7 +73,7 @@ static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) /* Make sure to wrap wptr if we need to */ wptr = get_wptr(ring); - spin_unlock_irqrestore(&ring->lock, flags); + spin_unlock_irqrestore(&ring->preempt_lock, flags); /* Make sure everything is posted before making a decision */ mb(); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 935bf9b1d941..1b6958e908dc 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -46,7 +46,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, ring->memptrs_iova = memptrs_iova; INIT_LIST_HEAD(&ring->submits); - spin_lock_init(&ring->lock); + spin_lock_init(&ring->preempt_lock); snprintf(name, sizeof(name), "gpu-ring-%d", ring->id); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index 0987d6bf848c..4956d1bc5d0e 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -46,7 +46,12 @@ struct msm_ringbuffer { struct msm_rbmemptrs *memptrs; uint64_t memptrs_iova; struct msm_fence_context *fctx; - spinlock_t lock; + + /* + * preempt_lock protects preemption and serializes wptr updates against + * preemption. Can be aquired from irq context. + */ + spinlock_t preempt_lock; }; struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, From 34e71ca0a0068f9d7e12c59dc997ae5725fa181f Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 14 Feb 2023 05:09:55 +0300 Subject: [PATCH 0680/1017] drm/msm/a5xx: fix the emptyness check in the preempt code [ Upstream commit b4fb748f0b734ce1d2e7834998cc599fcbd25d67 ] Quoting Yassine: ring->memptrs->rptr is never updated and stays 0, so the comparison always evaluates to false and get_next_ring always returns ring 0 thinking it isn't empty. Fix this by calling get_rptr() instead of reading rptr directly. Reported-by: Yassine Oudjana Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets") Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/522642/ Link: https://lore.kernel.org/r/20230214020956.164473-4-dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index 183de1139eeb..9da0aff0072d 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -63,7 +63,7 @@ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu) struct msm_ringbuffer *ring = gpu->rb[i]; spin_lock_irqsave(&ring->preempt_lock, flags); - empty = (get_wptr(ring) == ring->memptrs->rptr); + empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring)); spin_unlock_irqrestore(&ring->preempt_lock, flags); if (!empty) From 4c43a0291f878bf194061b34e367f521f7066e25 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 14 Feb 2023 05:09:56 +0300 Subject: [PATCH 0681/1017] drm/msm/a5xx: fix context faults during ring switch [ Upstream commit 32e7083429d46f29080626fe387ff90c086b1fbe ] The rptr_addr is set in the preempt_init_ring(), which is called from a5xx_gpu_init(). It uses shadowptr() to set the address, however the shadow_iova is not yet initialized at that time. Move the rptr_addr setting to the a5xx_preempt_hw_init() which is called after setting the shadow_iova, getting the correct value for the address. Fixes: 8907afb476ac ("drm/msm: Allow a5xx to mark the RPTR shadow as privileged") Suggested-by: Rob Clark Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/522640/ Link: https://lore.kernel.org/r/20230214020956.164473-5-dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index 9da0aff0072d..b8e71ad6f8d8 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -210,6 +210,7 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu) a5xx_gpu->preempt[i]->wptr = 0; a5xx_gpu->preempt[i]->rptr = 0; a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova; + a5xx_gpu->preempt[i]->rptr_addr = shadowptr(a5xx_gpu, gpu->rb[i]); } /* Write a 0 to signal that we aren't switching pagetables */ @@ -261,7 +262,6 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu, ptr->data = 0; ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE; - ptr->rptr_addr = shadowptr(a5xx_gpu, ring); ptr->counter = counters_iova; return 0; From cbf11ff3708ff163387da924f80a47ce7c721e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 27 Feb 2023 10:11:56 +0100 Subject: [PATCH 0682/1017] bgmac: fix *initial* chip reset to support BCM5358 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f99e6d7c4ed3be2531bd576425a5bd07fb133bd7 ] While bringing hardware up we should perform a full reset including the switch bit (BGMAC_BCMA_IOCTL_SW_RESET aka SICF_SWRST). It's what specification says and what reference driver does. This seems to be critical for the BCM5358. Without this hardware doesn't get initialized properly and doesn't seem to transmit or receive any packets. Originally bgmac was calling bgmac_chip_reset() before setting "has_robosw" property which resulted in expected behaviour. That has changed as a side effect of adding platform device support which regressed BCM5358 support. Fixes: f6a95a24957a ("net: ethernet: bgmac: Add platform device support") Cc: Jon Mason Signed-off-by: Rafał Miłecki Reviewed-by: Leon Romanovsky Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20230227091156.19509-1-zajec5@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bgmac.c | 8 ++++++-- drivers/net/ethernet/broadcom/bgmac.h | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 9960127f612e..bb999e67d773 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -890,13 +890,13 @@ static void bgmac_chip_reset_idm_config(struct bgmac *bgmac) if (iost & BGMAC_BCMA_IOST_ATTACHED) { flags = BGMAC_BCMA_IOCTL_SW_CLKEN; - if (!bgmac->has_robosw) + if (bgmac->in_init || !bgmac->has_robosw) flags |= BGMAC_BCMA_IOCTL_SW_RESET; } bgmac_clk_enable(bgmac, flags); } - if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw) + if (iost & BGMAC_BCMA_IOST_ATTACHED && (bgmac->in_init || !bgmac->has_robosw)) bgmac_idm_write(bgmac, BCMA_IOCTL, bgmac_idm_read(bgmac, BCMA_IOCTL) & ~BGMAC_BCMA_IOCTL_SW_RESET); @@ -1490,6 +1490,8 @@ int bgmac_enet_probe(struct bgmac *bgmac) struct net_device *net_dev = bgmac->net_dev; int err; + bgmac->in_init = true; + bgmac_chip_intrs_off(bgmac); net_dev->irq = bgmac->irq; @@ -1542,6 +1544,8 @@ int bgmac_enet_probe(struct bgmac *bgmac) /* Omit FCS from max MTU size */ net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN; + bgmac->in_init = false; + err = register_netdev(bgmac->net_dev); if (err) { dev_err(bgmac->dev, "Cannot register net device\n"); diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 351c598a3ec6..d1200b27af1e 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -512,6 +512,8 @@ struct bgmac { int irq; u32 int_mask; + bool in_init; + /* Current MAC state */ int mac_speed; int mac_duplex; From 80be62358fa5507cefbaa067c7e6648401f2c3da Mon Sep 17 00:00:00 2001 From: Kang Chen Date: Mon, 27 Feb 2023 17:30:37 +0800 Subject: [PATCH 0683/1017] nfc: fdp: add null check of devm_kmalloc_array in fdp_nci_i2c_read_device_properties [ Upstream commit 11f180a5d62a51b484e9648f9b310e1bd50b1a57 ] devm_kmalloc_array may fails, *fw_vsc_cfg might be null and cause out-of-bounds write in device_property_read_u8_array later. Fixes: a06347c04c13 ("NFC: Add Intel Fields Peak NFC solution driver") Signed-off-by: Kang Chen Reviewed-by: Krzysztof Kozlowski Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230227093037.907654-1-void0red@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/nfc/fdp/i2c.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c index 5e300788be52..808d73050afd 100644 --- a/drivers/nfc/fdp/i2c.c +++ b/drivers/nfc/fdp/i2c.c @@ -249,6 +249,9 @@ static void fdp_nci_i2c_read_device_properties(struct device *dev, len, sizeof(**fw_vsc_cfg), GFP_KERNEL); + if (!*fw_vsc_cfg) + goto alloc_err; + r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME, *fw_vsc_cfg, len); @@ -262,6 +265,7 @@ vsc_read_err: *fw_vsc_cfg = NULL; } +alloc_err: dev_dbg(dev, "Clock type: %d, clock frequency: %d, VSC: %s", *clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no"); } From 6f0cc879c889596c7ea0cddc86ca19fcf540a1c4 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 24 Feb 2023 17:59:39 +0200 Subject: [PATCH 0684/1017] powerpc: dts: t1040rdb: fix compatible string for Rev A boards [ Upstream commit ae44f1c9d1fc54aeceb335fedb1e73b2c3ee4561 ] It looks like U-Boot fails to start the kernel properly when the compatible string of the board isn't fsl,T1040RDB, so stop overriding it from the rev-a.dts. Fixes: 5ebb74749202 ("powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch") Signed-off-by: Vladimir Oltean Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts b/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts index 73f8c998c64d..d4f5f159d6f2 100644 --- a/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts +++ b/arch/powerpc/boot/dts/fsl/t1040rdb-rev-a.dts @@ -10,7 +10,6 @@ / { model = "fsl,T1040RDB-REV-A"; - compatible = "fsl,T1040RDB-REV-A"; }; &seville_port0 { From 42d9ed4e5dc5f87fbd67c232e2e4a9b88ceeb47f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 27 Feb 2023 15:30:24 +0000 Subject: [PATCH 0685/1017] ila: do not generate empty messages in ila_xlat_nl_cmd_get_mapping() [ Upstream commit 693aa2c0d9b6d5b1f2745d31b6e70d09dbbaf06e ] ila_xlat_nl_cmd_get_mapping() generates an empty skb, triggerring a recent sanity check [1]. Instead, return an error code, so that user space can get it. [1] skb_assert_len WARNING: CPU: 0 PID: 5923 at include/linux/skbuff.h:2527 skb_assert_len include/linux/skbuff.h:2527 [inline] WARNING: CPU: 0 PID: 5923 at include/linux/skbuff.h:2527 __dev_queue_xmit+0x1bc0/0x3488 net/core/dev.c:4156 Modules linked in: CPU: 0 PID: 5923 Comm: syz-executor269 Not tainted 6.2.0-syzkaller-18300-g2ebd1fbb946d #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/21/2023 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : skb_assert_len include/linux/skbuff.h:2527 [inline] pc : __dev_queue_xmit+0x1bc0/0x3488 net/core/dev.c:4156 lr : skb_assert_len include/linux/skbuff.h:2527 [inline] lr : __dev_queue_xmit+0x1bc0/0x3488 net/core/dev.c:4156 sp : ffff80001e0d6c40 x29: ffff80001e0d6e60 x28: dfff800000000000 x27: ffff0000c86328c0 x26: dfff800000000000 x25: ffff0000c8632990 x24: ffff0000c8632a00 x23: 0000000000000000 x22: 1fffe000190c6542 x21: ffff0000c8632a10 x20: ffff0000c8632a00 x19: ffff80001856e000 x18: ffff80001e0d5fc0 x17: 0000000000000000 x16: ffff80001235d16c x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000001 x12: 0000000000000001 x11: ff80800008353a30 x10: 0000000000000000 x9 : 21567eaf25bfb600 x8 : 21567eaf25bfb600 x7 : 0000000000000001 x6 : 0000000000000001 x5 : ffff80001e0d6558 x4 : ffff800015c74760 x3 : ffff800008596744 x2 : 0000000000000001 x1 : 0000000100000000 x0 : 000000000000000e Call trace: skb_assert_len include/linux/skbuff.h:2527 [inline] __dev_queue_xmit+0x1bc0/0x3488 net/core/dev.c:4156 dev_queue_xmit include/linux/netdevice.h:3033 [inline] __netlink_deliver_tap_skb net/netlink/af_netlink.c:307 [inline] __netlink_deliver_tap+0x45c/0x6f8 net/netlink/af_netlink.c:325 netlink_deliver_tap+0xf4/0x174 net/netlink/af_netlink.c:338 __netlink_sendskb net/netlink/af_netlink.c:1283 [inline] netlink_sendskb+0x6c/0x154 net/netlink/af_netlink.c:1292 netlink_unicast+0x334/0x8d4 net/netlink/af_netlink.c:1380 nlmsg_unicast include/net/netlink.h:1099 [inline] genlmsg_unicast include/net/genetlink.h:433 [inline] genlmsg_reply include/net/genetlink.h:443 [inline] ila_xlat_nl_cmd_get_mapping+0x620/0x7d0 net/ipv6/ila/ila_xlat.c:493 genl_family_rcv_msg_doit net/netlink/genetlink.c:968 [inline] genl_family_rcv_msg net/netlink/genetlink.c:1048 [inline] genl_rcv_msg+0x938/0xc1c net/netlink/genetlink.c:1065 netlink_rcv_skb+0x214/0x3c4 net/netlink/af_netlink.c:2574 genl_rcv+0x38/0x50 net/netlink/genetlink.c:1076 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x660/0x8d4 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x800/0xae0 net/netlink/af_netlink.c:1942 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg net/socket.c:734 [inline] ____sys_sendmsg+0x558/0x844 net/socket.c:2479 ___sys_sendmsg net/socket.c:2533 [inline] __sys_sendmsg+0x26c/0x33c net/socket.c:2562 __do_sys_sendmsg net/socket.c:2571 [inline] __se_sys_sendmsg net/socket.c:2569 [inline] __arm64_sys_sendmsg+0x80/0x94 net/socket.c:2569 __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline] invoke_syscall+0x98/0x2c0 arch/arm64/kernel/syscall.c:52 el0_svc_common+0x138/0x258 arch/arm64/kernel/syscall.c:142 do_el0_svc+0x64/0x198 arch/arm64/kernel/syscall.c:193 el0_svc+0x58/0x168 arch/arm64/kernel/entry-common.c:637 el0t_64_sync_handler+0x84/0xf0 arch/arm64/kernel/entry-common.c:655 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:591 irq event stamp: 136484 hardirqs last enabled at (136483): [] __up_console_sem+0x60/0xb4 kernel/printk/printk.c:345 hardirqs last disabled at (136484): [] el1_dbg+0x24/0x80 arch/arm64/kernel/entry-common.c:405 softirqs last enabled at (136418): [] softirq_handle_end kernel/softirq.c:414 [inline] softirqs last enabled at (136418): [] __do_softirq+0xd4c/0xfa4 kernel/softirq.c:600 softirqs last disabled at (136371): [] ____do_softirq+0x14/0x20 arch/arm64/kernel/irq.c:80 ---[ end trace 0000000000000000 ]--- skb len=0 headroom=0 headlen=0 tailroom=192 mac=(0,0) net=(0,-1) trans=-1 shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0)) csum(0x0 ip_summed=0 complete_sw=0 valid=0 level=0) hash(0x0 sw=0 l4=0) proto=0x0010 pkttype=6 iif=0 dev name=nlmon0 feat=0x0000000000005861 Fixes: 7f00feaf1076 ("ila: Add generic ILA translation facility") Reported-by: syzbot Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv6/ila/ila_xlat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index a1ac0e3d8c60..163668531a57 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -477,6 +477,7 @@ int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info) rcu_read_lock(); + ret = -ESRCH; ila = ila_lookup_by_params(&xp, ilan); if (ila) { ret = ila_dump_info(ila, From 374cbffe7d6fd93ee22db7783a0205a0f7d5dccf Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Mon, 27 Feb 2023 17:36:46 +0800 Subject: [PATCH 0686/1017] selftests: nft_nat: ensuring the listening side is up before starting the client [ Upstream commit 2067e7a00aa604b94de31d64f29b8893b1696f26 ] The test_local_dnat_portonly() function initiates the client-side as soon as it sets the listening side to the background. This could lead to a race condition where the server may not be ready to listen. To ensure that the server-side is up and running before initiating the client-side, a delay is introduced to the test_local_dnat_portonly() function. Before the fix: # ./nft_nat.sh PASS: netns routing/connectivity: ns0-rthlYrBU can reach ns1-rthlYrBU and ns2-rthlYrBU PASS: ping to ns1-rthlYrBU was ip NATted to ns2-rthlYrBU PASS: ping to ns1-rthlYrBU OK after ip nat output chain flush PASS: ipv6 ping to ns1-rthlYrBU was ip6 NATted to ns2-rthlYrBU 2023/02/27 04:11:03 socat[6055] E connect(5, AF=2 10.0.1.99:2000, 16): Connection refused ERROR: inet port rewrite After the fix: # ./nft_nat.sh PASS: netns routing/connectivity: ns0-9sPJV6JJ can reach ns1-9sPJV6JJ and ns2-9sPJV6JJ PASS: ping to ns1-9sPJV6JJ was ip NATted to ns2-9sPJV6JJ PASS: ping to ns1-9sPJV6JJ OK after ip nat output chain flush PASS: ipv6 ping to ns1-9sPJV6JJ was ip6 NATted to ns2-9sPJV6JJ PASS: inet port rewrite without l3 address Fixes: 282e5f8fe907 ("netfilter: nat: really support inet nat without l3 address") Signed-off-by: Hangbin Liu Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- tools/testing/selftests/netfilter/nft_nat.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/netfilter/nft_nat.sh b/tools/testing/selftests/netfilter/nft_nat.sh index 4e15e8167310..67697d8ea59a 100755 --- a/tools/testing/selftests/netfilter/nft_nat.sh +++ b/tools/testing/selftests/netfilter/nft_nat.sh @@ -404,6 +404,8 @@ EOF echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 & sc_s=$! + sleep 1 + result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT) if [ "$result" = "SERVER-inet" ];then From d5e8f7edc2ac6b2fddeeaadf4930dea4c65da03d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 2 Nov 2020 11:45:06 +0000 Subject: [PATCH 0687/1017] net: usb: lan78xx: Remove lots of set but unused 'ret' variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 06cd7c46b3ab3f2252c61bf85b191236cf0254e1 ] Fixes the following W=1 kernel build warning(s): drivers/net/usb/lan78xx.c: In function ‘lan78xx_read_raw_otp’: drivers/net/usb/lan78xx.c:825:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_write_raw_otp’: drivers/net/usb/lan78xx.c:879:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_deferred_multicast_write’: drivers/net/usb/lan78xx.c:1041:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_update_flowcontrol’: drivers/net/usb/lan78xx.c:1127:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_init_mac_address’: drivers/net/usb/lan78xx.c:1666:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_link_status_change’: drivers/net/usb/lan78xx.c:1841:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_irq_bus_sync_unlock’: drivers/net/usb/lan78xx.c:1920:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan8835_fixup’: drivers/net/usb/lan78xx.c:1994:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_rx_max_frame_length’: drivers/net/usb/lan78xx.c:2192:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_change_mtu’: drivers/net/usb/lan78xx.c:2270:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_mac_addr’: drivers/net/usb/lan78xx.c:2299:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_features’: drivers/net/usb/lan78xx.c:2333:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_suspend’: drivers/net/usb/lan78xx.c:3807:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20201102114512.1062724-25-lee.jones@linaro.org Signed-off-by: Jakub Kicinski Stable-dep-of: e57cf3639c32 ("net: lan78xx: fix accessing the LAN7800's internal phy specific registers from the MAC driver") Signed-off-by: Sasha Levin --- drivers/net/usb/lan78xx.c | 168 ++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 90 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 6f7b70522d92..0b5b4f9c7c5b 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -824,20 +824,19 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset, u32 length, u8 *data) { int i; - int ret; u32 buf; unsigned long timeout; - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (buf & OTP_PWR_DN_PWRDN_N_) { /* clear it and wait to be cleared */ - ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0); + lan78xx_write_reg(dev, OTP_PWR_DN, 0); timeout = jiffies + HZ; do { usleep_range(1, 10); - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on OTP_PWR_DN"); @@ -847,18 +846,18 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset, } for (i = 0; i < length; i++) { - ret = lan78xx_write_reg(dev, OTP_ADDR1, + lan78xx_write_reg(dev, OTP_ADDR1, ((offset + i) >> 8) & OTP_ADDR1_15_11); - ret = lan78xx_write_reg(dev, OTP_ADDR2, + lan78xx_write_reg(dev, OTP_ADDR2, ((offset + i) & OTP_ADDR2_10_3)); - ret = lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); - ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); + lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); + lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); timeout = jiffies + HZ; do { udelay(1); - ret = lan78xx_read_reg(dev, OTP_STATUS, &buf); + lan78xx_read_reg(dev, OTP_STATUS, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on OTP_STATUS"); @@ -866,7 +865,7 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset, } } while (buf & OTP_STATUS_BUSY_); - ret = lan78xx_read_reg(dev, OTP_RD_DATA, &buf); + lan78xx_read_reg(dev, OTP_RD_DATA, &buf); data[i] = (u8)(buf & 0xFF); } @@ -878,20 +877,19 @@ static int lan78xx_write_raw_otp(struct lan78xx_net *dev, u32 offset, u32 length, u8 *data) { int i; - int ret; u32 buf; unsigned long timeout; - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (buf & OTP_PWR_DN_PWRDN_N_) { /* clear it and wait to be cleared */ - ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0); + lan78xx_write_reg(dev, OTP_PWR_DN, 0); timeout = jiffies + HZ; do { udelay(1); - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on OTP_PWR_DN completion"); @@ -901,21 +899,21 @@ static int lan78xx_write_raw_otp(struct lan78xx_net *dev, u32 offset, } /* set to BYTE program mode */ - ret = lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_); + lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_); for (i = 0; i < length; i++) { - ret = lan78xx_write_reg(dev, OTP_ADDR1, + lan78xx_write_reg(dev, OTP_ADDR1, ((offset + i) >> 8) & OTP_ADDR1_15_11); - ret = lan78xx_write_reg(dev, OTP_ADDR2, + lan78xx_write_reg(dev, OTP_ADDR2, ((offset + i) & OTP_ADDR2_10_3)); - ret = lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); - ret = lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); - ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); + lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); + lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); + lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); timeout = jiffies + HZ; do { udelay(1); - ret = lan78xx_read_reg(dev, OTP_STATUS, &buf); + lan78xx_read_reg(dev, OTP_STATUS, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "Timeout on OTP_STATUS completion"); @@ -1040,7 +1038,6 @@ static void lan78xx_deferred_multicast_write(struct work_struct *param) container_of(param, struct lan78xx_priv, set_multicast); struct lan78xx_net *dev = pdata->dev; int i; - int ret; netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x\n", pdata->rfe_ctl); @@ -1049,14 +1046,14 @@ static void lan78xx_deferred_multicast_write(struct work_struct *param) DP_SEL_VHF_HASH_LEN, pdata->mchash_table); for (i = 1; i < NUM_OF_MAF; i++) { - ret = lan78xx_write_reg(dev, MAF_HI(i), 0); - ret = lan78xx_write_reg(dev, MAF_LO(i), + lan78xx_write_reg(dev, MAF_HI(i), 0); + lan78xx_write_reg(dev, MAF_LO(i), pdata->pfilter_table[i][1]); - ret = lan78xx_write_reg(dev, MAF_HI(i), + lan78xx_write_reg(dev, MAF_HI(i), pdata->pfilter_table[i][0]); } - ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); } static void lan78xx_set_multicast(struct net_device *netdev) @@ -1126,7 +1123,6 @@ static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex, u16 lcladv, u16 rmtadv) { u32 flow = 0, fct_flow = 0; - int ret; u8 cap; if (dev->fc_autoneg) @@ -1149,10 +1145,10 @@ static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex, (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); - ret = lan78xx_write_reg(dev, FCT_FLOW, fct_flow); + lan78xx_write_reg(dev, FCT_FLOW, fct_flow); /* threshold value should be set before enabling flow */ - ret = lan78xx_write_reg(dev, FLOW, flow); + lan78xx_write_reg(dev, FLOW, flow); return 0; } @@ -1673,11 +1669,10 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { static void lan78xx_init_mac_address(struct lan78xx_net *dev) { u32 addr_lo, addr_hi; - int ret; u8 addr[6]; - ret = lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); - ret = lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); + lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); + lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); addr[0] = addr_lo & 0xFF; addr[1] = (addr_lo >> 8) & 0xFF; @@ -1710,12 +1705,12 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev) (addr[2] << 16) | (addr[3] << 24); addr_hi = addr[4] | (addr[5] << 8); - ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); - ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + lan78xx_write_reg(dev, RX_ADDRL, addr_lo); + lan78xx_write_reg(dev, RX_ADDRH, addr_hi); } - ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); - ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); ether_addr_copy(dev->net->dev_addr, addr); } @@ -1848,7 +1843,7 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) static void lan78xx_link_status_change(struct net_device *net) { struct phy_device *phydev = net->phydev; - int ret, temp; + int temp; /* At forced 100 F/H mode, chip may fail to set mode correctly * when cable is switched between long(~50+m) and short one. @@ -1859,7 +1854,7 @@ static void lan78xx_link_status_change(struct net_device *net) /* disable phy interrupt */ temp = phy_read(phydev, LAN88XX_INT_MASK); temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; - ret = phy_write(phydev, LAN88XX_INT_MASK, temp); + phy_write(phydev, LAN88XX_INT_MASK, temp); temp = phy_read(phydev, MII_BMCR); temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); @@ -1873,7 +1868,7 @@ static void lan78xx_link_status_change(struct net_device *net) /* enable phy interrupt back */ temp = phy_read(phydev, LAN88XX_INT_MASK); temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; - ret = phy_write(phydev, LAN88XX_INT_MASK, temp); + phy_write(phydev, LAN88XX_INT_MASK, temp); } } @@ -1927,14 +1922,13 @@ static void lan78xx_irq_bus_sync_unlock(struct irq_data *irqd) struct lan78xx_net *dev = container_of(data, struct lan78xx_net, domain_data); u32 buf; - int ret; /* call register access here because irq_bus_lock & irq_bus_sync_unlock * are only two callbacks executed in non-atomic contex. */ - ret = lan78xx_read_reg(dev, INT_EP_CTL, &buf); + lan78xx_read_reg(dev, INT_EP_CTL, &buf); if (buf != data->irqenable) - ret = lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable); + lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable); mutex_unlock(&data->irq_lock); } @@ -2001,7 +1995,6 @@ static void lan78xx_remove_irq_domain(struct lan78xx_net *dev) static int lan8835_fixup(struct phy_device *phydev) { int buf; - int ret; struct lan78xx_net *dev = netdev_priv(phydev->attached_dev); /* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */ @@ -2011,11 +2004,11 @@ static int lan8835_fixup(struct phy_device *phydev) phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8010, buf); /* RGMII MAC TXC Delay Enable */ - ret = lan78xx_write_reg(dev, MAC_RGMII_ID, + lan78xx_write_reg(dev, MAC_RGMII_ID, MAC_RGMII_ID_TXC_DELAY_EN_); /* RGMII TX DLL Tune Adjust */ - ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); + lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); dev->interface = PHY_INTERFACE_MODE_RGMII_TXID; @@ -2199,28 +2192,27 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) { - int ret = 0; u32 buf; bool rxenabled; - ret = lan78xx_read_reg(dev, MAC_RX, &buf); + lan78xx_read_reg(dev, MAC_RX, &buf); rxenabled = ((buf & MAC_RX_RXEN_) != 0); if (rxenabled) { buf &= ~MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); } /* add 4 to size for FCS */ buf &= ~MAC_RX_MAX_SIZE_MASK_; buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT_) & MAC_RX_MAX_SIZE_MASK_); - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); if (rxenabled) { buf |= MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); } return 0; @@ -2277,13 +2269,12 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu) int ll_mtu = new_mtu + netdev->hard_header_len; int old_hard_mtu = dev->hard_mtu; int old_rx_urb_size = dev->rx_urb_size; - int ret; /* no second zero-length packet read wanted after mtu-sized packets */ if ((ll_mtu % dev->maxpacket) == 0) return -EDOM; - ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); + lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); netdev->mtu = new_mtu; @@ -2306,7 +2297,6 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) struct lan78xx_net *dev = netdev_priv(netdev); struct sockaddr *addr = p; u32 addr_lo, addr_hi; - int ret; if (netif_running(netdev)) return -EBUSY; @@ -2323,12 +2313,12 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) addr_hi = netdev->dev_addr[4] | netdev->dev_addr[5] << 8; - ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); - ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + lan78xx_write_reg(dev, RX_ADDRL, addr_lo); + lan78xx_write_reg(dev, RX_ADDRH, addr_hi); /* Added to support MAC address changes */ - ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); - ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); return 0; } @@ -2340,7 +2330,6 @@ static int lan78xx_set_features(struct net_device *netdev, struct lan78xx_net *dev = netdev_priv(netdev); struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); unsigned long flags; - int ret; spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); @@ -2364,7 +2353,7 @@ static int lan78xx_set_features(struct net_device *netdev, spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); - ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); return 0; } @@ -3820,7 +3809,6 @@ static u16 lan78xx_wakeframe_crc16(const u8 *buf, int len) static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) { u32 buf; - int ret; int mask_index; u16 crc; u32 temp_wucsr; @@ -3829,26 +3817,26 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) const u8 ipv6_multicast[3] = { 0x33, 0x33 }; const u8 arp_type[2] = { 0x08, 0x06 }; - ret = lan78xx_read_reg(dev, MAC_TX, &buf); + lan78xx_read_reg(dev, MAC_TX, &buf); buf &= ~MAC_TX_TXEN_; - ret = lan78xx_write_reg(dev, MAC_TX, buf); - ret = lan78xx_read_reg(dev, MAC_RX, &buf); + lan78xx_write_reg(dev, MAC_TX, buf); + lan78xx_read_reg(dev, MAC_RX, &buf); buf &= ~MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); - ret = lan78xx_write_reg(dev, WUCSR, 0); - ret = lan78xx_write_reg(dev, WUCSR2, 0); - ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + lan78xx_write_reg(dev, WUCSR, 0); + lan78xx_write_reg(dev, WUCSR2, 0); + lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); temp_wucsr = 0; temp_pmt_ctl = 0; - ret = lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); + lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); temp_pmt_ctl &= ~PMT_CTL_RES_CLR_WKP_EN_; temp_pmt_ctl |= PMT_CTL_RES_CLR_WKP_STS_; for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) - ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); + lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); mask_index = 0; if (wol & WAKE_PHY) { @@ -3877,30 +3865,30 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) /* set WUF_CFG & WUF_MASK for IPv4 Multicast */ crc = lan78xx_wakeframe_crc16(ipv4_multicast, 3); - ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), + lan78xx_write_reg(dev, WUF_CFG(mask_index), WUF_CFGX_EN_ | WUF_CFGX_TYPE_MCAST_ | (0 << WUF_CFGX_OFFSET_SHIFT_) | (crc & WUF_CFGX_CRC16_MASK_)); - ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); - ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); - ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); - ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); + lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); mask_index++; /* for IPv6 Multicast */ crc = lan78xx_wakeframe_crc16(ipv6_multicast, 2); - ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), + lan78xx_write_reg(dev, WUF_CFG(mask_index), WUF_CFGX_EN_ | WUF_CFGX_TYPE_MCAST_ | (0 << WUF_CFGX_OFFSET_SHIFT_) | (crc & WUF_CFGX_CRC16_MASK_)); - ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); - ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); - ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); - ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); + lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); mask_index++; temp_pmt_ctl |= PMT_CTL_WOL_EN_; @@ -3921,16 +3909,16 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) * for packettype (offset 12,13) = ARP (0x0806) */ crc = lan78xx_wakeframe_crc16(arp_type, 2); - ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), + lan78xx_write_reg(dev, WUF_CFG(mask_index), WUF_CFGX_EN_ | WUF_CFGX_TYPE_ALL_ | (0 << WUF_CFGX_OFFSET_SHIFT_) | (crc & WUF_CFGX_CRC16_MASK_)); - ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); - ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); - ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); - ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); + lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); + lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); mask_index++; temp_pmt_ctl |= PMT_CTL_WOL_EN_; @@ -3938,7 +3926,7 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; } - ret = lan78xx_write_reg(dev, WUCSR, temp_wucsr); + lan78xx_write_reg(dev, WUCSR, temp_wucsr); /* when multiple WOL bits are set */ if (hweight_long((unsigned long)wol) > 1) { @@ -3946,16 +3934,16 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) temp_pmt_ctl &= ~PMT_CTL_SUS_MODE_MASK_; temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; } - ret = lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); + lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); /* clear WUPS */ - ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + lan78xx_read_reg(dev, PMT_CTL, &buf); buf |= PMT_CTL_WUPS_MASK_; - ret = lan78xx_write_reg(dev, PMT_CTL, buf); + lan78xx_write_reg(dev, PMT_CTL, buf); - ret = lan78xx_read_reg(dev, MAC_RX, &buf); + lan78xx_read_reg(dev, MAC_RX, &buf); buf |= MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); return 0; } From db16d6567402754300059b99f137844ca3fe532a Mon Sep 17 00:00:00 2001 From: Yuiko Oshino Date: Wed, 1 Mar 2023 08:43:07 -0700 Subject: [PATCH 0688/1017] net: lan78xx: fix accessing the LAN7800's internal phy specific registers from the MAC driver [ Upstream commit e57cf3639c323eeed05d3725fd82f91b349adca8 ] Move the LAN7800 internal phy (phy ID 0x0007c132) specific register accesses to the phy driver (microchip.c). Fix the error reported by Enguerrand de Ribaucourt in December 2022, "Some operations during the cable switch workaround modify the register LAN88XX_INT_MASK of the PHY. However, this register is specific to the LAN8835 PHY. For instance, if a DP8322I PHY is connected to the LAN7801, that register (0x19), corresponds to the LED and MAC address configuration, resulting in unapropriate behavior." I did not test with the DP8322I PHY, but I tested with an EVB-LAN7800 with the internal PHY. Fixes: 14437e3fa284 ("lan78xx: workaround of forced 100 Full/Half duplex mode error") Signed-off-by: Yuiko Oshino Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20230301154307.30438-1-yuiko.oshino@microchip.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/phy/microchip.c | 32 ++++++++++++++++++++++++++++++++ drivers/net/usb/lan78xx.c | 27 +-------------------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index a644e8e5071c..375bbd60b38a 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -326,6 +326,37 @@ static int lan88xx_config_aneg(struct phy_device *phydev) return genphy_config_aneg(phydev); } +static void lan88xx_link_change_notify(struct phy_device *phydev) +{ + int temp; + + /* At forced 100 F/H mode, chip may fail to set mode correctly + * when cable is switched between long(~50+m) and short one. + * As workaround, set to 10 before setting to 100 + * at forced 100 F/H mode. + */ + if (!phydev->autoneg && phydev->speed == 100) { + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + + temp = phy_read(phydev, MII_BMCR); + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ + temp |= BMCR_SPEED100; + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ + + /* clear pending interrupt generated while workaround */ + temp = phy_read(phydev, LAN88XX_INT_STS); + + /* enable phy interrupt back */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + } +} + static struct phy_driver microchip_phy_driver[] = { { .phy_id = 0x0007c130, @@ -339,6 +370,7 @@ static struct phy_driver microchip_phy_driver[] = { .config_init = lan88xx_config_init, .config_aneg = lan88xx_config_aneg, + .link_change_notify = lan88xx_link_change_notify, .ack_interrupt = lan88xx_phy_ack_interrupt, .config_intr = lan88xx_phy_config_intr, diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 0b5b4f9c7c5b..667984efeb3b 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1843,33 +1843,8 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) static void lan78xx_link_status_change(struct net_device *net) { struct phy_device *phydev = net->phydev; - int temp; - /* At forced 100 F/H mode, chip may fail to set mode correctly - * when cable is switched between long(~50+m) and short one. - * As workaround, set to 10 before setting to 100 - * at forced 100 F/H mode. - */ - if (!phydev->autoneg && (phydev->speed == 100)) { - /* disable phy interrupt */ - temp = phy_read(phydev, LAN88XX_INT_MASK); - temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; - phy_write(phydev, LAN88XX_INT_MASK, temp); - - temp = phy_read(phydev, MII_BMCR); - temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); - phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ - temp |= BMCR_SPEED100; - phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ - - /* clear pending interrupt generated while workaround */ - temp = phy_read(phydev, LAN88XX_INT_STS); - - /* enable phy interrupt back */ - temp = phy_read(phydev, LAN88XX_INT_MASK); - temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; - phy_write(phydev, LAN88XX_INT_MASK, temp); - } + phy_print_status(phydev); } static int irq_map(struct irq_domain *d, unsigned int irq, From c3aaec463a632cf4187dc017e421bfa69d7834a9 Mon Sep 17 00:00:00 2001 From: Shigeru Yoshida Date: Thu, 2 Mar 2023 01:39:13 +0900 Subject: [PATCH 0689/1017] net: caif: Fix use-after-free in cfusbl_device_notify() [ Upstream commit 9781e98a97110f5e76999058368b4be76a788484 ] syzbot reported use-after-free in cfusbl_device_notify() [1]. This causes a stack trace like below: BUG: KASAN: use-after-free in cfusbl_device_notify+0x7c9/0x870 net/caif/caif_usb.c:138 Read of size 8 at addr ffff88807ac4e6f0 by task kworker/u4:6/1214 CPU: 0 PID: 1214 Comm: kworker/u4:6 Not tainted 5.19.0-rc3-syzkaller-00146-g92f20ff72066 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: netns cleanup_net Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 print_address_description.constprop.0.cold+0xeb/0x467 mm/kasan/report.c:313 print_report mm/kasan/report.c:429 [inline] kasan_report.cold+0xf4/0x1c6 mm/kasan/report.c:491 cfusbl_device_notify+0x7c9/0x870 net/caif/caif_usb.c:138 notifier_call_chain+0xb5/0x200 kernel/notifier.c:87 call_netdevice_notifiers_info+0xb5/0x130 net/core/dev.c:1945 call_netdevice_notifiers_extack net/core/dev.c:1983 [inline] call_netdevice_notifiers net/core/dev.c:1997 [inline] netdev_wait_allrefs_any net/core/dev.c:10227 [inline] netdev_run_todo+0xbc0/0x10f0 net/core/dev.c:10341 default_device_exit_batch+0x44e/0x590 net/core/dev.c:11334 ops_exit_list+0x125/0x170 net/core/net_namespace.c:167 cleanup_net+0x4ea/0xb00 net/core/net_namespace.c:594 process_one_work+0x996/0x1610 kernel/workqueue.c:2289 worker_thread+0x665/0x1080 kernel/workqueue.c:2436 kthread+0x2e9/0x3a0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:302 When unregistering a net device, unregister_netdevice_many_notify() sets the device's reg_state to NETREG_UNREGISTERING, calls notifiers with NETDEV_UNREGISTER, and adds the device to the todo list. Later on, devices in the todo list are processed by netdev_run_todo(). netdev_run_todo() waits devices' reference count become 1 while rebdoadcasting NETDEV_UNREGISTER notification. When cfusbl_device_notify() is called with NETDEV_UNREGISTER multiple times, the parent device might be freed. This could cause UAF. Processing NETDEV_UNREGISTER multiple times also causes inbalance of reference count for the module. This patch fixes the issue by accepting only first NETDEV_UNREGISTER notification. Fixes: 7ad65bf68d70 ("caif: Add support for CAIF over CDC NCM USB interface") CC: sjur.brandeland@stericsson.com Reported-by: syzbot+b563d33852b893653a9e@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=c3bfd8e2450adab3bffe4d80821fbbced600407f [1] Signed-off-by: Shigeru Yoshida Link: https://lore.kernel.org/r/20230301163913.391304-1-syoshida@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/caif/caif_usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c index b02e1292f7f1..24488a4e2d26 100644 --- a/net/caif/caif_usb.c +++ b/net/caif/caif_usb.c @@ -134,6 +134,9 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, struct usb_device *usbdev; int res; + if (what == NETDEV_UNREGISTER && dev->reg_state >= NETREG_UNREGISTERED) + return 0; + /* Check whether we have a NCM device, and find its VID/PID. */ if (!(dev->dev.parent && dev->dev.parent->driver && strcmp(dev->dev.parent->driver->name, "cdc_ncm") == 0)) From d2a5a9cdc5d6a33008c508d592f9847e7ff347cd Mon Sep 17 00:00:00 2001 From: Rongguang Wei Date: Thu, 2 Mar 2023 14:21:43 +0800 Subject: [PATCH 0690/1017] net: stmmac: add to set device wake up flag when stmmac init phy [ Upstream commit a9334b702a03b693f54ebd3b98f67bf722b74870 ] When MAC is not support PMT, driver will check PHY's WoL capability and set device wakeup capability in stmmac_init_phy(). We can enable the WoL through ethtool, the driver would enable the device wake up flag. Now the device_may_wakeup() return true. But if there is a way which enable the PHY's WoL capability derectly, like in BIOS. The driver would not know the enable thing and would not set the device wake up flag. The phy_suspend may failed like this: [ 32.409063] PM: dpm_run_callback(): mdio_bus_phy_suspend+0x0/0x50 returns -16 [ 32.409065] PM: Device stmmac-1:00 failed to suspend: error -16 [ 32.409067] PM: Some devices failed to suspend, or early wake event detected Add to set the device wakeup enable flag according to the get_wol function result in PHY can fix the error in this scene. v2: add a Fixes tag. Fixes: 1d8e5b0f3f2c ("net: stmmac: Support WOL with phy") Signed-off-by: Rongguang Wei Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1ec000d4c770..04c59102a286 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1145,6 +1145,7 @@ static int stmmac_init_phy(struct net_device *dev) phylink_ethtool_get_wol(priv->phylink, &wol); device_set_wakeup_capable(priv->device, !!wol.supported); + device_set_wakeup_enable(priv->device, !!wol.wolopts); } return ret; From c0df4e5c247d73f80925a62e7f0f9f8ae84bf691 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Fri, 3 Mar 2023 16:37:54 +0000 Subject: [PATCH 0691/1017] net: phylib: get rid of unnecessary locking [ Upstream commit f4b47a2e9463950df3e7c8b70e017877c1d4eb11 ] The locking in phy_probe() and phy_remove() does very little to prevent any races with e.g. phy_attach_direct(), but instead causes lockdep ABBA warnings. Remove it. ====================================================== WARNING: possible circular locking dependency detected 6.2.0-dirty #1108 Tainted: G W E ------------------------------------------------------ ip/415 is trying to acquire lock: ffff5c268f81ef50 (&dev->lock){+.+.}-{3:3}, at: phy_attach_direct+0x17c/0x3a0 [libphy] but task is already holding lock: ffffaef6496cb518 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x154/0x560 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (rtnl_mutex){+.+.}-{3:3}: __lock_acquire+0x35c/0x6c0 lock_acquire.part.0+0xcc/0x220 lock_acquire+0x68/0x84 __mutex_lock+0x8c/0x414 mutex_lock_nested+0x34/0x40 rtnl_lock+0x24/0x30 sfp_bus_add_upstream+0x34/0x150 phy_sfp_probe+0x4c/0x94 [libphy] mv3310_probe+0x148/0x184 [marvell10g] phy_probe+0x8c/0x200 [libphy] call_driver_probe+0xbc/0x15c really_probe+0xc0/0x320 __driver_probe_device+0x84/0x120 driver_probe_device+0x44/0x120 __device_attach_driver+0xc4/0x160 bus_for_each_drv+0x80/0xe0 __device_attach+0xb0/0x1f0 device_initial_probe+0x1c/0x2c bus_probe_device+0xa4/0xb0 device_add+0x360/0x53c phy_device_register+0x60/0xa4 [libphy] fwnode_mdiobus_phy_device_register+0xc0/0x190 [fwnode_mdio] fwnode_mdiobus_register_phy+0x160/0xd80 [fwnode_mdio] of_mdiobus_register+0x140/0x340 [of_mdio] orion_mdio_probe+0x298/0x3c0 [mvmdio] platform_probe+0x70/0xe0 call_driver_probe+0x34/0x15c really_probe+0xc0/0x320 __driver_probe_device+0x84/0x120 driver_probe_device+0x44/0x120 __driver_attach+0x104/0x210 bus_for_each_dev+0x78/0xdc driver_attach+0x2c/0x3c bus_add_driver+0x184/0x240 driver_register+0x80/0x13c __platform_driver_register+0x30/0x3c xt_compat_calc_jump+0x28/0xa4 [x_tables] do_one_initcall+0x50/0x1b0 do_init_module+0x50/0x1fc load_module+0x684/0x744 __do_sys_finit_module+0xc4/0x140 __arm64_sys_finit_module+0x28/0x34 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x6c/0x1b0 do_el0_svc+0x34/0x44 el0_svc+0x48/0xf0 el0t_64_sync_handler+0xb8/0xc0 el0t_64_sync+0x1a0/0x1a4 -> #0 (&dev->lock){+.+.}-{3:3}: check_prev_add+0xb4/0xc80 validate_chain+0x414/0x47c __lock_acquire+0x35c/0x6c0 lock_acquire.part.0+0xcc/0x220 lock_acquire+0x68/0x84 __mutex_lock+0x8c/0x414 mutex_lock_nested+0x34/0x40 phy_attach_direct+0x17c/0x3a0 [libphy] phylink_fwnode_phy_connect.part.0+0x70/0xe4 [phylink] phylink_fwnode_phy_connect+0x48/0x60 [phylink] mvpp2_open+0xec/0x2e0 [mvpp2] __dev_open+0x104/0x214 __dev_change_flags+0x1d4/0x254 dev_change_flags+0x2c/0x7c do_setlink+0x254/0xa50 __rtnl_newlink+0x430/0x514 rtnl_newlink+0x58/0x8c rtnetlink_rcv_msg+0x17c/0x560 netlink_rcv_skb+0x64/0x150 rtnetlink_rcv+0x20/0x30 netlink_unicast+0x1d4/0x2b4 netlink_sendmsg+0x1a4/0x400 ____sys_sendmsg+0x228/0x290 ___sys_sendmsg+0x88/0xec __sys_sendmsg+0x70/0xd0 __arm64_sys_sendmsg+0x2c/0x40 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x6c/0x1b0 do_el0_svc+0x34/0x44 el0_svc+0x48/0xf0 el0t_64_sync_handler+0xb8/0xc0 el0t_64_sync+0x1a0/0x1a4 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(rtnl_mutex); lock(&dev->lock); lock(rtnl_mutex); lock(&dev->lock); *** DEADLOCK *** Fixes: 298e54fa810e ("net: phy: add core phylib sfp support") Reported-by: Marc Zyngier Signed-off-by: Russell King (Oracle) Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/phy/phy_device.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 3ef5aa6b72a7..e771e0e8a9bc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -2833,8 +2833,6 @@ static int phy_probe(struct device *dev) if (phydrv->flags & PHY_IS_INTERNAL) phydev->is_internal = true; - mutex_lock(&phydev->lock); - /* Deassert the reset signal */ phy_device_reset(phydev, 0); @@ -2903,12 +2901,10 @@ static int phy_probe(struct device *dev) phydev->state = PHY_READY; out: - /* Assert the reset signal */ + /* Re-assert the reset signal on error */ if (err) phy_device_reset(phydev, 1); - mutex_unlock(&phydev->lock); - return err; } @@ -2918,9 +2914,7 @@ static int phy_remove(struct device *dev) cancel_delayed_work_sync(&phydev->state_queue); - mutex_lock(&phydev->lock); phydev->state = PHY_DOWN; - mutex_unlock(&phydev->lock); sfp_bus_del_upstream(phydev->sfp_bus); phydev->sfp_bus = NULL; From d16701a385b54f44bf41ff1d7485e7a11080deb3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 3 Mar 2023 18:43:57 -0800 Subject: [PATCH 0692/1017] bnxt_en: Avoid order-5 memory allocation for TPA data [ Upstream commit accd7e23693aaaa9aa0d3e9eca0ae77d1be80ab3 ] The driver needs to keep track of all the possible concurrent TPA (GRO/LRO) completions on the aggregation ring. On P5 chips, the maximum number of concurrent TPA is 256 and the amount of memory we allocate is order-5 on systems using 4K pages. Memory allocation failure has been reported: NetworkManager: page allocation failure: order:5, mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), nodemask=(null),cpuset=/,mems_allowed=0-1 CPU: 15 PID: 2995 Comm: NetworkManager Kdump: loaded Not tainted 5.10.156 #1 Hardware name: Dell Inc. PowerEdge R660/0M1CC5, BIOS 0.2.25 08/12/2022 Call Trace: dump_stack+0x57/0x6e warn_alloc.cold.120+0x7b/0xdd ? _cond_resched+0x15/0x30 ? __alloc_pages_direct_compact+0x15f/0x170 __alloc_pages_slowpath.constprop.108+0xc58/0xc70 __alloc_pages_nodemask+0x2d0/0x300 kmalloc_order+0x24/0xe0 kmalloc_order_trace+0x19/0x80 bnxt_alloc_mem+0x1150/0x15c0 [bnxt_en] ? bnxt_get_func_stat_ctxs+0x13/0x60 [bnxt_en] __bnxt_open_nic+0x12e/0x780 [bnxt_en] bnxt_open+0x10b/0x240 [bnxt_en] __dev_open+0xe9/0x180 __dev_change_flags+0x1af/0x220 dev_change_flags+0x21/0x60 do_setlink+0x35c/0x1100 Instead of allocating this big chunk of memory and dividing it up for the concurrent TPA instances, allocate each small chunk separately for each TPA instance. This will reduce it to order-0 allocations. Fixes: 79632e9ba386 ("bnxt_en: Expand bnxt_tpa_info struct to support 57500 chips.") Reviewed-by: Somnath Kotur Reviewed-by: Damodharam Ammepalli Reviewed-by: Pavan Chebbi Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index c4a768ce8c99..6928c0b578ab 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2854,7 +2854,7 @@ static int bnxt_alloc_ring(struct bnxt *bp, struct bnxt_ring_mem_info *rmem) static void bnxt_free_tpa_info(struct bnxt *bp) { - int i; + int i, j; for (i = 0; i < bp->rx_nr_rings; i++) { struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; @@ -2862,8 +2862,10 @@ static void bnxt_free_tpa_info(struct bnxt *bp) kfree(rxr->rx_tpa_idx_map); rxr->rx_tpa_idx_map = NULL; if (rxr->rx_tpa) { - kfree(rxr->rx_tpa[0].agg_arr); - rxr->rx_tpa[0].agg_arr = NULL; + for (j = 0; j < bp->max_tpa; j++) { + kfree(rxr->rx_tpa[j].agg_arr); + rxr->rx_tpa[j].agg_arr = NULL; + } } kfree(rxr->rx_tpa); rxr->rx_tpa = NULL; @@ -2872,14 +2874,13 @@ static void bnxt_free_tpa_info(struct bnxt *bp) static int bnxt_alloc_tpa_info(struct bnxt *bp) { - int i, j, total_aggs = 0; + int i, j; bp->max_tpa = MAX_TPA; if (bp->flags & BNXT_FLAG_CHIP_P5) { if (!bp->max_tpa_v2) return 0; bp->max_tpa = max_t(u16, bp->max_tpa_v2, MAX_TPA_P5); - total_aggs = bp->max_tpa * MAX_SKB_FRAGS; } for (i = 0; i < bp->rx_nr_rings; i++) { @@ -2893,12 +2894,12 @@ static int bnxt_alloc_tpa_info(struct bnxt *bp) if (!(bp->flags & BNXT_FLAG_CHIP_P5)) continue; - agg = kcalloc(total_aggs, sizeof(*agg), GFP_KERNEL); - rxr->rx_tpa[0].agg_arr = agg; - if (!agg) - return -ENOMEM; - for (j = 1; j < bp->max_tpa; j++) - rxr->rx_tpa[j].agg_arr = agg + j * MAX_SKB_FRAGS; + for (j = 0; j < bp->max_tpa; j++) { + agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL); + if (!agg) + return -ENOMEM; + rxr->rx_tpa[j].agg_arr = agg; + } rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map), GFP_KERNEL); if (!rxr->rx_tpa_idx_map) From 26fa059cc92477c5fb16ef5bdca3b75997ddf95c Mon Sep 17 00:00:00 2001 From: Ivan Delalande Date: Thu, 2 Mar 2023 17:48:31 -0800 Subject: [PATCH 0693/1017] netfilter: ctnetlink: revert to dumping mark regardless of event type [ Upstream commit 9f7dd42f0db1dc6915a52d4a8a96ca18dd8cc34e ] It seems that change was unintentional, we have userspace code that needs the mark while listening for events like REPLY, DESTROY, etc. Also include 0-marks in requested dumps, as they were before that fix. Fixes: 1feeae071507 ("netfilter: ctnetlink: fix compilation warning after data race fixes in ct mark") Signed-off-by: Ivan Delalande Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_conntrack_netlink.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index f8ba3bc25cf3..c9ca857f1068 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -317,11 +317,12 @@ nla_put_failure: } #ifdef CONFIG_NF_CONNTRACK_MARK -static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) +static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct, + bool dump) { u32 mark = READ_ONCE(ct->mark); - if (!mark) + if (!mark && !dump) return 0; if (nla_put_be32(skb, CTA_MARK, htonl(mark))) @@ -332,7 +333,7 @@ nla_put_failure: return -1; } #else -#define ctnetlink_dump_mark(a, b) (0) +#define ctnetlink_dump_mark(a, b, c) (0) #endif #ifdef CONFIG_NF_CONNTRACK_SECMARK @@ -537,7 +538,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb, static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct) { if (ctnetlink_dump_status(skb, ct) < 0 || - ctnetlink_dump_mark(skb, ct) < 0 || + ctnetlink_dump_mark(skb, ct, true) < 0 || ctnetlink_dump_secctx(skb, ct) < 0 || ctnetlink_dump_id(skb, ct) < 0 || ctnetlink_dump_use(skb, ct) < 0 || @@ -816,8 +817,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) } #ifdef CONFIG_NF_CONNTRACK_MARK - if (events & (1 << IPCT_MARK) && - ctnetlink_dump_mark(skb, ct) < 0) + if (ctnetlink_dump_mark(skb, ct, events & (1 << IPCT_MARK))) goto nla_put_failure; #endif nlmsg_end(skb, nlh); @@ -2734,7 +2734,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct) goto nla_put_failure; #ifdef CONFIG_NF_CONNTRACK_MARK - if (ctnetlink_dump_mark(skb, ct) < 0) + if (ctnetlink_dump_mark(skb, ct, true) < 0) goto nla_put_failure; #endif if (ctnetlink_dump_labels(skb, ct) < 0) From 065c1ed5c4cec2ae676f2b6b35fd13acf85a11eb Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 3 Mar 2023 10:58:56 +0100 Subject: [PATCH 0694/1017] netfilter: tproxy: fix deadlock due to missing BH disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 4a02426787bf024dafdb79b362285ee325de3f5e ] The xtables packet traverser performs an unconditional local_bh_disable(), but the nf_tables evaluation loop does not. Functions that are called from either xtables or nftables must assume that they can be called in process context. inet_twsk_deschedule_put() assumes that no softirq interrupt can occur. If tproxy is used from nf_tables its possible that we'll deadlock trying to aquire a lock already held in process context. Add a small helper that takes care of this and use it. Link: https://lore.kernel.org/netfilter-devel/401bd6ed-314a-a196-1cdc-e13c720cc8f2@balasys.hu/ Fixes: 4ed8eb6570a4 ("netfilter: nf_tables: Add native tproxy support") Reported-and-tested-by: Major Dávid Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- include/net/netfilter/nf_tproxy.h | 7 +++++++ net/ipv4/netfilter/nf_tproxy_ipv4.c | 2 +- net/ipv6/netfilter/nf_tproxy_ipv6.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/net/netfilter/nf_tproxy.h b/include/net/netfilter/nf_tproxy.h index 82d0e41b76f2..faa108b1ba67 100644 --- a/include/net/netfilter/nf_tproxy.h +++ b/include/net/netfilter/nf_tproxy.h @@ -17,6 +17,13 @@ static inline bool nf_tproxy_sk_is_transparent(struct sock *sk) return false; } +static inline void nf_tproxy_twsk_deschedule_put(struct inet_timewait_sock *tw) +{ + local_bh_disable(); + inet_twsk_deschedule_put(tw); + local_bh_enable(); +} + /* assign a socket to the skb -- consumes sk */ static inline void nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) { diff --git a/net/ipv4/netfilter/nf_tproxy_ipv4.c b/net/ipv4/netfilter/nf_tproxy_ipv4.c index b2bae0b0e42a..61cb2341f50f 100644 --- a/net/ipv4/netfilter/nf_tproxy_ipv4.c +++ b/net/ipv4/netfilter/nf_tproxy_ipv4.c @@ -38,7 +38,7 @@ nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb, hp->source, lport ? lport : hp->dest, skb->dev, NF_TPROXY_LOOKUP_LISTENER); if (sk2) { - inet_twsk_deschedule_put(inet_twsk(sk)); + nf_tproxy_twsk_deschedule_put(inet_twsk(sk)); sk = sk2; } } diff --git a/net/ipv6/netfilter/nf_tproxy_ipv6.c b/net/ipv6/netfilter/nf_tproxy_ipv6.c index 6bac68fb27a3..3fe4f15e01dc 100644 --- a/net/ipv6/netfilter/nf_tproxy_ipv6.c +++ b/net/ipv6/netfilter/nf_tproxy_ipv6.c @@ -63,7 +63,7 @@ nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff, lport ? lport : hp->dest, skb->dev, NF_TPROXY_LOOKUP_LISTENER); if (sk2) { - inet_twsk_deschedule_put(inet_twsk(sk)); + nf_tproxy_twsk_deschedule_put(inet_twsk(sk)); sk = sk2; } } From 01a1e98109056dd8c760283f618a8d5fa97d26f9 Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Mon, 6 Mar 2023 11:21:37 +0000 Subject: [PATCH 0695/1017] btf: fix resolving BTF_KIND_VAR after ARRAY, STRUCT, UNION, PTR [ Upstream commit 9b459804ff9973e173fabafba2a1319f771e85fa ] btf_datasec_resolve contains a bug that causes the following BTF to fail loading: [1] DATASEC a size=2 vlen=2 type_id=4 offset=0 size=1 type_id=7 offset=1 size=1 [2] INT (anon) size=1 bits_offset=0 nr_bits=8 encoding=(none) [3] PTR (anon) type_id=2 [4] VAR a type_id=3 linkage=0 [5] INT (anon) size=1 bits_offset=0 nr_bits=8 encoding=(none) [6] TYPEDEF td type_id=5 [7] VAR b type_id=6 linkage=0 This error message is printed during btf_check_all_types: [1] DATASEC a size=2 vlen=2 type_id=7 offset=1 size=1 Invalid type By tracing btf_*_resolve we can pinpoint the problem: btf_datasec_resolve(depth: 1, type_id: 1, mode: RESOLVE_TBD) = 0 btf_var_resolve(depth: 2, type_id: 4, mode: RESOLVE_TBD) = 0 btf_ptr_resolve(depth: 3, type_id: 3, mode: RESOLVE_PTR) = 0 btf_var_resolve(depth: 2, type_id: 4, mode: RESOLVE_PTR) = 0 btf_datasec_resolve(depth: 1, type_id: 1, mode: RESOLVE_PTR) = -22 The last invocation of btf_datasec_resolve should invoke btf_var_resolve by means of env_stack_push, instead it returns EINVAL. The reason is that env_stack_push is never executed for the second VAR. if (!env_type_is_resolve_sink(env, var_type) && !env_type_is_resolved(env, var_type_id)) { env_stack_set_next_member(env, i + 1); return env_stack_push(env, var_type, var_type_id); } env_type_is_resolve_sink() changes its behaviour based on resolve_mode. For RESOLVE_PTR, we can simplify the if condition to the following: (btf_type_is_modifier() || btf_type_is_ptr) && !env_type_is_resolved() Since we're dealing with a VAR the clause evaluates to false. This is not sufficient to trigger the bug however. The log output and EINVAL are only generated if btf_type_id_size() fails. if (!btf_type_id_size(btf, &type_id, &type_size)) { btf_verifier_log_vsi(env, v->t, vsi, "Invalid type"); return -EINVAL; } Most types are sized, so for example a VAR referring to an INT is not a problem. The bug is only triggered if a VAR points at a modifier. Since we skipped btf_var_resolve that modifier was also never resolved, which means that btf_resolved_type_id returns 0 aka VOID for the modifier. This in turn causes btf_type_id_size to return NULL, triggering EINVAL. To summarise, the following conditions are necessary: - VAR pointing at PTR, STRUCT, UNION or ARRAY - Followed by a VAR pointing at TYPEDEF, VOLATILE, CONST, RESTRICT or TYPE_TAG The fix is to reset resolve_mode to RESOLVE_TBD before attempting to resolve a VAR from a DATASEC. Fixes: 1dc92851849c ("bpf: kernel side support for BTF Var and DataSec") Signed-off-by: Lorenz Bauer Link: https://lore.kernel.org/r/20230306112138.155352-2-lmb@isovalent.com Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- kernel/bpf/btf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 11b612e94e4e..cb80d18a49b5 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -3541,6 +3541,7 @@ static int btf_datasec_resolve(struct btf_verifier_env *env, struct btf *btf = env->btf; u16 i; + env->resolve_mode = RESOLVE_TBD; for_each_vsi_from(i, v->next_member, v->t, vsi) { u32 var_type_id = vsi->type, type_id, type_size = 0; const struct btf_type *var_type = btf_type_by_id(env->btf, From f4eae84f575492e18bd71176ad1a084bf837252d Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 4 Mar 2023 13:43:20 +0000 Subject: [PATCH 0696/1017] net: ethernet: mtk_eth_soc: fix RX data corruption issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 193250ace270fecd586dd2d0dfbd9cbd2ade977f ] Fix data corruption issue with SerDes connected PHYs operating at 1.25 Gbps speed where we could previously observe about 30% packet loss while the bad packet counter was increasing. As almost all boards with MediaTek MT7622 or MT7986 use either the MT7531 switch IC operating at 3.125Gbps SerDes rate or single-port PHYs using rate-adaptation to 2500Base-X mode, this issue only got exposed now when we started trying to use SFP modules operating with 1.25 Gbps with the BananaPi R3 board. The fix is to set bit 12 which disables the RX FIFO clear function when setting up MAC MCR, MediaTek SDK did the same change stating: "If without this patch, kernel might receive invalid packets that are corrupted by GMAC."[1] [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/d8a2975939a12686c4a95c40db21efdc3f821f63 Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC") Tested-by: Bjørn Mork Signed-off-by: Daniel Golle Reviewed-by: Vladimir Oltean Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/138da2735f92c8b6f8578ec2e5a794ee515b665f.1677937317.git.daniel@makrotopia.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 ++- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 217dc67c48fa..a8319295f1ab 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -354,7 +354,8 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); mcr_new = mcr_cur; mcr_new |= MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE | - MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK; + MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK | + MAC_MCR_RX_FIFO_CLR_DIS; /* Only update control register when needed! */ if (mcr_new != mcr_cur) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index 54a7cd93cc0f..0ca3223ad545 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -339,6 +339,7 @@ #define MAC_MCR_FORCE_MODE BIT(15) #define MAC_MCR_TX_EN BIT(14) #define MAC_MCR_RX_EN BIT(13) +#define MAC_MCR_RX_FIFO_CLR_DIS BIT(12) #define MAC_MCR_BACKOFF_EN BIT(9) #define MAC_MCR_BACKPR_EN BIT(8) #define MAC_MCR_FORCE_RX_FC BIT(5) From 0fe672336d69c56d0656e705158311618f627aba Mon Sep 17 00:00:00 2001 From: Chandrakanth Patil Date: Thu, 2 Mar 2023 16:23:40 +0530 Subject: [PATCH 0697/1017] scsi: megaraid_sas: Update max supported LD IDs to 240 [ Upstream commit bfa659177dcba48cf13f2bd88c1972f12a60bf1c ] The firmware only supports Logical Disk IDs up to 240 and LD ID 255 (0xFF) is reserved for deleted LDs. However, in some cases, firmware was assigning LD ID 254 (0xFE) to deleted LDs and this was causing the driver to mark the wrong disk as deleted. This in turn caused the wrong disk device to be taken offline by the SCSI midlayer. To address this issue, limit the LD ID range from 255 to 240. This ensures the deleted LD ID is properly identified and removed by the driver without accidently deleting any valid LDs. Fixes: ae6874ba4b43 ("scsi: megaraid_sas: Early detection of VD deletion through RaidMap update") Reported-by: Martin K. Petersen Signed-off-by: Chandrakanth Patil Signed-off-by: Sumit Saxena Link: https://lore.kernel.org/r/20230302105342.34933-2-chandrakanth.patil@broadcom.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/megaraid/megaraid_sas.h | 2 ++ drivers/scsi/megaraid/megaraid_sas_fp.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index c088a848776e..2d5b1d597866 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1517,6 +1517,8 @@ struct megasas_ctrl_info { #define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \ MEGASAS_MAX_DEV_PER_CHANNEL) +#define MEGASAS_MAX_SUPPORTED_LD_IDS 240 + #define MEGASAS_MAX_SECTORS (2*1024) #define MEGASAS_MAX_SECTORS_IEEE (2*128) #define MEGASAS_DBG_LVL 1 diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 83f69c33b01a..ec10d35b4685 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -358,7 +358,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id) ld = MR_TargetIdToLdGet(i, drv_map); /* For non existing VDs, iterate to next VD*/ - if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1)) + if (ld >= MEGASAS_MAX_SUPPORTED_LD_IDS) continue; raid = MR_LdRaidGet(ld, drv_map); From 93367126f68cd66359bbc81c3e9f6fda93701099 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 25 Feb 2023 21:39:51 -0800 Subject: [PATCH 0698/1017] platform: x86: MLX_PLATFORM: select REGMAP instead of depending on it [ Upstream commit 7e7e1541c91615e9950d0b96bcd1806d297e970e ] REGMAP is a hidden (not user visible) symbol. Users cannot set it directly thru "make *config", so drivers should select it instead of depending on it if they need it. Consistently using "select" or "depends on" can also help reduce Kconfig circular dependency issues. Therefore, change the use of "depends on REGMAP" to "select REGMAP". Fixes: ef0f62264b2a ("platform/x86: mlx-platform: Add physical bus number auto detection") Signed-off-by: Randy Dunlap Cc: Vadim Pasternak Cc: Darren Hart Cc: Hans de Goede Cc: Mark Gross Cc: platform-driver-x86@vger.kernel.org Link: https://lore.kernel.org/r/20230226053953.4681-7-rdunlap@infradead.org Signed-off-by: Hans de Goede Reviewed-by: Hans de Goede Signed-off-by: Sasha Levin --- drivers/platform/x86/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index a1858689d6e1..84c5b922f245 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1195,7 +1195,8 @@ config I2C_MULTI_INSTANTIATE config MLX_PLATFORM tristate "Mellanox Technologies platform support" - depends on I2C && REGMAP + depends on I2C + select REGMAP help This option enables system support for the Mellanox Technologies platform. The Mellanox systems provide data center networking From e1b8342a85289d0d3411744c4fc1e0fc46fc9d5c Mon Sep 17 00:00:00 2001 From: "D. Wythe" Date: Tue, 7 Mar 2023 11:23:46 +0800 Subject: [PATCH 0699/1017] net/smc: fix fallback failed while sendmsg with fastopen [ Upstream commit ce7ca794712f186da99719e8b4e97bd5ddbb04c3 ] Before determining whether the msg has unsupported options, it has been prematurely terminated by the wrong status check. For the application, the general usages of MSG_FASTOPEN likes fd = socket(...) /* rather than connect */ sendto(fd, data, len, MSG_FASTOPEN) Hence, We need to check the flag before state check, because the sock state here is always SMC_INIT when applications tries MSG_FASTOPEN. Once we found unsupported options, fallback it to TCP. Fixes: ee9dfbef02d1 ("net/smc: handle sockopts forcing fallback") Signed-off-by: D. Wythe Signed-off-by: Simon Horman v2 -> v1: Optimize code style Reviewed-by: Tony Lu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/smc/af_smc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 41cbc7c89c9d..8ab84926816f 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1988,16 +1988,14 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; struct smc_sock *smc; - int rc = -EPIPE; + int rc; smc = smc_sk(sk); lock_sock(sk); - if ((sk->sk_state != SMC_ACTIVE) && - (sk->sk_state != SMC_APPCLOSEWAIT1) && - (sk->sk_state != SMC_INIT)) - goto out; + /* SMC does not support connect with fastopen */ if (msg->msg_flags & MSG_FASTOPEN) { + /* not connected yet, fallback */ if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) { smc_switch_to_fallback(smc); smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; @@ -2005,6 +2003,11 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) rc = -EINVAL; goto out; } + } else if ((sk->sk_state != SMC_ACTIVE) && + (sk->sk_state != SMC_APPCLOSEWAIT1) && + (sk->sk_state != SMC_INIT)) { + rc = -EPIPE; + goto out; } if (smc->use_fallback) From ce7dd61e004002bc1c48d1ca47c887f3f3cc7370 Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Fri, 3 Mar 2023 16:08:32 -0500 Subject: [PATCH 0700/1017] SUNRPC: Fix a server shutdown leak [ Upstream commit 9ca6705d9d609441d34f8b853e1e4a6369b3b171 ] Fix a race where kthread_stop() may prevent the threadfn from ever getting called. If that happens the svc_rqst will not be cleaned up. Fixes: ed6473ddc704 ("NFSv4: Fix callback server shutdown") Signed-off-by: Benjamin Coddington Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- net/sunrpc/svc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index d38788cd9433..af657a482ad2 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -800,6 +800,7 @@ EXPORT_SYMBOL_GPL(svc_set_num_threads); static int svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) { + struct svc_rqst *rqstp; struct task_struct *task; unsigned int state = serv->sv_nrthreads-1; @@ -808,7 +809,10 @@ svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) task = choose_victim(serv, pool, &state); if (task == NULL) break; - kthread_stop(task); + rqstp = kthread_data(task); + /* Did we lose a race to svo_function threadfn? */ + if (kthread_stop(task) == -EINTR) + svc_exit_thread(rqstp); nrservs++; } while (nrservs < 0); return 0; From 3de277af481ab931fab9e295ad8762692920732a Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Wed, 8 Mar 2023 10:16:39 +0100 Subject: [PATCH 0701/1017] riscv: Use READ_ONCE_NOCHECK in imprecise unwinding stack mode [ Upstream commit 76950340cf03b149412fe0d5f0810e52ac1df8cb ] When CONFIG_FRAME_POINTER is unset, the stack unwinding function walk_stackframe randomly reads the stack and then, when KASAN is enabled, it can lead to the following backtrace: [ 0.000000] ================================================================== [ 0.000000] BUG: KASAN: stack-out-of-bounds in walk_stackframe+0xa6/0x11a [ 0.000000] Read of size 8 at addr ffffffff81807c40 by task swapper/0 [ 0.000000] [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 6.2.0-12919-g24203e6db61f #43 [ 0.000000] Hardware name: riscv-virtio,qemu (DT) [ 0.000000] Call Trace: [ 0.000000] [] walk_stackframe+0x0/0x11a [ 0.000000] [] init_param_lock+0x26/0x2a [ 0.000000] [] walk_stackframe+0xa2/0x11a [ 0.000000] [] dump_stack_lvl+0x22/0x36 [ 0.000000] [] print_report+0x198/0x4a8 [ 0.000000] [] init_param_lock+0x26/0x2a [ 0.000000] [] walk_stackframe+0xa2/0x11a [ 0.000000] [] kasan_report+0x9a/0xc8 [ 0.000000] [] walk_stackframe+0xa2/0x11a [ 0.000000] [] walk_stackframe+0xa2/0x11a [ 0.000000] [] desc_make_final+0x80/0x84 [ 0.000000] [] stack_trace_save+0x88/0xa6 [ 0.000000] [] filter_irq_stacks+0x72/0x76 [ 0.000000] [] devkmsg_read+0x32a/0x32e [ 0.000000] [] kasan_save_stack+0x28/0x52 [ 0.000000] [] desc_make_final+0x7c/0x84 [ 0.000000] [] stack_trace_save+0x84/0xa6 [ 0.000000] [] kasan_set_track+0x12/0x20 [ 0.000000] [] __kasan_slab_alloc+0x58/0x5e [ 0.000000] [] __kmem_cache_create+0x21e/0x39a [ 0.000000] [] create_boot_cache+0x70/0x9c [ 0.000000] [] kmem_cache_init+0x6c/0x11e [ 0.000000] [] mm_init+0xd8/0xfe [ 0.000000] [] start_kernel+0x190/0x3ca [ 0.000000] [ 0.000000] The buggy address belongs to stack of task swapper/0 [ 0.000000] and is located at offset 0 in frame: [ 0.000000] stack_trace_save+0x0/0xa6 [ 0.000000] [ 0.000000] This frame has 1 object: [ 0.000000] [32, 56) 'c' [ 0.000000] [ 0.000000] The buggy address belongs to the physical page: [ 0.000000] page:(____ptrval____) refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x81a07 [ 0.000000] flags: 0x1000(reserved|zone=0) [ 0.000000] raw: 0000000000001000 ff600003f1e3d150 ff600003f1e3d150 0000000000000000 [ 0.000000] raw: 0000000000000000 0000000000000000 00000001ffffffff [ 0.000000] page dumped because: kasan: bad access detected [ 0.000000] [ 0.000000] Memory state around the buggy address: [ 0.000000] ffffffff81807b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0.000000] ffffffff81807b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0.000000] >ffffffff81807c00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 f3 [ 0.000000] ^ [ 0.000000] ffffffff81807c80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 [ 0.000000] ffffffff81807d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0.000000] ================================================================== Fix that by using READ_ONCE_NOCHECK when reading the stack in imprecise mode. Fixes: 5d8544e2d007 ("RISC-V: Generic library routines and assembly") Reported-by: Chathura Rajapaksha Link: https://lore.kernel.org/all/CAD7mqryDQCYyJ1gAmtMm8SASMWAQ4i103ptTb0f6Oda=tPY2=A@mail.gmail.com/ Suggested-by: Dmitry Vyukov Signed-off-by: Alexandre Ghiti Link: https://lore.kernel.org/r/20230308091639.602024-1-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index 1e53fbe5eb78..9c34735c1e77 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -96,7 +96,7 @@ void notrace walk_stackframe(struct task_struct *task, while (!kstack_end(ksp)) { if (__kernel_text_address(pc) && unlikely(fn(pc, arg))) break; - pc = (*ksp++) - 0x4; + pc = READ_ONCE_NOCHECK(*ksp++) - 0x4; } } From ab89b8a67fbbc37c34c2ecb3ed0d7d2ea4bc4c3d Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Fri, 3 Mar 2023 14:37:55 +0000 Subject: [PATCH 0702/1017] RISC-V: Don't check text_mutex during stop_machine [ Upstream commit 2a8db5ec4a28a0fce822d10224db9471a44b6925 ] We're currently using stop_machine() to update ftrace & kprobes, which means that the thread that takes text_mutex during may not be the same as the thread that eventually patches the code. This isn't actually a race because the lock is still held (preventing any other concurrent accesses) and there is only one thread running during stop_machine(), but it does trigger a lockdep failure. This patch just elides the lockdep check during stop_machine. Fixes: c15ac4fd60d5 ("riscv/ftrace: Add dynamic function tracer support") Suggested-by: Steven Rostedt Reported-by: Changbin Du Signed-off-by: Palmer Dabbelt Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20230303143754.4005217-1-conor.dooley@microchip.com Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/include/asm/ftrace.h | 2 +- arch/riscv/include/asm/patch.h | 2 ++ arch/riscv/kernel/ftrace.c | 14 ++++++++++++-- arch/riscv/kernel/patch.c | 28 +++++++++++++++++++++++++--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h index 04dad3380041..bc745900c163 100644 --- a/arch/riscv/include/asm/ftrace.h +++ b/arch/riscv/include/asm/ftrace.h @@ -83,6 +83,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); #define ftrace_init_nop ftrace_init_nop #endif -#endif +#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* _ASM_RISCV_FTRACE_H */ diff --git a/arch/riscv/include/asm/patch.h b/arch/riscv/include/asm/patch.h index 9a7d7346001e..98d9de07cba1 100644 --- a/arch/riscv/include/asm/patch.h +++ b/arch/riscv/include/asm/patch.h @@ -9,4 +9,6 @@ int patch_text_nosync(void *addr, const void *insns, size_t len); int patch_text(void *addr, u32 insn); +extern int riscv_patch_in_stop_machine; + #endif /* _ASM_RISCV_PATCH_H */ diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c index 765b62434f30..8693dfcffb02 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -15,11 +15,21 @@ int ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex) { mutex_lock(&text_mutex); + + /* + * The code sequences we use for ftrace can't be patched while the + * kernel is running, so we need to use stop_machine() to modify them + * for now. This doesn't play nice with text_mutex, we use this flag + * to elide the check. + */ + riscv_patch_in_stop_machine = true; + return 0; } int ftrace_arch_code_modify_post_process(void) __releases(&text_mutex) { + riscv_patch_in_stop_machine = false; mutex_unlock(&text_mutex); return 0; } @@ -109,9 +119,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) { int out; - ftrace_arch_code_modify_prepare(); + mutex_lock(&text_mutex); out = ftrace_make_nop(mod, rec, MCOUNT_ADDR); - ftrace_arch_code_modify_post_process(); + mutex_unlock(&text_mutex); return out; } diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c index 1612e11f7bf6..c3fced410e74 100644 --- a/arch/riscv/kernel/patch.c +++ b/arch/riscv/kernel/patch.c @@ -11,6 +11,7 @@ #include #include #include +#include #include struct patch_insn { @@ -19,6 +20,8 @@ struct patch_insn { atomic_t cpu_count; }; +int riscv_patch_in_stop_machine = false; + #ifdef CONFIG_MMU static void *patch_map(void *addr, int fixmap) { @@ -55,8 +58,15 @@ static int patch_insn_write(void *addr, const void *insn, size_t len) * Before reaching here, it was expected to lock the text_mutex * already, so we don't need to give another lock here and could * ensure that it was safe between each cores. + * + * We're currently using stop_machine() for ftrace & kprobes, and while + * that ensures text_mutex is held before installing the mappings it + * does not ensure text_mutex is held by the calling thread. That's + * safe but triggers a lockdep failure, so just elide it for that + * specific case. */ - lockdep_assert_held(&text_mutex); + if (!riscv_patch_in_stop_machine) + lockdep_assert_held(&text_mutex); if (across_pages) patch_map(addr + len, FIX_TEXT_POKE1); @@ -117,13 +127,25 @@ NOKPROBE_SYMBOL(patch_text_cb); int patch_text(void *addr, u32 insn) { + int ret; struct patch_insn patch = { .addr = addr, .insn = insn, .cpu_count = ATOMIC_INIT(0), }; - return stop_machine_cpuslocked(patch_text_cb, - &patch, cpu_online_mask); + /* + * kprobes takes text_mutex, before calling patch_text(), but as we call + * calls stop_machine(), the lockdep assertion in patch_insn_write() + * gets confused by the context in which the lock is taken. + * Instead, ensure the lock is held before calling stop_machine(), and + * set riscv_patch_in_stop_machine to skip the check in + * patch_insn_write(). + */ + lockdep_assert_held(&text_mutex); + riscv_patch_in_stop_machine = true; + ret = stop_machine_cpuslocked(patch_text_cb, &patch, cpu_online_mask); + riscv_patch_in_stop_machine = false; + return ret; } NOKPROBE_SYMBOL(patch_text); From b113f90204479f55a17295bedf0cc966a60c7a56 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 1 Mar 2023 15:10:04 +0100 Subject: [PATCH 0703/1017] ext4: Fix deadlock during directory rename [ Upstream commit 3c92792da8506a295afb6d032b4476e46f979725 ] As lockdep properly warns, we should not be locking i_rwsem while having transactions started as the proper lock ordering used by all directory handling operations is i_rwsem -> transaction start. Fix the lock ordering by moving the locking of the directory earlier in ext4_rename(). Reported-by: syzbot+9d16c39efb5fade84574@syzkaller.appspotmail.com Fixes: 0813299c586b ("ext4: Fix possible corruption when moving a directory") Link: https://syzkaller.appspot.com/bug?extid=9d16c39efb5fade84574 Signed-off-by: Jan Kara Link: https://lore.kernel.org/r/20230301141004.15087-1-jack@suse.cz Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/namei.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 17590bb76914..1f47aeca7142 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3863,10 +3863,20 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, return retval; } + /* + * We need to protect against old.inode directory getting converted + * from inline directory format into a normal one. + */ + if (S_ISDIR(old.inode->i_mode)) + inode_lock_nested(old.inode, I_MUTEX_NONDIR2); + old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, &old.inlined); - if (IS_ERR(old.bh)) - return PTR_ERR(old.bh); + if (IS_ERR(old.bh)) { + retval = PTR_ERR(old.bh); + goto unlock_moved_dir; + } + /* * Check for inode number is _not_ due to possible IO errors. * We might rmdir the source, keep it as pwd of some process @@ -3923,11 +3933,6 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir)) goto end_rename; } - /* - * We need to protect against old.inode directory getting - * converted from inline directory format into a normal one. - */ - inode_lock_nested(old.inode, I_MUTEX_NONDIR2); retval = ext4_rename_dir_prepare(handle, &old); if (retval) { inode_unlock(old.inode); @@ -4057,12 +4062,15 @@ end_rename: } else { ext4_journal_stop(handle); } - if (old.dir_bh) - inode_unlock(old.inode); release_bh: brelse(old.dir_bh); brelse(old.bh); brelse(new.bh); + +unlock_moved_dir: + if (S_ISDIR(old.inode->i_mode)) + inode_unlock(old.inode); + return retval; } From f2a5ec7f7b28f9b9cd5fac232ff51019a7f7b9e9 Mon Sep 17 00:00:00 2001 From: Gavrilov Ilia Date: Thu, 2 Feb 2023 08:26:56 +0000 Subject: [PATCH 0704/1017] iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter [ Upstream commit b6b26d86c61c441144c72f842f7469bb686e1211 ] The 'acpiid' buffer in the parse_ivrs_acpihid function may overflow, because the string specifier in the format string sscanf() has no width limitation. Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE. Fixes: ca3bf5d47cec ("iommu/amd: Introduces ivrs_acpihid kernel parameter") Cc: stable@vger.kernel.org Signed-off-by: Ilia.Gavrilov Reviewed-by: Kim Phillips Link: https://lore.kernel.org/r/20230202082719.1513849-1-Ilia.Gavrilov@infotecs.ru Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/amd/init.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index ce822347f747..603f625a74e5 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -3124,15 +3124,26 @@ found: return 1; } +#define ACPIID_LEN (ACPIHID_UID_LEN + ACPIHID_HID_LEN) + static int __init parse_ivrs_acpihid(char *str) { u32 seg = 0, bus, dev, fn; char *hid, *uid, *p, *addr; - char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0}; + char acpiid[ACPIID_LEN] = {0}; int i; addr = strchr(str, '@'); if (!addr) { + addr = strchr(str, '='); + if (!addr) + goto not_found; + + ++addr; + + if (strlen(addr) > ACPIID_LEN) + goto not_found; + if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 || sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) { pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n", @@ -3145,6 +3156,9 @@ static int __init parse_ivrs_acpihid(char *str) /* We have the '@', make it the terminator to get just the acpiid */ *addr++ = 0; + if (strlen(str) > ACPIID_LEN + 1) + goto not_found; + if (sscanf(str, "=%s", acpiid) != 1) goto not_found; From b1fddddf58acd6d9618a2e3e974f3a2629b2ebf5 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 7 Mar 2023 16:21:06 +0100 Subject: [PATCH 0705/1017] watch_queue: fix IOC_WATCH_QUEUE_SET_SIZE alloc error paths [ Upstream commit 03e1d60e177eedbd302b77af4ea5e21b5a7ade31 ] The watch_queue_set_size() allocation error paths return the ret value set via the prior pipe_resize_ring() call, which will always be zero. As a result, IOC_WATCH_QUEUE_SET_SIZE callers such as "keyctl watch" fail to detect kernel wqueue->notes allocation failures and proceed to KEYCTL_WATCH_KEY, with any notifications subsequently lost. Fixes: c73be61cede58 ("pipe: Add general notification queue support") Signed-off-by: David Disseldorp Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Sasha Levin --- kernel/watch_queue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index d29731a30b8e..73717917d816 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -274,6 +274,7 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes) if (ret < 0) goto error; + ret = -ENOMEM; pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL); if (!pages) goto error; From c660e024bc681fdd0bd839a94834be216afd30d5 Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Wed, 15 Feb 2023 10:25:52 +0100 Subject: [PATCH 0706/1017] tpm/eventlog: Don't abort tpm_read_log on faulty ACPI address [ Upstream commit 80a6c216b16d7f5c584d2148c2e4345ea4eb06ce ] tpm_read_log_acpi() should return -ENODEV when no eventlog from the ACPI table is found. If the firmware vendor includes an invalid log address we are unable to map from the ACPI memory and tpm_read_log() returns -EIO which would abort discovery of the eventlog. Change the return value from -EIO to -ENODEV when acpi_os_map_iomem() fails to map the event log. The following hardware was used to test this issue: Framework Laptop (Pre-production) BIOS: INSYDE Corp, Revision: 3.2 TPM Device: NTC, Firmware Revision: 7.2 Dump of the faulty ACPI TPM2 table: [000h 0000 4] Signature : "TPM2" [Trusted Platform Module hardware interface Table] [004h 0004 4] Table Length : 0000004C [008h 0008 1] Revision : 04 [009h 0009 1] Checksum : 2B [00Ah 0010 6] Oem ID : "INSYDE" [010h 0016 8] Oem Table ID : "TGL-ULT" [018h 0024 4] Oem Revision : 00000002 [01Ch 0028 4] Asl Compiler ID : "ACPI" [020h 0032 4] Asl Compiler Revision : 00040000 [024h 0036 2] Platform Class : 0000 [026h 0038 2] Reserved : 0000 [028h 0040 8] Control Address : 0000000000000000 [030h 0048 4] Start Method : 06 [Memory Mapped I/O] [034h 0052 12] Method Parameters : 00 00 00 00 00 00 00 00 00 00 00 00 [040h 0064 4] Minimum Log Length : 00010000 [044h 0068 8] Log Address : 000000004053D000 Fixes: 0cf577a03f21 ("tpm: Fix handling of missing event log") Tested-by: Erkki Eilonen Signed-off-by: Morten Linderud Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Sasha Levin --- drivers/char/tpm/eventlog/acpi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c index 0913d3eb8d51..cd266021d010 100644 --- a/drivers/char/tpm/eventlog/acpi.c +++ b/drivers/char/tpm/eventlog/acpi.c @@ -143,8 +143,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip) ret = -EIO; virt = acpi_os_map_iomem(start, len); - if (!virt) + if (!virt) { + dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__); + /* try EFI log next */ + ret = -ENODEV; goto err; + } memcpy_fromio(log->bios_event_log, virt, len); From 5533742c7cb1bc9b1f0bf401cc397d44a3a9e07a Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 13 Mar 2023 15:27:53 -0700 Subject: [PATCH 0707/1017] block, bfq: fix possible uaf for 'bfqq->bic' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 64dc8c732f5c2b406cc752e6aaa1bd5471159cab ] Our test report a uaf for 'bfqq->bic' in 5.10: ================================================================== BUG: KASAN: use-after-free in bfq_select_queue+0x378/0xa30 CPU: 6 PID: 2318352 Comm: fsstress Kdump: loaded Not tainted 5.10.0-60.18.0.50.h602.kasan.eulerosv2r11.x86_64 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-20220320_160524-szxrtosci10000 04/01/2014 Call Trace: bfq_select_queue+0x378/0xa30 bfq_dispatch_request+0xe8/0x130 blk_mq_do_dispatch_sched+0x62/0xb0 __blk_mq_sched_dispatch_requests+0x215/0x2a0 blk_mq_sched_dispatch_requests+0x8f/0xd0 __blk_mq_run_hw_queue+0x98/0x180 __blk_mq_delay_run_hw_queue+0x22b/0x240 blk_mq_run_hw_queue+0xe3/0x190 blk_mq_sched_insert_requests+0x107/0x200 blk_mq_flush_plug_list+0x26e/0x3c0 blk_finish_plug+0x63/0x90 __iomap_dio_rw+0x7b5/0x910 iomap_dio_rw+0x36/0x80 ext4_dio_read_iter+0x146/0x190 [ext4] ext4_file_read_iter+0x1e2/0x230 [ext4] new_sync_read+0x29f/0x400 vfs_read+0x24e/0x2d0 ksys_read+0xd5/0x1b0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x61/0xc6 Commit 3bc5e683c67d ("bfq: Split shared queues on move between cgroups") changes that move process to a new cgroup will allocate a new bfqq to use, however, the old bfqq and new bfqq can point to the same bic: 1) Initial state, two process with io in the same cgroup. Process 1 Process 2 (BIC1) (BIC2) | Λ | Λ | | | | V | V | bfqq1 bfqq2 2) bfqq1 is merged to bfqq2. Process 1 Process 2 (BIC1) (BIC2) | | \-------------\| V bfqq1 bfqq2(coop) 3) Process 1 exit, then issue new io(denoce IOA) from Process 2. (BIC2) | Λ | | V | bfqq2(coop) 4) Before IOA is completed, move Process 2 to another cgroup and issue io. Process 2 (BIC2) Λ |\--------------\ | V bfqq2 bfqq3 Now that BIC2 points to bfqq3, while bfqq2 and bfqq3 both point to BIC2. If all the requests are completed, and Process 2 exit, BIC2 will be freed while there is no guarantee that bfqq2 will be freed before BIC2. Fix the problem by clearing bfqq->bic while bfqq is detached from bic. Fixes: 3bc5e683c67d ("bfq: Split shared queues on move between cgroups") Suggested-by: Jan Kara Signed-off-by: Yu Kuai Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20221214030430.3304151-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Khazhismel Kumykov Signed-off-by: Sasha Levin --- block/bfq-iosched.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 7c4b8d0635eb..afaededb3c49 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -373,6 +373,12 @@ struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, bool is_sync) void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync) { + struct bfq_queue *old_bfqq = bic->bfqq[is_sync]; + + /* Clear bic pointer if bfqq is detached from this bic */ + if (old_bfqq && old_bfqq->bic == bic) + old_bfqq->bic = NULL; + bic->bfqq[is_sync] = bfqq; } @@ -4977,7 +4983,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync) unsigned long flags; spin_lock_irqsave(&bfqd->lock, flags); - bfqq->bic = NULL; bfq_exit_bfqq(bfqd, bfqq); bic_set_bfqq(bic, NULL, is_sync); spin_unlock_irqrestore(&bfqd->lock, flags); From 1425f1bb5df5239021fd09ebc2a5e8070e705d36 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 13 Mar 2023 15:27:54 -0700 Subject: [PATCH 0708/1017] block, bfq: fix uaf for bfqq in bfq_exit_icq_bfqq [ Upstream commit 246cf66e300b76099b5dbd3fdd39e9a5dbc53f02 ] Commit 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'") will access 'bic->bfqq' in bic_set_bfqq(), however, bfq_exit_icq_bfqq() can free bfqq first, and then call bic_set_bfqq(), which will cause uaf. Fix the problem by moving bfq_exit_bfqq() behind bic_set_bfqq(). Fixes: 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'") Reported-by: Yi Zhang Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20221226030605.1437081-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Khazhismel Kumykov Signed-off-by: Sasha Levin --- block/bfq-iosched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index afaededb3c49..0a53b653a7e2 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -4983,8 +4983,8 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync) unsigned long flags; spin_lock_irqsave(&bfqd->lock, flags); - bfq_exit_bfqq(bfqd, bfqq); bic_set_bfqq(bic, NULL, is_sync); + bfq_exit_bfqq(bfqd, bfqq); spin_unlock_irqrestore(&bfqd->lock, flags); } } From e6f03decf5b77214602ba2a1a6e33f1fb789bae3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 13 Mar 2023 15:27:55 -0700 Subject: [PATCH 0709/1017] block/bfq-iosched.c: use "false" rather than "BLK_RW_ASYNC" [ Upstream commit f6bad159f5d5e5b33531aba3d9b860ad8618afe0 ] bfq_get_queue() expects a "bool" for the third arg, so pass "false" rather than "BLK_RW_ASYNC" which will soon be removed. Link: https://lkml.kernel.org/r/164549983746.9187.7949730109246767909.stgit@noble.brown Signed-off-by: NeilBrown Acked-by: Jens Axboe Cc: Anna Schumaker Cc: Chao Yu Cc: Darrick J. Wong Cc: Ilya Dryomov Cc: Jaegeuk Kim Cc: Jan Kara Cc: Jeff Layton Cc: Lars Ellenberg Cc: Miklos Szeredi Cc: Paolo Valente Cc: Philipp Reisner Cc: Ryusuke Konishi Cc: Trond Myklebust Cc: Wu Fengguang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Stable-dep-of: b600de2d7d3a ("block, bfq: fix uaf for bfqq in bic_set_bfqq()") Signed-off-by: Sasha Levin Signed-off-by: Khazhismel Kumykov Signed-off-by: Sasha Levin --- block/bfq-iosched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 0a53b653a7e2..35b240cba092 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5071,7 +5071,7 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio) bfqq = bic_to_bfqq(bic, false); if (bfqq) { bfq_release_process_ref(bfqd, bfqq); - bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic); + bfqq = bfq_get_queue(bfqd, bio, false, bic); bic_set_bfqq(bic, bfqq, false); } From 6291281f15e147428c95f0e053108086eba78f6e Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 13 Mar 2023 15:27:56 -0700 Subject: [PATCH 0710/1017] block, bfq: replace 0/1 with false/true in bic apis [ Upstream commit 337366e02b370d2800110fbc99940f6ddddcbdfa ] Just to make the code a litter cleaner, there are no functional changes. Signed-off-by: Yu Kuai Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20221214033155.3455754-3-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Stable-dep-of: b600de2d7d3a ("block, bfq: fix uaf for bfqq in bic_set_bfqq()") Signed-off-by: Sasha Levin Signed-off-by: Khazhismel Kumykov Signed-off-by: Sasha Levin --- block/bfq-cgroup.c | 8 ++++---- block/bfq-iosched.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index badb90352bf3..2f440b79183d 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -705,15 +705,15 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, struct bfq_io_cq *bic, struct bfq_group *bfqg) { - struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); - struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); + struct bfq_queue *async_bfqq = bic_to_bfqq(bic, false); + struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, true); struct bfq_entity *entity; if (async_bfqq) { entity = &async_bfqq->entity; if (entity->sched_data != &bfqg->sched_data) { - bic_set_bfqq(bic, NULL, 0); + bic_set_bfqq(bic, NULL, false); bfq_release_process_ref(bfqd, async_bfqq); } } @@ -749,7 +749,7 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, */ bfq_put_cooperator(sync_bfqq); bfq_release_process_ref(bfqd, sync_bfqq); - bic_set_bfqq(bic, NULL, 1); + bic_set_bfqq(bic, NULL, true); } } } diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 35b240cba092..016d7f32af9f 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2816,7 +2816,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, /* * Merge queues (that is, let bic redirect its requests to new_bfqq) */ - bic_set_bfqq(bic, new_bfqq, 1); + bic_set_bfqq(bic, new_bfqq, true); bfq_mark_bfqq_coop(new_bfqq); /* * new_bfqq now belongs to at least two bics (it is a shared queue): @@ -6014,7 +6014,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) return bfqq; } - bic_set_bfqq(bic, NULL, 1); + bic_set_bfqq(bic, NULL, true); bfq_put_cooperator(bfqq); From 7f77f3dab5066a7c9da73d72d1eee895ff84a8d5 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 13 Mar 2023 15:27:57 -0700 Subject: [PATCH 0711/1017] block, bfq: fix uaf for bfqq in bic_set_bfqq() [ Upstream commit b600de2d7d3a16f9007fad1bdae82a3951a26af2 ] After commit 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'"), bic->bfqq will be accessed in bic_set_bfqq(), however, in some context bic->bfqq will be freed, and bic_set_bfqq() is called with the freed bic->bfqq. Fix the problem by always freeing bfqq after bic_set_bfqq(). Fixes: 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'") Reported-and-tested-by: Shinichiro Kawasaki Signed-off-by: Yu Kuai Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230130014136.591038-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Khazhismel Kumykov Signed-off-by: Sasha Levin --- block/bfq-cgroup.c | 2 +- block/bfq-iosched.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index 2f440b79183d..1f9ccc661d57 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -748,8 +748,8 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, * request from the old cgroup. */ bfq_put_cooperator(sync_bfqq); - bfq_release_process_ref(bfqd, sync_bfqq); bic_set_bfqq(bic, NULL, true); + bfq_release_process_ref(bfqd, sync_bfqq); } } } diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 016d7f32af9f..6687b805bab3 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5070,9 +5070,11 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio) bfqq = bic_to_bfqq(bic, false); if (bfqq) { - bfq_release_process_ref(bfqd, bfqq); + struct bfq_queue *old_bfqq = bfqq; + bfqq = bfq_get_queue(bfqd, bio, false, bic); bic_set_bfqq(bic, bfqq, false); + bfq_release_process_ref(bfqd, old_bfqq); } bfqq = bic_to_bfqq(bic, true); From 5ddcb0a348194b372e9f0d027ba7eedb6b5bd1e0 Mon Sep 17 00:00:00 2001 From: xurui Date: Wed, 18 Jan 2023 16:59:12 +0800 Subject: [PATCH 0712/1017] MIPS: Fix a compilation issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 109d587a4b4d7ccca2200ab1f808f43ae23e2585 ] arch/mips/include/asm/mach-rc32434/pci.h:377: cc1: error: result of ‘-117440512 << 16’ requires 44 bits to represent, but ‘int’ only has 32 bits [-Werror=shift-overflow=] All bits in KORINA_STAT are already at the correct position, so there is no addtional shift needed. Signed-off-by: xurui Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/include/asm/mach-rc32434/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-rc32434/pci.h b/arch/mips/include/asm/mach-rc32434/pci.h index 9a6eefd12757..3eb767c8a4ee 100644 --- a/arch/mips/include/asm/mach-rc32434/pci.h +++ b/arch/mips/include/asm/mach-rc32434/pci.h @@ -374,7 +374,7 @@ struct pci_msu { PCI_CFG04_STAT_SSE | \ PCI_CFG04_STAT_PE) -#define KORINA_CNFG1 ((KORINA_STAT<<16)|KORINA_CMD) +#define KORINA_CNFG1 (KORINA_STAT | KORINA_CMD) #define KORINA_REVID 0 #define KORINA_CLASS_CODE 0 From 9a61a3a6ec660915b641dacc6ac40bb52cc9e06b Mon Sep 17 00:00:00 2001 From: Rohan McLure Date: Mon, 6 Feb 2023 13:17:58 +1100 Subject: [PATCH 0713/1017] powerpc/kcsan: Exclude udelay to prevent recursive instrumentation [ Upstream commit 2a7ce82dc46c591c9244057d89a6591c9639b9b9 ] In order for KCSAN to increase its likelihood of observing a data race, it sets a watchpoint on memory accesses and stalls, allowing for detection of conflicting accesses by other kernel threads or interrupts. Stalls are implemented by injecting a call to udelay in instrumented code. To prevent recursive instrumentation, exclude udelay from being instrumented. Signed-off-by: Rohan McLure Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230206021801.105268-3-rmclure@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 1d20f0f77a92..ba9b54d35f57 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -436,7 +436,7 @@ void vtime_flush(struct task_struct *tsk) #define calc_cputime_factors() #endif -void __delay(unsigned long loops) +void __no_kcsan __delay(unsigned long loops) { unsigned long start; @@ -457,7 +457,7 @@ void __delay(unsigned long loops) } EXPORT_SYMBOL(__delay); -void udelay(unsigned long usecs) +void __no_kcsan udelay(unsigned long usecs) { __delay(tb_ticks_per_usec * usecs); } From 9cff3f106a4cc59454c764eb3eff7c6237d649ab Mon Sep 17 00:00:00 2001 From: Edward Humes Date: Sat, 27 Aug 2022 02:49:39 -0400 Subject: [PATCH 0714/1017] alpha: fix R_ALPHA_LITERAL reloc for large modules [ Upstream commit b6b17a8b3ecd878d98d5472a9023ede9e669ca72 ] Previously, R_ALPHA_LITERAL relocations would overflow for large kernel modules. This was because the Alpha's apply_relocate_add was relying on the kernel's module loader to have sorted the GOT towards the very end of the module as it was mapped into memory in order to correctly assign the global pointer. While this behavior would mostly work fine for small kernel modules, this approach would overflow on kernel modules with large GOT's since the global pointer would be very far away from the GOT, and thus, certain entries would be out of range. This patch fixes this by instead using the Tru64 behavior of assigning the global pointer to be 32KB away from the start of the GOT. The change made in this patch won't work for multi-GOT kernel modules as it makes the assumption the module only has one GOT located at the beginning of .got, although for the vast majority kernel modules, this should be fine. Of the kernel modules that would previously result in a relocation error, none of them, even modules like nouveau, have even come close to filling up a single GOT, and they've all worked fine under this patch. Signed-off-by: Edward Humes Signed-off-by: Matt Turner Signed-off-by: Sasha Levin --- arch/alpha/kernel/module.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index 5b60c248de9e..cbefa5a77384 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -146,10 +146,8 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab, base = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr; symtab = (Elf64_Sym *)sechdrs[symindex].sh_addr; - /* The small sections were sorted to the end of the segment. - The following should definitely cover them. */ - gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000; got = sechdrs[me->arch.gotsecindex].sh_addr; + gp = got + 0x8000; for (i = 0; i < n; i++) { unsigned long r_sym = ELF64_R_SYM (rela[i].r_info); From d47d364f6671d8794a89e4972b1fd3284d213c96 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 15 Feb 2023 10:12:12 -0700 Subject: [PATCH 0715/1017] macintosh: windfarm: Use unsigned type for 1-bit bitfields [ Upstream commit 748ea32d2dbd813d3bd958117bde5191182f909a ] Clang warns: drivers/macintosh/windfarm_lm75_sensor.c:63:14: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion] lm->inited = 1; ^ ~ drivers/macintosh/windfarm_smu_sensors.c:356:19: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion] pow->fake_volts = 1; ^ ~ drivers/macintosh/windfarm_smu_sensors.c:368:18: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion] pow->quadratic = 1; ^ ~ There is no bug here since no code checks the actual value of these fields, just whether or not they are zero (boolean context), but this can be easily fixed by switching to an unsigned type. Signed-off-by: Nathan Chancellor Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230215-windfarm-wsingle-bit-bitfield-constant-conversion-v1-1-26415072e855@kernel.org Signed-off-by: Sasha Levin --- drivers/macintosh/windfarm_lm75_sensor.c | 4 ++-- drivers/macintosh/windfarm_smu_sensors.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 29f48c2028b6..e90ad1b78e93 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -34,8 +34,8 @@ #endif struct wf_lm75_sensor { - int ds1775 : 1; - int inited : 1; + unsigned int ds1775 : 1; + unsigned int inited : 1; struct i2c_client *i2c; struct wf_sensor sens; }; diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index c8706cfb83fd..714c1e14074e 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c @@ -273,8 +273,8 @@ struct smu_cpu_power_sensor { struct list_head link; struct wf_sensor *volts; struct wf_sensor *amps; - int fake_volts : 1; - int quadratic : 1; + unsigned int fake_volts : 1; + unsigned int quadratic : 1; struct wf_sensor sens; }; #define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens) From be658aa43a47c9a8e3462b01c7eb1420ba74d433 Mon Sep 17 00:00:00 2001 From: Alvaro Karsz Date: Tue, 10 Jan 2023 18:56:36 +0200 Subject: [PATCH 0716/1017] PCI: Add SolidRun vendor ID [ Upstream commit db6c4dee4c104f50ed163af71c53bfdb878a8318 ] Add SolidRun vendor ID to pci_ids.h The vendor ID is used in 2 different source files, the SNET vDPA driver and PCI quirks. Signed-off-by: Alvaro Karsz Acked-by: Bjorn Helgaas Message-Id: <20230110165638.123745-2-alvaro.karsz@solid-run.com> Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 2e1935917c24..4b34a5c12599 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -3115,6 +3115,8 @@ #define PCI_VENDOR_ID_3COM_2 0xa727 +#define PCI_VENDOR_ID_SOLIDRUN 0xd063 + #define PCI_VENDOR_ID_DIGIUM 0xd161 #define PCI_DEVICE_ID_DIGIUM_HFC4S 0xb410 From 42bb1e6b7fe8f826851eb4c5f1bac2b22a06a80b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Jan 2023 11:30:06 +0900 Subject: [PATCH 0717/1017] scripts: handle BrokenPipeError for python scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 87c7ee67deb7fce9951a5f9d80641138694aad17 ] In the follow-up of commit fb3041d61f68 ("kbuild: fix SIGPIPE error message for AR=gcc-ar and AR=llvm-ar"), Kees Cook pointed out that tools should _not_ catch their own SIGPIPEs [1] [2]. Based on his feedback, LLVM was fixed [3]. However, Python's default behavior is to show noisy bracktrace when SIGPIPE is sent. So, scripts written in Python are basically in the same situation as the buggy llvm tools. Example: $ make -s allnoconfig $ make -s allmodconfig $ scripts/diffconfig .config.old .config | head -n1 -ALIX n Traceback (most recent call last): File "/home/masahiro/linux/scripts/diffconfig", line 132, in main() File "/home/masahiro/linux/scripts/diffconfig", line 130, in main print_config("+", config, None, b[config]) File "/home/masahiro/linux/scripts/diffconfig", line 64, in print_config print("+%s %s" % (config, new_value)) BrokenPipeError: [Errno 32] Broken pipe Python documentation [4] notes how to make scripts die immediately and silently: """ Piping output of your program to tools like head(1) will cause a SIGPIPE signal to be sent to your process when the receiver of its standard output closes early. This results in an exception like BrokenPipeError: [Errno 32] Broken pipe. To handle this case, wrap your entry point to catch this exception as follows: import os import sys def main(): try: # simulate large output (your code replaces this loop) for x in range(10000): print("y") # flush output here to force SIGPIPE to be triggered # while inside this try block. sys.stdout.flush() except BrokenPipeError: # Python flushes standard streams on exit; redirect remaining output # to devnull to avoid another BrokenPipeError at shutdown devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) sys.exit(1) # Python exits with error code 1 on EPIPE if __name__ == '__main__': main() Do not set SIGPIPE’s disposition to SIG_DFL in order to avoid BrokenPipeError. Doing that would cause your program to exit unexpectedly whenever any socket connection is interrupted while your program is still writing to it. """ Currently, tools/perf/scripts/python/intel-pt-events.py seems to be the only script that fixes the issue that way. tools/perf/scripts/python/compaction-times.py uses another approach signal.signal(signal.SIGPIPE, signal.SIG_DFL) but the Python documentation clearly says "Don't do it". I cannot fix all Python scripts since there are so many. I fixed some in the scripts/ directory. [1]: https://lore.kernel.org/all/202211161056.1B9611A@keescook/ [2]: https://github.com/llvm/llvm-project/issues/59037 [3]: https://github.com/llvm/llvm-project/commit/4787efa38066adb51e2c049499d25b3610c0877b [4]: https://docs.python.org/3/library/signal.html#note-on-sigpipe Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Nicolas Schier Signed-off-by: Sasha Levin --- scripts/checkkconfigsymbols.py | 13 ++++++++++++- scripts/clang-tools/run-clang-tools.py | 21 ++++++++++++++------- scripts/diffconfig | 16 ++++++++++++++-- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py index 1548f9ce4682..697972432bbe 100755 --- a/scripts/checkkconfigsymbols.py +++ b/scripts/checkkconfigsymbols.py @@ -113,7 +113,7 @@ def parse_options(): return args -def main(): +def print_undefined_symbols(): """Main function of this module.""" args = parse_options() @@ -472,5 +472,16 @@ def parse_kconfig_file(kfile): return defined, references +def main(): + try: + print_undefined_symbols() + except BrokenPipeError: + # Python flushes standard streams on exit; redirect remaining output + # to devnull to avoid another BrokenPipeError at shutdown + devnull = os.open(os.devnull, os.O_WRONLY) + os.dup2(devnull, sys.stdout.fileno()) + sys.exit(1) # Python exits with error code 1 on EPIPE + + if __name__ == "__main__": main() diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py index f754415af398..f42699134f1c 100755 --- a/scripts/clang-tools/run-clang-tools.py +++ b/scripts/clang-tools/run-clang-tools.py @@ -60,14 +60,21 @@ def run_analysis(entry): def main(): - args = parse_arguments() + try: + args = parse_arguments() - lock = multiprocessing.Lock() - pool = multiprocessing.Pool(initializer=init, initargs=(lock, args)) - # Read JSON data into the datastore variable - with open(args.path, "r") as f: - datastore = json.load(f) - pool.map(run_analysis, datastore) + lock = multiprocessing.Lock() + pool = multiprocessing.Pool(initializer=init, initargs=(lock, args)) + # Read JSON data into the datastore variable + with open(args.path, "r") as f: + datastore = json.load(f) + pool.map(run_analysis, datastore) + except BrokenPipeError: + # Python flushes standard streams on exit; redirect remaining output + # to devnull to avoid another BrokenPipeError at shutdown + devnull = os.open(os.devnull, os.O_WRONLY) + os.dup2(devnull, sys.stdout.fileno()) + sys.exit(1) # Python exits with error code 1 on EPIPE if __name__ == "__main__": diff --git a/scripts/diffconfig b/scripts/diffconfig index d5da5fa05d1d..43f0f3d273ae 100755 --- a/scripts/diffconfig +++ b/scripts/diffconfig @@ -65,7 +65,7 @@ def print_config(op, config, value, new_value): else: print(" %s %s -> %s" % (config, value, new_value)) -def main(): +def show_diff(): global merge_style # parse command line args @@ -129,4 +129,16 @@ def main(): for config in new: print_config("+", config, None, b[config]) -main() +def main(): + try: + show_diff() + except BrokenPipeError: + # Python flushes standard streams on exit; redirect remaining output + # to devnull to avoid another BrokenPipeError at shutdown + devnull = os.open(os.devnull, os.O_WRONLY) + os.dup2(devnull, sys.stdout.fileno()) + sys.exit(1) # Python exits with error code 1 on EPIPE + + +if __name__ == '__main__': + main() From 13b04efb5bd011570a392a912df3e6109e414a9c Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Mon, 28 Nov 2022 09:02:01 +0100 Subject: [PATCH 0718/1017] media: ov5640: Fix analogue gain control [ Upstream commit afa4805799c1d332980ad23339fdb07b5e0cf7e0 ] Gain control is badly documented in publicly available (including leaked) documentation. There is an AGC pre-gain in register 0x3a13, expressed as a 6-bit value (plus an enable bit in bit 6). The driver hardcodes it to 0x43, which one application note states is equal to x1.047. The documentation also states that 0x40 is equel to x1.000. The pre-gain thus seems to be expressed as in 1/64 increments, and thus ranges from x1.00 to x1.984. What the pre-gain does is however unspecified. There is then an AGC gain limit, in registers 0x3a18 and 0x3a19, expressed as a 10-bit "real gain format" value. One application note sets it to 0x00f8 and states it is equal to x15.5, so it appears to be expressed in 1/16 increments, up to x63.9375. The manual gain is stored in registers 0x350a and 0x350b, also as a 10-bit "real gain format" value. It is documented in the application note as a Q6.4 values, up to x63.9375. One version of the datasheet indicates that the sensor supports a digital gain: The OV5640 supports 1/2/4 digital gain. Normally, the gain is controlled automatically by the automatic gain control (AGC) block. It isn't clear how that would be controlled manually. There appears to be no indication regarding whether the gain controlled through registers 0x350a and 0x350b is an analogue gain only or also includes digital gain. The words "real gain" don't necessarily mean "combined analogue and digital gains". Some OmniVision sensors (such as the OV8858) are documented as supoprting different formats for the gain values, selectable through a register bit, and they are called "real gain format" and "sensor gain format". For that sensor, we have (one of) the gain registers documented as 0x3503[2]=0, gain[7:0] is real gain format, where low 4 bits are fraction bits, for example, 0x10 is 1x gain, 0x28 is 2.5x gain If 0x3503[2]=1, gain[7:0] is sensor gain format, gain[7:4] is coarse gain, 00000: 1x, 00001: 2x, 00011: 4x, 00111: 8x, gain[7] is 1, gain[3:0] is fine gain. For example, 0x10 is 1x gain, 0x30 is 2x gain, 0x70 is 4x gain (The second part of the text makes little sense) "Real gain" may thus refer to the combination of the coarse and fine analogue gains as a single value. The OV5640 0x350a and 0x350b registers thus appear to control analogue gain. The driver incorrectly uses V4L2_CID_GAIN as V4L2 has a specific control for analogue gain, V4L2_CID_ANALOGUE_GAIN. Use it. If registers 0x350a and 0x350b are later found to control digital gain as well, the driver could then restrict the range of the analogue gain control value to lower than x64 and add a separate digital gain control. Signed-off-by: Paul Elder Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/i2c/ov5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 8f0812e85901..92a5f9aff9b5 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -2748,7 +2748,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) /* Auto/manual gain */ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, + ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, 0, 1023, 1, 0); ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, From a5c140d88a69eb43de2a030f1d7ff7b16bff3b1a Mon Sep 17 00:00:00 2001 From: Li Jun Date: Wed, 11 Jan 2023 10:39:21 +0100 Subject: [PATCH 0719/1017] media: rc: gpio-ir-recv: add remove function [ Upstream commit 30040818b338b8ebc956ce0ebd198f8d593586a6 ] In case runtime PM is enabled, do runtime PM clean up to remove cpu latency qos request, otherwise driver removal may have below kernel dump: [ 19.463299] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000048 [ 19.472161] Mem abort info: [ 19.474985] ESR = 0x0000000096000004 [ 19.478754] EC = 0x25: DABT (current EL), IL = 32 bits [ 19.484081] SET = 0, FnV = 0 [ 19.487149] EA = 0, S1PTW = 0 [ 19.490361] FSC = 0x04: level 0 translation fault [ 19.495256] Data abort info: [ 19.498149] ISV = 0, ISS = 0x00000004 [ 19.501997] CM = 0, WnR = 0 [ 19.504977] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000049f81000 [ 19.511432] [0000000000000048] pgd=0000000000000000, p4d=0000000000000000 [ 19.518245] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP [ 19.524520] Modules linked in: gpio_ir_recv(+) rc_core [last unloaded: rc_core] [ 19.531845] CPU: 0 PID: 445 Comm: insmod Not tainted 6.2.0-rc1-00028-g2c397a46d47c #72 [ 19.531854] Hardware name: FSL i.MX8MM EVK board (DT) [ 19.531859] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 19.551777] pc : cpu_latency_qos_remove_request+0x20/0x110 [ 19.557277] lr : gpio_ir_recv_runtime_suspend+0x18/0x30 [gpio_ir_recv] [ 19.557294] sp : ffff800008ce3740 [ 19.557297] x29: ffff800008ce3740 x28: 0000000000000000 x27: ffff800008ce3d50 [ 19.574270] x26: ffffc7e3e9cea100 x25: 00000000000f4240 x24: ffffc7e3f9ef0e30 [ 19.574284] x23: 0000000000000000 x22: ffff0061803820f4 x21: 0000000000000008 [ 19.574296] x20: ffffc7e3fa75df30 x19: 0000000000000020 x18: ffffffffffffffff [ 19.588570] x17: 0000000000000000 x16: ffffc7e3f9efab70 x15: ffffffffffffffff [ 19.595712] x14: ffff800008ce37b8 x13: ffff800008ce37aa x12: 0000000000000001 [ 19.602853] x11: 0000000000000001 x10: ffffcbe3ec0dff87 x9 : 0000000000000008 [ 19.609991] x8 : 0101010101010101 x7 : 0000000000000000 x6 : 000000000f0bfe9f [ 19.624261] x5 : 00ffffffffffffff x4 : 0025ab8e00000000 x3 : ffff006180382010 [ 19.631405] x2 : ffffc7e3e9ce8030 x1 : ffffc7e3fc3eb810 x0 : 0000000000000020 [ 19.638548] Call trace: [ 19.640995] cpu_latency_qos_remove_request+0x20/0x110 [ 19.646142] gpio_ir_recv_runtime_suspend+0x18/0x30 [gpio_ir_recv] [ 19.652339] pm_generic_runtime_suspend+0x2c/0x44 [ 19.657055] __rpm_callback+0x48/0x1dc [ 19.660807] rpm_callback+0x6c/0x80 [ 19.664301] rpm_suspend+0x10c/0x640 [ 19.667880] rpm_idle+0x250/0x2d0 [ 19.671198] update_autosuspend+0x38/0xe0 [ 19.675213] pm_runtime_set_autosuspend_delay+0x40/0x60 [ 19.680442] gpio_ir_recv_probe+0x1b4/0x21c [gpio_ir_recv] [ 19.685941] platform_probe+0x68/0xc0 [ 19.689610] really_probe+0xc0/0x3dc [ 19.693189] __driver_probe_device+0x7c/0x190 [ 19.697550] driver_probe_device+0x3c/0x110 [ 19.701739] __driver_attach+0xf4/0x200 [ 19.705578] bus_for_each_dev+0x70/0xd0 [ 19.709417] driver_attach+0x24/0x30 [ 19.712998] bus_add_driver+0x17c/0x240 [ 19.716834] driver_register+0x78/0x130 [ 19.720676] __platform_driver_register+0x28/0x34 [ 19.725386] gpio_ir_recv_driver_init+0x20/0x1000 [gpio_ir_recv] [ 19.731404] do_one_initcall+0x44/0x2ac [ 19.735243] do_init_module+0x48/0x1d0 [ 19.739003] load_module+0x19fc/0x2034 [ 19.742759] __do_sys_finit_module+0xac/0x12c [ 19.747124] __arm64_sys_finit_module+0x20/0x30 [ 19.751664] invoke_syscall+0x48/0x114 [ 19.755420] el0_svc_common.constprop.0+0xcc/0xec [ 19.760132] do_el0_svc+0x38/0xb0 [ 19.763456] el0_svc+0x2c/0x84 [ 19.766516] el0t_64_sync_handler+0xf4/0x120 [ 19.770789] el0t_64_sync+0x190/0x194 [ 19.774460] Code: 910003fd a90153f3 aa0003f3 91204021 (f9401400) [ 19.780556] ---[ end trace 0000000000000000 ]--- Signed-off-by: Li Jun Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/rc/gpio-ir-recv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 22e524b69806..a56c844d7f81 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -130,6 +130,23 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) "gpio-ir-recv-irq", gpio_dev); } +static int gpio_ir_recv_remove(struct platform_device *pdev) +{ + struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); + struct device *pmdev = gpio_dev->pmdev; + + if (pmdev) { + pm_runtime_get_sync(pmdev); + cpu_latency_qos_remove_request(&gpio_dev->qos); + + pm_runtime_disable(pmdev); + pm_runtime_put_noidle(pmdev); + pm_runtime_set_suspended(pmdev); + } + + return 0; +} + #ifdef CONFIG_PM static int gpio_ir_recv_suspend(struct device *dev) { @@ -189,6 +206,7 @@ MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match); static struct platform_driver gpio_ir_recv_driver = { .probe = gpio_ir_recv_probe, + .remove = gpio_ir_recv_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = of_match_ptr(gpio_ir_recv_of_match), From 7aa5a495cbf8a33cd9fec892c180dedf14292b76 Mon Sep 17 00:00:00 2001 From: Yejune Deng Date: Mon, 16 Nov 2020 15:30:07 +0800 Subject: [PATCH 0720/1017] ipmi/watchdog: replace atomic_add() and atomic_sub() commit a01a89b1db1066a6af23ae08b9a0c345b7966f0b upstream. atomic_inc() and atomic_dec() looks better Signed-off-by: Yejune Deng Message-Id: <1605511807-7135-1-git-send-email-yejune.deng@gmail.com> Signed-off-by: Corey Minyard Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_watchdog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 92eda5b2f134..7f71471c7a46 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -503,7 +503,7 @@ static void panic_halt_ipmi_heartbeat(void) msg.cmd = IPMI_WDOG_RESET_TIMER; msg.data = NULL; msg.data_len = 0; - atomic_add(1, &panic_done_count); + atomic_inc(&panic_done_count); rv = ipmi_request_supply_msgs(watchdog_user, (struct ipmi_addr *) &addr, 0, @@ -513,7 +513,7 @@ static void panic_halt_ipmi_heartbeat(void) &panic_halt_heartbeat_recv_msg, 1); if (rv) - atomic_sub(1, &panic_done_count); + atomic_dec(&panic_done_count); } static struct ipmi_smi_msg panic_halt_smi_msg = { @@ -537,12 +537,12 @@ static void panic_halt_ipmi_set_timeout(void) /* Wait for the messages to be free. */ while (atomic_read(&panic_done_count) != 0) ipmi_poll_interface(watchdog_user); - atomic_add(1, &panic_done_count); + atomic_inc(&panic_done_count); rv = __ipmi_set_timeout(&panic_halt_smi_msg, &panic_halt_recv_msg, &send_heartbeat_now); if (rv) { - atomic_sub(1, &panic_done_count); + atomic_dec(&panic_done_count); pr_warn("Unable to extend the watchdog timeout\n"); } else { if (send_heartbeat_now) From a4932a2c544607640ddab7f3275726e364a897bf Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 20 Sep 2021 06:25:37 -0500 Subject: [PATCH 0721/1017] ipmi:watchdog: Set panic count to proper value on a panic commit db05ddf7f321634c5659a0cf7ea56594e22365f7 upstream. You will get two decrements when the messages on a panic are sent, not one, since commit 2033f6858970 ("ipmi: Free receive messages when in an oops") was added, but the watchdog code had a bug where it didn't set the value properly. Reported-by: Anton Lundin Cc: # v5.4+ Fixes: 2033f6858970 ("ipmi: Free receive messages when in an oops") Signed-off-by: Corey Minyard Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_watchdog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 7f71471c7a46..883b4a341012 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -503,7 +503,7 @@ static void panic_halt_ipmi_heartbeat(void) msg.cmd = IPMI_WDOG_RESET_TIMER; msg.data = NULL; msg.data_len = 0; - atomic_inc(&panic_done_count); + atomic_add(2, &panic_done_count); rv = ipmi_request_supply_msgs(watchdog_user, (struct ipmi_addr *) &addr, 0, @@ -513,7 +513,7 @@ static void panic_halt_ipmi_heartbeat(void) &panic_halt_heartbeat_recv_msg, 1); if (rv) - atomic_dec(&panic_done_count); + atomic_sub(2, &panic_done_count); } static struct ipmi_smi_msg panic_halt_smi_msg = { @@ -537,12 +537,12 @@ static void panic_halt_ipmi_set_timeout(void) /* Wait for the messages to be free. */ while (atomic_read(&panic_done_count) != 0) ipmi_poll_interface(watchdog_user); - atomic_inc(&panic_done_count); + atomic_add(2, &panic_done_count); rv = __ipmi_set_timeout(&panic_halt_smi_msg, &panic_halt_recv_msg, &send_heartbeat_now); if (rv) { - atomic_dec(&panic_done_count); + atomic_sub(2, &panic_done_count); pr_warn("Unable to extend the watchdog timeout\n"); } else { if (send_heartbeat_now) From c53d50d8081a49ba21f866a51277a012b9efad8e Mon Sep 17 00:00:00 2001 From: Tao Liu Date: Tue, 14 Mar 2023 20:10:17 +0800 Subject: [PATCH 0722/1017] skbuff: Fix nfct leak on napi stolen Upstream commit [0] had fixed this issue, and backported to kernel 5.10.54. However, nf_reset_ct() added in skb_release_head_state() instead of napi_skb_free_stolen_head(), which lead to leakage still exist in 5.10. [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8550ff8d8c75416e984d9c4b082845e57e560984 Fixes: 570341f10ecc ("skbuff: Release nfct refcount on napi stolen or re-used skbs")) Signed-off-by: Tao Liu Signed-off-by: Greg Kroah-Hartman --- net/core/dev.c | 1 + net/core/skbuff.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 8cbcb6a104f2..413c2a08d79d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6111,6 +6111,7 @@ EXPORT_SYMBOL(gro_find_complete_by_type); static void napi_skb_free_stolen_head(struct sk_buff *skb) { + nf_reset_ct(skb); skb_dst_drop(skb); skb_ext_put(skb); kmem_cache_free(skbuff_head_cache, skb); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 668a9d0fbbc6..09cdefe5e1c8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -659,7 +659,6 @@ fastpath: void skb_release_head_state(struct sk_buff *skb) { - nf_reset_ct(skb); skb_dst_drop(skb); if (skb->destructor) { WARN_ON(in_irq()); From b5005605013d30ab27c303cbaeff60b7872234a3 Mon Sep 17 00:00:00 2001 From: John Harrison Date: Wed, 15 Feb 2023 17:11:01 -0800 Subject: [PATCH 0723/1017] drm/i915: Don't use BAR mappings for ring buffers with LLC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 85636167e3206c3fbd52254fc432991cc4e90194 upstream. Direction from hardware is that ring buffers should never be mapped via the BAR on systems with LLC. There are too many caching pitfalls due to the way BAR accesses are routed. So it is safest to just not use it. Signed-off-by: John Harrison Fixes: 9d80841ea4c9 ("drm/i915: Allow ringbuffers to be bound anywhere") Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: intel-gfx@lists.freedesktop.org Cc: # v4.9+ Tested-by: Jouni Högander Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20230216011101.1909009-3-John.C.Harrison@Intel.com (cherry picked from commit 65c08339db1ada87afd6cfe7db8e60bb4851d919) Signed-off-by: Jani Nikula Signed-off-by: John Harrison Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/gt/intel_ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c index 4034a4bac7f0..69b2e5509d67 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring.c +++ b/drivers/gpu/drm/i915/gt/intel_ring.c @@ -49,7 +49,7 @@ int intel_ring_pin(struct intel_ring *ring, struct i915_gem_ww_ctx *ww) if (unlikely(ret)) goto err_unpin; - if (i915_vma_is_map_and_fenceable(vma)) + if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915)) addr = (void __force *)i915_vma_pin_iomap(vma); else addr = i915_gem_object_pin_map(vma->obj, @@ -91,7 +91,7 @@ void intel_ring_unpin(struct intel_ring *ring) return; i915_vma_unset_ggtt_write(vma); - if (i915_vma_is_map_and_fenceable(vma)) + if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915)) i915_vma_unpin_iomap(vma); else i915_gem_object_unpin_map(vma->obj); From 9cd21f5babb51e0eccb4bd18db890419971fe9d3 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Wed, 16 Feb 2022 12:32:45 +0530 Subject: [PATCH 0724/1017] ext4: refactor ext4_free_blocks() to pull out ext4_mb_clear_bb() commit 8ac3939db99f99667b8eb670cf4baf292896e72d upstream. ext4_free_blocks() function became too long and confusing, this patch just pulls out the ext4_mb_clear_bb() function logic from it which clears the block bitmap and frees it. No functionality change in this patch Signed-off-by: Ritesh Harjani Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/22c30fbb26ba409cf8aa5f0c7912970272c459e8.1644992610.git.riteshh@linux.ibm.com Signed-off-by: Theodore Ts'o Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman --- fs/ext4/mballoc.c | 180 ++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 78 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index d5ca02a7766e..0870f0436946 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -5303,7 +5303,8 @@ static void ext4_free_blocks_simple(struct inode *inode, ext4_fsblk_t block, } /** - * ext4_free_blocks() -- Free given blocks and update quota + * ext4_mb_clear_bb() -- helper function for freeing blocks. + * Used by ext4_free_blocks() * @handle: handle for this transaction * @inode: inode * @bh: optional buffer of the block to be freed @@ -5311,9 +5312,9 @@ static void ext4_free_blocks_simple(struct inode *inode, ext4_fsblk_t block, * @count: number of blocks to be freed * @flags: flags used by ext4_free_blocks */ -void ext4_free_blocks(handle_t *handle, struct inode *inode, - struct buffer_head *bh, ext4_fsblk_t block, - unsigned long count, int flags) +static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode, + ext4_fsblk_t block, unsigned long count, + int flags) { struct buffer_head *bitmap_bh = NULL; struct super_block *sb = inode->i_sb; @@ -5330,80 +5331,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, sbi = EXT4_SB(sb); - if (sbi->s_mount_state & EXT4_FC_REPLAY) { - ext4_free_blocks_simple(inode, block, count); - return; - } - - might_sleep(); - if (bh) { - if (block) - BUG_ON(block != bh->b_blocknr); - else - block = bh->b_blocknr; - } - - if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && - !ext4_inode_block_valid(inode, block, count)) { - ext4_error(sb, "Freeing blocks not in datazone - " - "block = %llu, count = %lu", block, count); - goto error_return; - } - - ext4_debug("freeing block %llu\n", block); - trace_ext4_free_blocks(inode, block, count, flags); - - if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { - BUG_ON(count > 1); - - ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA, - inode, bh, block); - } - - /* - * If the extent to be freed does not begin on a cluster - * boundary, we need to deal with partial clusters at the - * beginning and end of the extent. Normally we will free - * blocks at the beginning or the end unless we are explicitly - * requested to avoid doing so. - */ - overflow = EXT4_PBLK_COFF(sbi, block); - if (overflow) { - if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) { - overflow = sbi->s_cluster_ratio - overflow; - block += overflow; - if (count > overflow) - count -= overflow; - else - return; - } else { - block -= overflow; - count += overflow; - } - } - overflow = EXT4_LBLK_COFF(sbi, count); - if (overflow) { - if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) { - if (count > overflow) - count -= overflow; - else - return; - } else - count += sbi->s_cluster_ratio - overflow; - } - - if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { - int i; - int is_metadata = flags & EXT4_FREE_BLOCKS_METADATA; - - for (i = 0; i < count; i++) { - cond_resched(); - if (is_metadata) - bh = sb_find_get_block(inode->i_sb, block + i); - ext4_forget(handle, is_metadata, inode, bh, block + i); - } - } - do_more: overflow = 0; ext4_get_group_no_and_offset(sb, block, &block_group, &bit); @@ -5570,6 +5497,103 @@ error_return: return; } +/** + * ext4_free_blocks() -- Free given blocks and update quota + * @handle: handle for this transaction + * @inode: inode + * @bh: optional buffer of the block to be freed + * @block: starting physical block to be freed + * @count: number of blocks to be freed + * @flags: flags used by ext4_free_blocks + */ +void ext4_free_blocks(handle_t *handle, struct inode *inode, + struct buffer_head *bh, ext4_fsblk_t block, + unsigned long count, int flags) +{ + struct super_block *sb = inode->i_sb; + unsigned int overflow; + struct ext4_sb_info *sbi; + + sbi = EXT4_SB(sb); + + if (sbi->s_mount_state & EXT4_FC_REPLAY) { + ext4_free_blocks_simple(inode, block, count); + return; + } + + might_sleep(); + if (bh) { + if (block) + BUG_ON(block != bh->b_blocknr); + else + block = bh->b_blocknr; + } + + if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && + !ext4_inode_block_valid(inode, block, count)) { + ext4_error(sb, "Freeing blocks not in datazone - " + "block = %llu, count = %lu", block, count); + return; + } + + ext4_debug("freeing block %llu\n", block); + trace_ext4_free_blocks(inode, block, count, flags); + + if (bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { + BUG_ON(count > 1); + + ext4_forget(handle, flags & EXT4_FREE_BLOCKS_METADATA, + inode, bh, block); + } + + /* + * If the extent to be freed does not begin on a cluster + * boundary, we need to deal with partial clusters at the + * beginning and end of the extent. Normally we will free + * blocks at the beginning or the end unless we are explicitly + * requested to avoid doing so. + */ + overflow = EXT4_PBLK_COFF(sbi, block); + if (overflow) { + if (flags & EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER) { + overflow = sbi->s_cluster_ratio - overflow; + block += overflow; + if (count > overflow) + count -= overflow; + else + return; + } else { + block -= overflow; + count += overflow; + } + } + overflow = EXT4_LBLK_COFF(sbi, count); + if (overflow) { + if (flags & EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER) { + if (count > overflow) + count -= overflow; + else + return; + } else + count += sbi->s_cluster_ratio - overflow; + } + + if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { + int i; + int is_metadata = flags & EXT4_FREE_BLOCKS_METADATA; + + for (i = 0; i < count; i++) { + cond_resched(); + if (is_metadata) + bh = sb_find_get_block(inode->i_sb, block + i); + ext4_forget(handle, is_metadata, inode, bh, block + i); + } + } + + ext4_mb_clear_bb(handle, inode, block, count, flags); + return; +} + /** * ext4_group_add_blocks() -- Add given blocks to an existing group * @handle: handle to this transaction From 65061f49a50f8a303af61e9328e94a6c51ea4ab1 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Wed, 16 Feb 2022 12:32:49 +0530 Subject: [PATCH 0725/1017] ext4: add ext4_sb_block_valid() refactored out of ext4_inode_block_valid() commit 6bc6c2bdf1baca6522b8d9ba976257d722423085 upstream. This API will be needed at places where we don't have an inode for e.g. while freeing blocks in ext4_group_add_blocks() Suggested-by: Jan Kara Signed-off-by: Ritesh Harjani Link: https://lore.kernel.org/r/dd34a236543ad5ae7123eeebe0cb69e6bdd44f34.1644992610.git.riteshh@linux.ibm.com Signed-off-by: Theodore Ts'o Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman --- fs/ext4/block_validity.c | 26 +++++++++++++++++--------- fs/ext4/ext4.h | 3 +++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 8e6ca23ed172..eed5b855dd94 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -294,15 +294,10 @@ void ext4_release_system_zone(struct super_block *sb) call_rcu(&system_blks->rcu, ext4_destroy_system_zone); } -/* - * Returns 1 if the passed-in block region (start_blk, - * start_blk+count) is valid; 0 if some part of the block region - * overlaps with some other filesystem metadata blocks. - */ -int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk, - unsigned int count) +int ext4_sb_block_valid(struct super_block *sb, struct inode *inode, + ext4_fsblk_t start_blk, unsigned int count) { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_system_blocks *system_blks; struct ext4_system_zone *entry; struct rb_node *n; @@ -331,7 +326,9 @@ int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk, else if (start_blk >= (entry->start_blk + entry->count)) n = n->rb_right; else { - ret = (entry->ino == inode->i_ino); + ret = 0; + if (inode) + ret = (entry->ino == inode->i_ino); break; } } @@ -340,6 +337,17 @@ out_rcu: return ret; } +/* + * Returns 1 if the passed-in block region (start_blk, + * start_blk+count) is valid; 0 if some part of the block region + * overlaps with some other filesystem metadata blocks. + */ +int ext4_inode_block_valid(struct inode *inode, ext4_fsblk_t start_blk, + unsigned int count) +{ + return ext4_sb_block_valid(inode->i_sb, inode, start_blk, count); +} + int ext4_check_blockref(const char *function, unsigned int line, struct inode *inode, __le32 *p, unsigned int max) { diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 81dc61f1c557..246573a4e804 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3536,6 +3536,9 @@ extern int ext4_inode_block_valid(struct inode *inode, unsigned int count); extern int ext4_check_blockref(const char *, unsigned int, struct inode *, __le32 *, unsigned int); +extern int ext4_sb_block_valid(struct super_block *sb, struct inode *inode, + ext4_fsblk_t start_blk, unsigned int count); + /* extents.c */ struct ext4_ext_path; From c3fd717b58f0a3e2461c16e2360ee6a949b47940 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Wed, 16 Feb 2022 12:32:50 +0530 Subject: [PATCH 0726/1017] ext4: add strict range checks while freeing blocks commit a00b482b82fb098956a5bed22bd7873e56f152f1 upstream. Currently ext4_mb_clear_bb() & ext4_group_add_blocks() only checks whether the given block ranges (which is to be freed) belongs to any FS metadata blocks or not, of the block's respective block group. But to detect any FS error early, it is better to add more strict checkings in those functions which checks whether the given blocks belongs to any critical FS metadata or not within system-zone. Suggested-by: Jan Kara Signed-off-by: Ritesh Harjani Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/ddd9143d064774e32d6364a99667817c6e8bfdc0.1644992610.git.riteshh@linux.ibm.com Signed-off-by: Theodore Ts'o Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman --- fs/ext4/mballoc.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 0870f0436946..b98d77c8b002 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -5361,13 +5361,7 @@ do_more: goto error_return; } - if (in_range(ext4_block_bitmap(sb, gdp), block, count) || - in_range(ext4_inode_bitmap(sb, gdp), block, count) || - in_range(block, ext4_inode_table(sb, gdp), - sbi->s_itb_per_group) || - in_range(block + count - 1, ext4_inode_table(sb, gdp), - sbi->s_itb_per_group)) { - + if (!ext4_inode_block_valid(inode, block, count)) { ext4_error(sb, "Freeing blocks in system zone - " "Block = %llu, count = %lu", block, count); /* err = 0. ext4_std_error should be a no op */ @@ -5437,7 +5431,7 @@ do_more: NULL); if (err && err != -EOPNOTSUPP) ext4_msg(sb, KERN_WARNING, "discard request in" - " group:%d block:%d count:%lu failed" + " group:%u block:%d count:%lu failed" " with %d", block_group, bit, count, err); } else @@ -5650,11 +5644,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, goto error_return; } - if (in_range(ext4_block_bitmap(sb, desc), block, count) || - in_range(ext4_inode_bitmap(sb, desc), block, count) || - in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || - in_range(block + count - 1, ext4_inode_table(sb, desc), - sbi->s_itb_per_group)) { + if (!ext4_sb_block_valid(sb, NULL, block, count)) { ext4_error(sb, "Adding blocks in system zones - " "Block = %llu, count = %lu", block, count); From 7550aade978371ac582f6d43b14c4cb89ca54463 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Thu, 14 Jul 2022 18:59:03 +0200 Subject: [PATCH 0727/1017] ext4: block range must be validated before use in ext4_mb_clear_bb() commit 1e1c2b86ef86a8477fd9b9a4f48a6bfe235606f6 upstream. Block range to free is validated in ext4_free_blocks() using ext4_inode_block_valid() and then it's passed to ext4_mb_clear_bb(). However in some situations on bigalloc file system the range might be adjusted after the validation in ext4_free_blocks() which can lead to troubles on corrupted file systems such as one found by syzkaller that resulted in the following BUG kernel BUG at fs/ext4/ext4.h:3319! PREEMPT SMP NOPTI CPU: 28 PID: 4243 Comm: repro Kdump: loaded Not tainted 5.19.0-rc6+ #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1.fc35 04/01/2014 RIP: 0010:ext4_free_blocks+0x95e/0xa90 Call Trace: ? lock_timer_base+0x61/0x80 ? __es_remove_extent+0x5a/0x760 ? __mod_timer+0x256/0x380 ? ext4_ind_truncate_ensure_credits+0x90/0x220 ext4_clear_blocks+0x107/0x1b0 ext4_free_data+0x15b/0x170 ext4_ind_truncate+0x214/0x2c0 ? _raw_spin_unlock+0x15/0x30 ? ext4_discard_preallocations+0x15a/0x410 ? ext4_journal_check_start+0xe/0x90 ? __ext4_journal_start_sb+0x2f/0x110 ext4_truncate+0x1b5/0x460 ? __ext4_journal_start_sb+0x2f/0x110 ext4_evict_inode+0x2b4/0x6f0 evict+0xd0/0x1d0 ext4_enable_quotas+0x11f/0x1f0 ext4_orphan_cleanup+0x3de/0x430 ? proc_create_seq_private+0x43/0x50 ext4_fill_super+0x295f/0x3ae0 ? snprintf+0x39/0x40 ? sget_fc+0x19c/0x330 ? ext4_reconfigure+0x850/0x850 get_tree_bdev+0x16d/0x260 vfs_get_tree+0x25/0xb0 path_mount+0x431/0xa70 __x64_sys_mount+0xe2/0x120 do_syscall_64+0x5b/0x80 ? do_user_addr_fault+0x1e2/0x670 ? exc_page_fault+0x70/0x170 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x7fdf4e512ace Fix it by making sure that the block range is properly validated before used every time it changes in ext4_free_blocks() or ext4_mb_clear_bb(). Link: https://syzkaller.appspot.com/bug?id=5266d464285a03cee9dbfda7d2452a72c3c2ae7c Reported-by: syzbot+15cd994e273307bf5cfa@syzkaller.appspotmail.com Signed-off-by: Lukas Czerner Cc: Tadeusz Struk Tested-by: Tadeusz Struk Link: https://lore.kernel.org/r/20220714165903.58260-1-lczerner@redhat.com Signed-off-by: Theodore Ts'o Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman --- fs/ext4/mballoc.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b98d77c8b002..843840c2aced 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -5331,6 +5331,15 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode, sbi = EXT4_SB(sb); + if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && + !ext4_inode_block_valid(inode, block, count)) { + ext4_error(sb, "Freeing blocks in system zone - " + "Block = %llu, count = %lu", block, count); + /* err = 0. ext4_std_error should be a no op */ + goto error_return; + } + flags |= EXT4_FREE_BLOCKS_VALIDATED; + do_more: overflow = 0; ext4_get_group_no_and_offset(sb, block, &block_group, &bit); @@ -5347,6 +5356,8 @@ do_more: overflow = EXT4_C2B(sbi, bit) + count - EXT4_BLOCKS_PER_GROUP(sb); count -= overflow; + /* The range changed so it's no longer validated */ + flags &= ~EXT4_FREE_BLOCKS_VALIDATED; } count_clusters = EXT4_NUM_B2C(sbi, count); bitmap_bh = ext4_read_block_bitmap(sb, block_group); @@ -5361,7 +5372,8 @@ do_more: goto error_return; } - if (!ext4_inode_block_valid(inode, block, count)) { + if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && + !ext4_inode_block_valid(inode, block, count)) { ext4_error(sb, "Freeing blocks in system zone - " "Block = %llu, count = %lu", block, count); /* err = 0. ext4_std_error should be a no op */ @@ -5483,6 +5495,8 @@ do_more: block += count; count = overflow; put_bh(bitmap_bh); + /* The range changed so it's no longer validated */ + flags &= ~EXT4_FREE_BLOCKS_VALIDATED; goto do_more; } error_return: @@ -5529,6 +5543,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, "block = %llu, count = %lu", block, count); return; } + flags |= EXT4_FREE_BLOCKS_VALIDATED; ext4_debug("freeing block %llu\n", block); trace_ext4_free_blocks(inode, block, count, flags); @@ -5560,6 +5575,8 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, block -= overflow; count += overflow; } + /* The range changed so it's no longer validated */ + flags &= ~EXT4_FREE_BLOCKS_VALIDATED; } overflow = EXT4_LBLK_COFF(sbi, count); if (overflow) { @@ -5570,6 +5587,8 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, return; } else count += sbi->s_cluster_ratio - overflow; + /* The range changed so it's no longer validated */ + flags &= ~EXT4_FREE_BLOCKS_VALIDATED; } if (!bh && (flags & EXT4_FREE_BLOCKS_FORGET)) { From d367c5ebe94359b0ac38c0d91c4c10654460bb03 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 1 Mar 2023 19:04:52 -0700 Subject: [PATCH 0728/1017] arch: fix broken BuildID for arm64 and riscv commit 99cb0d917ffa1ab628bb67364ca9b162c07699b1 upstream. Dennis Gilmore reports that the BuildID is missing in the arm64 vmlinux since commit 994b7ac1697b ("arm64: remove special treatment for the link order of head.o"). The issue is that the type of .notes section, which contains the BuildID, changed from NOTES to PROGBITS. Ard Biesheuvel figured out that whichever object gets linked first gets to decide the type of a section. The PROGBITS type is the result of the compiler emitting .note.GNU-stack as PROGBITS rather than NOTE. While Ard provided a fix for arm64, I want to fix this globally because the same issue is happening on riscv since commit 2348e6bf4421 ("riscv: remove special treatment for the link order of head.o"). This problem will happen in general for other architectures if they start to drop unneeded entries from scripts/head-object-list.txt. Discard .note.GNU-stack in include/asm-generic/vmlinux.lds.h. Link: https://lore.kernel.org/lkml/CAABkxwuQoz1CTbyb57n0ZX65eSYiTonFCU8-LCQc=74D=xE=rA@mail.gmail.com/ Fixes: 994b7ac1697b ("arm64: remove special treatment for the link order of head.o") Fixes: 2348e6bf4421 ("riscv: remove special treatment for the link order of head.o") Reported-by: Dennis Gilmore Suggested-by: Ard Biesheuvel Signed-off-by: Masahiro Yamada Acked-by: Palmer Dabbelt [Tom: stable backport 5.15.y, 5.10.y, 5.4.y] Though the above "Fixes:" commits are not in this kernel, the conditions which lead to a missing Build ID in arm64 vmlinux are similar. Evidence points to these conditions: 1. ld version > 2.36 (exact binutils commit documented in a494398bde27) 2. first object which gets linked (head.o) has a PROGBITS .note.GNU-stack segment These conditions can be observed when: - 5.15.60+ OR 5.10.136+ OR 5.4.210+ - AND ld version > 2.36 - AND arch=arm64 - AND CONFIG_MODVERSIONS=y There are notable differences in the vmlinux elf files produced before(bad) and after(good) applying this series. Good: p_type:PT_NOTE segment exists. Bad: p_type:PT_NOTE segment is missing. Good: sh_name_str:.notes section has sh_type:SHT_NOTE Bad: sh_name_str:.notes section has sh_type:SHT_PROGBITS `readelf -n` (as of v2.40) searches for Build Id by processing only the very first note in sh_type:SHT_NOTE sections. This was previously bisected to the stable backport of 0d362be5b142. Follow-up experiments were discussed here: https://lore.kernel.org/all/20221221235413.xaisboqmr7dkqwn6@oracle.com/ which strongly hints at condition 2. Signed-off-by: Tom Saeger Signed-off-by: Greg Kroah-Hartman --- include/asm-generic/vmlinux.lds.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index d233f9e4b9c6..44103f9487c9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -906,7 +906,12 @@ #define TRACEDATA #endif +/* + * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler. + * Otherwise, the type of .notes section would become PROGBITS instead of NOTES. + */ #define NOTES \ + /DISCARD/ : { *(.note.GNU-stack) } \ .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ __start_notes = .; \ KEEP(*(.note.*)) \ From af560685bad5f182a2ca00b82774081f71939c86 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 1 Mar 2023 19:04:53 -0700 Subject: [PATCH 0729/1017] powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT commit 4b9880dbf3bdba3a7c56445137c3d0e30aaa0a40 upstream. The powerpc linker script explicitly includes .exit.text, because otherwise the link fails due to references from __bug_table and __ex_table. The code is freed (discarded) at runtime along with .init.text and data. That has worked in the past despite powerpc not defining RUNTIME_DISCARD_EXIT because DISCARDS appears late in the powerpc linker script (line 410), and the explicit inclusion of .exit.text earlier (line 280) supersedes the discard. However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") introduced an earlier use of DISCARD as part of the RO_DATA macro (line 136). With binutils < 2.36 that causes the DISCARD directives later in the script to be applied earlier [1], causing .exit.text to actually be discarded at link time, leading to build errors: '.exit.text' referenced in section '__bug_table' of crypto/algboss.o: defined in discarded section '.exit.text' of crypto/algboss.o '.exit.text' referenced in section '__ex_table' of drivers/nvdimm/core.o: defined in discarded section '.exit.text' of drivers/nvdimm/core.o Fix it by defining RUNTIME_DISCARD_EXIT, which causes the generic DISCARDS macro to not include .exit.text at all. 1: https://lore.kernel.org/lkml/87fscp2v7k.fsf@igel.home/ Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230105132349.384666-1-mpe@ellerman.id.au Signed-off-by: Tom Saeger Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 4a1f494ef03f..e3984389f8ef 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -8,6 +8,7 @@ #define BSS_FIRST_SECTIONS *(.bss.prominit) #define EMITS_PT_NOTE #define RO_EXCEPTION_TABLE_ALIGN 0 +#define RUNTIME_DISCARD_EXIT #include #include From 6af633e7782c85d6522fe44ef8a97632725fa5fe Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 1 Mar 2023 19:04:54 -0700 Subject: [PATCH 0730/1017] powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds commit 07b050f9290ee012a407a0f64151db902a1520f5 upstream. Relocatable kernels must not discard relocations, they need to be processed at runtime. As such they are included for CONFIG_RELOCATABLE builds in the powerpc linker script (line 340). However they are also unconditionally discarded later in the script (line 414). Previously that worked because the earlier inclusion superseded the discard. However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") introduced an earlier use of DISCARD as part of the RO_DATA macro (line 137). With binutils < 2.36 that causes the DISCARD directives later in the script to be applied earlier, causing .rela* to actually be discarded at link time, leading to build warnings and a kernel that doesn't boot: ld: warning: discarding dynamic section .rela.init.rodata Fix it by conditionally discarding .rela* only when CONFIG_RELOCATABLE is disabled. Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20230105132349.384666-2-mpe@ellerman.id.au Signed-off-by: Tom Saeger Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/vmlinux.lds.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index e3984389f8ef..fabe6cf10bd2 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -379,9 +379,12 @@ SECTIONS DISCARDS /DISCARD/ : { *(*.EMB.apuinfo) - *(.glink .iplt .plt .rela* .comment) + *(.glink .iplt .plt .comment) *(.gnu.version*) *(.gnu.attributes) *(.eh_frame) +#ifndef CONFIG_RELOCATABLE + *(.rela*) +#endif } } From bfef72d2fc62c194a36f271917ff1240f45d0f2f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 1 Mar 2023 19:04:55 -0700 Subject: [PATCH 0731/1017] s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36 commit a494398bde273143c2352dd373cad8211f7d94b2 upstream. Nathan Chancellor reports that the s390 vmlinux fails to link with GNU ld < 2.36 since commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv"). It happens for defconfig, or more specifically for CONFIG_EXPOLINE=y. $ s390x-linux-gnu-ld --version | head -n1 GNU ld (GNU Binutils for Debian) 2.35.2 $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- allnoconfig $ ./scripts/config -e CONFIG_EXPOLINE $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- `.exit.text' referenced in section `.s390_return_reg' of drivers/base/dd.o: defined in discarded section `.exit.text' of drivers/base/dd.o make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1 make: *** [Makefile:1252: vmlinux] Error 2 arch/s390/kernel/vmlinux.lds.S wants to keep EXIT_TEXT: .exit.text : { EXIT_TEXT } But, at the same time, EXIT_TEXT is thrown away by DISCARD because s390 does not define RUNTIME_DISCARD_EXIT. I still do not understand why the latter wins after 99cb0d917ffa, but defining RUNTIME_DISCARD_EXIT seems correct because the comment line in arch/s390/kernel/vmlinux.lds.S says: /* * .exit.text is discarded at runtime, not link time, * to deal with references from __bug_table */ Nathan also found that binutils commit 21401fc7bf67 ("Duplicate output sections in scripts") cured this issue, so we cannot reproduce it with binutils 2.36+, but it is better to not rely on it. Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/ Reported-by: Nathan Chancellor Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20230105031306.1455409-1-masahiroy@kernel.org Signed-off-by: Heiko Carstens Signed-off-by: Tom Saeger Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index d7291eb0d0c0..1c65c38ec9a3 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -15,6 +15,8 @@ /* Handle ro_after_init data on our own. */ #define RO_AFTER_INIT_DATA +#define RUNTIME_DISCARD_EXIT + #define EMITS_PT_NOTE #include From 5c425eb9da8ace13cecd18e705b0ed65923927f4 Mon Sep 17 00:00:00 2001 From: Tom Saeger Date: Wed, 1 Mar 2023 19:04:56 -0700 Subject: [PATCH 0732/1017] sh: define RUNTIME_DISCARD_EXIT commit c1c551bebf928889e7a8fef7415b44f9a64975f4 upstream. sh vmlinux fails to link with GNU ld < 2.40 (likely < 2.36) since commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv"). This is similar to fixes for powerpc and s390: commit 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT"). commit a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36"). $ sh4-linux-gnu-ld --version | head -n1 GNU ld (GNU Binutils for Debian) 2.35.2 $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu- microdev_defconfig $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu- `.exit.text' referenced in section `__bug_table' of crypto/algboss.o: defined in discarded section `.exit.text' of crypto/algboss.o `.exit.text' referenced in section `__bug_table' of drivers/char/hw_random/core.o: defined in discarded section `.exit.text' of drivers/char/hw_random/core.o make[2]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1 make[1]: *** [Makefile:1252: vmlinux] Error 2 arch/sh/kernel/vmlinux.lds.S keeps EXIT_TEXT: /* * .exit.text is discarded at runtime, not link time, to deal with * references from __bug_table */ .exit.text : AT(ADDR(.exit.text)) { EXIT_TEXT } However, EXIT_TEXT is thrown away by DISCARD(include/asm-generic/vmlinux.lds.h) because sh does not define RUNTIME_DISCARD_EXIT. GNU ld 2.40 does not have this issue and builds fine. This corresponds with Masahiro's comments in a494398bde27: "Nathan [Chancellor] also found that binutils commit 21401fc7bf67 ("Duplicate output sections in scripts") cured this issue, so we cannot reproduce it with binutils 2.36+, but it is better to not rely on it." Link: https://lkml.kernel.org/r/9166a8abdc0f979e50377e61780a4bba1dfa2f52.1674518464.git.tom.saeger@oracle.com Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/ Link: https://lore.kernel.org/all/20230123194218.47ssfzhrpnv3xfez@oracle.com/ Signed-off-by: Tom Saeger Tested-by: John Paul Adrian Glaubitz Cc: Ard Biesheuvel Cc: Arnd Bergmann Cc: Christoph Hellwig Cc: Dennis Gilmore Cc: Greg Kroah-Hartman Cc: Masahiro Yamada Cc: Naresh Kamboju Cc: Nathan Chancellor Cc: Palmer Dabbelt Cc: Rich Felker Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Tom Saeger Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 3161b9ccd2a5..b6276a3521d7 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -4,6 +4,7 @@ * Written by Niibe Yutaka and Paul Mundt */ OUTPUT_ARCH(sh) +#define RUNTIME_DISCARD_EXIT #include #include #include From 9da269bee7ead0922dc091475e525cbe21cbdfa8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Feb 2023 01:41:56 +0900 Subject: [PATCH 0733/1017] UML: define RUNTIME_DISCARD_EXIT commit b99ddbe8336ee680257c8ab479f75051eaa49dcf upstream. With CONFIG_VIRTIO_UML=y, GNU ld < 2.36 fails to link UML vmlinux (w/wo CONFIG_LD_SCRIPT_STATIC). `.exit.text' referenced in section `.uml.exitcall.exit' of arch/um/drivers/virtio_uml.o: defined in discarded section `.exit.text' of arch/um/drivers/virtio_uml.o collect2: error: ld returned 1 exit status This fix is similar to the following commits: - 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT") - a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36") - c1c551bebf92 ("sh: define RUNTIME_DISCARD_EXIT") Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv") Reported-by: SeongJae Park Signed-off-by: Masahiro Yamada Tested-by: SeongJae Park Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- arch/um/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index 16e49bfa2b42..53d719c04ba9 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,4 +1,4 @@ - +#define RUNTIME_DISCARD_EXIT KERNEL_STACK_SIZE = 4096 * (1 << CONFIG_KERNEL_STACK_ORDER); #ifdef CONFIG_LD_SCRIPT_STATIC From 0ef55bafabb9ebf45bf5cdfaeabdc37d206e7624 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 29 Nov 2021 10:47:01 +0100 Subject: [PATCH 0734/1017] KVM: nVMX: Don't use Enlightened MSR Bitmap for L3 commit 250552b925ce400c17d166422fde9bb215958481 upstream. When KVM runs as a nested hypervisor on top of Hyper-V it uses Enlightened VMCS and enables Enlightened MSR Bitmap feature for its L1s and L2s (which are actually L2s and L3s from Hyper-V's perspective). When MSR bitmap is updated, KVM has to reset HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP from clean fields to make Hyper-V aware of the change. For KVM's L1s, this is done in vmx_disable_intercept_for_msr()/vmx_enable_intercept_for_msr(). MSR bitmap for L2 is build in nested_vmx_prepare_msr_bitmap() by blending MSR bitmap for L1 and L1's idea of MSR bitmap for L2. KVM, however, doesn't check if the resulting bitmap is different and never cleans HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP in eVMCS02. This is incorrect and may result in Hyper-V missing the update. The issue could've been solved by calling evmcs_touch_msr_bitmap() for eVMCS02 from nested_vmx_prepare_msr_bitmap() unconditionally but doing so would not give any performance benefits (compared to not using Enlightened MSR Bitmap at all). 3-level nesting is also not a very common setup nowadays. Don't enable 'Enlightened MSR Bitmap' feature for KVM's L2s (real L3s) for now. Signed-off-by: Vitaly Kuznetsov Message-Id: <20211129094704.326635-2-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Alexandru Matei Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/vmx.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index c37cbd3fdd85..eefd6387a99d 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2725,15 +2725,6 @@ int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs) if (!loaded_vmcs->msr_bitmap) goto out_vmcs; memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE); - - if (IS_ENABLED(CONFIG_HYPERV) && - static_branch_unlikely(&enable_evmcs) && - (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) { - struct hv_enlightened_vmcs *evmcs = - (struct hv_enlightened_vmcs *)loaded_vmcs->vmcs; - - evmcs->hv_enlightenments_control.msr_bitmap = 1; - } } memset(&loaded_vmcs->host_state, 0, sizeof(struct vmcs_host_state)); @@ -7029,6 +7020,19 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) if (err < 0) goto free_pml; + /* + * Use Hyper-V 'Enlightened MSR Bitmap' feature when KVM runs as a + * nested (L1) hypervisor and Hyper-V in L0 supports it. Enable the + * feature only for vmcs01, KVM currently isn't equipped to realize any + * performance benefits from enabling it for vmcs02. + */ + if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs) && + (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) { + struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs; + + evmcs->hv_enlightenments_control.msr_bitmap = 1; + } + /* The MSR bitmap starts with all ones */ bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS); bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS); From 685ed0a277f16881090891988b4d93257f8caf3c Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 29 Nov 2021 10:47:02 +0100 Subject: [PATCH 0735/1017] KVM: VMX: Introduce vmx_msr_bitmap_l01_changed() helper commit b84155c38076b36d625043a06a2f1c90bde62903 upstream. In preparation to enabling 'Enlightened MSR Bitmap' feature for Hyper-V guests move MSR bitmap update tracking to a dedicated helper. Note: vmx_msr_bitmap_l01_changed() is called when MSR bitmap might be updated. KVM doesn't check if the bit we're trying to set is already set (or the bit it's trying to clear is already cleared). Such situations should not be common and a few false positives should not be a problem. No functional change intended. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Maxim Levitsky Reviewed-by: Sean Christopherson Message-Id: <20211129094704.326635-3-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Alexandru Matei Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/vmx.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index eefd6387a99d..ee05c0e1cb2a 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3785,6 +3785,17 @@ static void vmx_set_msr_bitmap_write(ulong *msr_bitmap, u32 msr) __set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); } +static void vmx_msr_bitmap_l01_changed(struct vcpu_vmx *vmx) +{ + /* + * When KVM is a nested hypervisor on top of Hyper-V and uses + * 'Enlightened MSR Bitmap' feature L0 needs to know that MSR + * bitmap has changed. + */ + if (static_branch_unlikely(&enable_evmcs)) + evmcs_touch_msr_bitmap(); +} + static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type) { @@ -3794,8 +3805,7 @@ static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, if (!cpu_has_vmx_msr_bitmap()) return; - if (static_branch_unlikely(&enable_evmcs)) - evmcs_touch_msr_bitmap(); + vmx_msr_bitmap_l01_changed(vmx); /* * Mark the desired intercept state in shadow bitmap, this is needed @@ -3840,8 +3850,7 @@ static __always_inline void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, if (!cpu_has_vmx_msr_bitmap()) return; - if (static_branch_unlikely(&enable_evmcs)) - evmcs_touch_msr_bitmap(); + vmx_msr_bitmap_l01_changed(vmx); /* * Mark the desired intercept state in shadow bitmap, this is needed From 6baebcecf09acd19e2bab1c2911dcdba5d48a1dc Mon Sep 17 00:00:00 2001 From: Alexandru Matei Date: Tue, 24 Jan 2023 00:12:08 +0200 Subject: [PATCH 0736/1017] KVM: VMX: Fix crash due to uninitialized current_vmcs commit 93827a0a36396f2fd6368a54a020f420c8916e9b upstream. KVM enables 'Enlightened VMCS' and 'Enlightened MSR Bitmap' when running as a nested hypervisor on top of Hyper-V. When MSR bitmap is updated, evmcs_touch_msr_bitmap function uses current_vmcs per-cpu variable to mark that the msr bitmap was changed. vmx_vcpu_create() modifies the msr bitmap via vmx_disable_intercept_for_msr -> vmx_msr_bitmap_l01_changed which in the end calls this function. The function checks for current_vmcs if it is null but the check is insufficient because current_vmcs is not initialized. Because of this, the code might incorrectly write to the structure pointed by current_vmcs value left by another task. Preemption is not disabled, the current task can be preempted and moved to another CPU while current_vmcs is accessed multiple times from evmcs_touch_msr_bitmap() which leads to crash. The manipulation of MSR bitmaps by callers happens only for vmcs01 so the solution is to use vmx->vmcs01.vmcs instead of current_vmcs. BUG: kernel NULL pointer dereference, address: 0000000000000338 PGD 4e1775067 P4D 0 Oops: 0002 [#1] PREEMPT SMP NOPTI ... RIP: 0010:vmx_msr_bitmap_l01_changed+0x39/0x50 [kvm_intel] ... Call Trace: vmx_disable_intercept_for_msr+0x36/0x260 [kvm_intel] vmx_vcpu_create+0xe6/0x540 [kvm_intel] kvm_arch_vcpu_create+0x1d1/0x2e0 [kvm] kvm_vm_ioctl_create_vcpu+0x178/0x430 [kvm] kvm_vm_ioctl+0x53f/0x790 [kvm] __x64_sys_ioctl+0x8a/0xc0 do_syscall_64+0x5c/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: ceef7d10dfb6 ("KVM: x86: VMX: hyper-v: Enlightened MSR-Bitmap support") Cc: stable@vger.kernel.org Suggested-by: Sean Christopherson Signed-off-by: Alexandru Matei Link: https://lore.kernel.org/r/20230123221208.4964-1-alexandru.matei@uipath.com Signed-off-by: Sean Christopherson [manual backport: evmcs.h got renamed to hyperv.h in a later version, modified in evmcs.h instead] Signed-off-by: Alexandru Matei Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/evmcs.h | 11 ----------- arch/x86/kvm/vmx/vmx.c | 9 +++++++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h index 011929a63823..9180155d5d89 100644 --- a/arch/x86/kvm/vmx/evmcs.h +++ b/arch/x86/kvm/vmx/evmcs.h @@ -166,16 +166,6 @@ static inline u16 evmcs_read16(unsigned long field) return *(u16 *)((char *)current_evmcs + offset); } -static inline void evmcs_touch_msr_bitmap(void) -{ - if (unlikely(!current_evmcs)) - return; - - if (current_evmcs->hv_enlightenments_control.msr_bitmap) - current_evmcs->hv_clean_fields &= - ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP; -} - static inline void evmcs_load(u64 phys_addr) { struct hv_vp_assist_page *vp_ap = @@ -196,7 +186,6 @@ static inline u64 evmcs_read64(unsigned long field) { return 0; } static inline u32 evmcs_read32(unsigned long field) { return 0; } static inline u16 evmcs_read16(unsigned long field) { return 0; } static inline void evmcs_load(u64 phys_addr) {} -static inline void evmcs_touch_msr_bitmap(void) {} #endif /* IS_ENABLED(CONFIG_HYPERV) */ enum nested_evmptrld_status { diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index ee05c0e1cb2a..2c5d8b9f9873 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3792,8 +3792,13 @@ static void vmx_msr_bitmap_l01_changed(struct vcpu_vmx *vmx) * 'Enlightened MSR Bitmap' feature L0 needs to know that MSR * bitmap has changed. */ - if (static_branch_unlikely(&enable_evmcs)) - evmcs_touch_msr_bitmap(); + if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs)) { + struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs; + + if (evmcs->hv_enlightenments_control.msr_bitmap) + evmcs->hv_clean_fields &= + ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP; + } } static __always_inline void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, From aa8579bc084673c651204f7cd0d6308a47dffc16 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Tue, 25 May 2021 14:50:06 +0200 Subject: [PATCH 0737/1017] s390/dasd: add missing discipline function commit c0c8a8397fa8a74d04915f4d3d28cb4a5d401427 upstream. Fix crash with illegal operation exception in dasd_device_tasklet. Commit b72949328869 ("s390/dasd: Prepare for additional path event handling") renamed the verify_path function for ECKD but not for FBA and DIAG. This leads to a panic when the path verification function is called for a FBA or DIAG device. Fix by defining a wrapper function for dasd_generic_verify_path(). Fixes: b72949328869 ("s390/dasd: Prepare for additional path event handling") Cc: #5.11 Reviewed-by: Jan Hoeppner Signed-off-by: Stefan Haberland Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/20210525125006.157531-2-sth@linux.ibm.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/s390/block/dasd_diag.c | 7 ++++++- drivers/s390/block/dasd_fba.c | 7 ++++++- drivers/s390/block/dasd_int.h | 1 - 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 1b9e1442e6a5..d5c7b70bd4de 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -642,12 +642,17 @@ static void dasd_diag_setup_blk_queue(struct dasd_block *block) blk_queue_segment_boundary(q, PAGE_SIZE - 1); } +static int dasd_diag_pe_handler(struct dasd_device *device, __u8 tbvpm) +{ + return dasd_generic_verify_path(device, tbvpm); +} + static struct dasd_discipline dasd_diag_discipline = { .owner = THIS_MODULE, .name = "DIAG", .ebcname = "DIAG", .check_device = dasd_diag_check_device, - .verify_path = dasd_generic_verify_path, + .pe_handler = dasd_diag_pe_handler, .fill_geometry = dasd_diag_fill_geometry, .setup_blk_queue = dasd_diag_setup_blk_queue, .start_IO = dasd_start_diag, diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 1a44e321b54e..b159575a2760 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -803,13 +803,18 @@ static void dasd_fba_setup_blk_queue(struct dasd_block *block) blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); } +static int dasd_fba_pe_handler(struct dasd_device *device, __u8 tbvpm) +{ + return dasd_generic_verify_path(device, tbvpm); +} + static struct dasd_discipline dasd_fba_discipline = { .owner = THIS_MODULE, .name = "FBA ", .ebcname = "FBA ", .check_device = dasd_fba_check_characteristics, .do_analysis = dasd_fba_do_analysis, - .verify_path = dasd_generic_verify_path, + .pe_handler = dasd_fba_pe_handler, .setup_blk_queue = dasd_fba_setup_blk_queue, .fill_geometry = dasd_fba_fill_geometry, .start_IO = dasd_start_IO, diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index e8a06d85d6f7..5d7d35ca5eb4 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -298,7 +298,6 @@ struct dasd_discipline { * e.g. verify that new path is compatible with the current * configuration. */ - int (*verify_path)(struct dasd_device *, __u8); int (*pe_handler)(struct dasd_device *, __u8); /* From de26e1b2103b1f56451f6ad77f0190c9066c87dc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 17 Mar 2023 08:45:17 +0100 Subject: [PATCH 0738/1017] Linux 5.10.175 Link: https://lore.kernel.org/r/20230315115731.942692602@linuxfoundation.org Tested-by: Florian Fainelli Tested-by: Salvatore Bonaccorso Tested-by: Shuah Khan Link: https://lore.kernel.org/r/20230316083430.973448646@linuxfoundation.org Tested-by: Chris Paterson (CIP) Tested-by: Florian Fainelli Tested-by: Tom Saeger Tested-by: Guenter Roeck Tested-by: Linux Kernel Functional Testing Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 92accf2ddc08..e6b09052f222 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 174 +SUBLEVEL = 175 EXTRAVERSION = NAME = Dare mighty things From 0da0b816972a88dc82431586cb2c1e85876f9c77 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 21 Feb 2023 13:54:00 +0800 Subject: [PATCH 0739/1017] xfrm: Allow transport-mode states with AF_UNSPEC selector [ Upstream commit c276a706ea1f51cf9723ed8484feceaf961b8f89 ] xfrm state selectors are matched against the inner-most flow which can be of any address family. Therefore middle states in nested configurations need to carry a wildcard selector in order to work at all. However, this is currently forbidden for transport-mode states. Fix this by removing the unnecessary check. Fixes: 13996378e658 ("[IPSEC]: Rename mode to outer_mode and add inner_mode") Reported-by: David George Signed-off-by: Herbert Xu Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/xfrm/xfrm_state.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index fdbd56ed4bd5..ba73014805a4 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2611,9 +2611,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) if (inner_mode == NULL) goto error; - if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) - goto error; - x->inner_mode = *inner_mode; if (x->props.family == AF_INET) From a3c502218cd34992dabbfe0b5385a2ece5864f82 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 17 Nov 2022 04:40:38 +0300 Subject: [PATCH 0740/1017] drm/panfrost: Don't sync rpm suspension after mmu flushing [ Upstream commit ba3be66f11c3c49afaa9f49b99e21d88756229ef ] Lockdep warns about potential circular locking dependency of devfreq with the fs_reclaim caused by immediate device suspension when mapping is released by shrinker. Fix it by doing the suspension asynchronously. Reviewed-by: Steven Price Fixes: ec7eba47da86 ("drm/panfrost: Rework page table flushing and runtime PM interaction") Signed-off-by: Dmitry Osipenko Link: https://lore.kernel.org/all/20230108210445.3948344-3-dmitry.osipenko@collabora.com/ Signed-off-by: Sasha Levin --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 13596961ae17..5ff856ef7d88 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -236,7 +236,7 @@ static void panfrost_mmu_flush_range(struct panfrost_device *pfdev, if (pm_runtime_active(pfdev->dev)) mmu_hw_do_operation(pfdev, mmu, iova, size, AS_COMMAND_FLUSH_PT); - pm_runtime_put_sync_autosuspend(pfdev->dev); + pm_runtime_put_autosuspend(pfdev->dev); } static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, From ed9ed2f58cebfa4894efaee43986e1e96e8ca850 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Wed, 16 Nov 2022 11:11:36 +0800 Subject: [PATCH 0741/1017] cifs: Move the in_send statistic to __smb_send_rqst() [ Upstream commit d0dc41119905f740e8d5594adce277f7c0de8c92 ] When send SMB_COM_NT_CANCEL and RFC1002_SESSION_REQUEST, the in_send statistic was lost. Let's move the in_send statistic to the send function to avoid this scenario. Fixes: 7ee1af765dfa ("[CIFS]") Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/transport.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index b137006f0fd2..4409f56fc37e 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -312,7 +312,7 @@ static int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst) { - int rc = 0; + int rc; struct kvec *iov; int n_vec; unsigned int send_length = 0; @@ -323,6 +323,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, struct msghdr smb_msg = {}; __be32 rfc1002_marker; + cifs_in_send_inc(server); if (cifs_rdma_enabled(server)) { /* return -EAGAIN when connecting or reconnecting */ rc = -EAGAIN; @@ -331,14 +332,17 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, goto smbd_done; } + rc = -EAGAIN; if (ssocket == NULL) - return -EAGAIN; + goto out; + rc = -ERESTARTSYS; if (fatal_signal_pending(current)) { cifs_dbg(FYI, "signal pending before send request\n"); - return -ERESTARTSYS; + goto out; } + rc = 0; /* cork the socket */ tcp_sock_set_cork(ssocket->sk, true); @@ -449,7 +453,8 @@ smbd_done: rc); else if (rc > 0) rc = 0; - +out: + cifs_in_send_dec(server); return rc; } @@ -826,9 +831,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, * I/O response may come back and free the mid entry on another thread. */ cifs_save_when_sent(mid); - cifs_in_send_inc(server); rc = smb_send_rqst(server, 1, rqst, flags); - cifs_in_send_dec(server); if (rc < 0) { revert_current_mid(server, mid->credits); @@ -1117,9 +1120,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, else midQ[i]->callback = cifs_compound_last_callback; } - cifs_in_send_inc(server); rc = smb_send_rqst(server, num_rqst, rqst, flags); - cifs_in_send_dec(server); for (i = 0; i < num_rqst; i++) cifs_save_when_sent(midQ[i]); @@ -1356,9 +1357,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, midQ->mid_state = MID_REQUEST_SUBMITTED; - cifs_in_send_inc(server); rc = smb_send(server, in_buf, len); - cifs_in_send_dec(server); cifs_save_when_sent(midQ); if (rc < 0) @@ -1495,9 +1494,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, } midQ->mid_state = MID_REQUEST_SUBMITTED; - cifs_in_send_inc(server); rc = smb_send(server, in_buf, len); - cifs_in_send_dec(server); cifs_save_when_sent(midQ); if (rc < 0) From 081893e254f1369b64f4427911d4fd7b48d651aa Mon Sep 17 00:00:00 2001 From: Christian Hewitt Date: Fri, 3 Mar 2023 12:33:12 +0000 Subject: [PATCH 0742/1017] drm/meson: fix 1px pink line on GXM when scaling video overlay [ Upstream commit 5c8cf1664f288098a971a1d1e65716a2b6a279e1 ] Playing media with a resolution smaller than the crtc size requires the video overlay to be scaled for output and GXM boards display a 1px pink line on the bottom of the scaled overlay. Comparing with the downstream vendor driver revealed VPP_DUMMY_DATA not being set [0]. Setting VPP_DUMMY_DATA prevents the 1px pink line from being seen. [0] https://github.com/endlessm/linux-s905x/blob/master/drivers/amlogic/amports/video.c#L7869 Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") Suggested-by: Martin Blumenstingl Signed-off-by: Christian Hewitt Acked-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230303123312.155164-1-christianshewitt@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_vpp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c index 154837688ab0..5df1957c8e41 100644 --- a/drivers/gpu/drm/meson/meson_vpp.c +++ b/drivers/gpu/drm/meson/meson_vpp.c @@ -100,6 +100,8 @@ void meson_vpp_init(struct meson_drm *priv) priv->io_base + _REG(VPP_DOLBY_CTRL)); writel_relaxed(0x1020080, priv->io_base + _REG(VPP_DUMMY_DATA1)); + writel_relaxed(0x42020, + priv->io_base + _REG(VPP_DUMMY_DATA)); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) writel_relaxed(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL)); From ea1e21d38a8d78f22c6cd87d2df89ac08705c1e8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 25 Feb 2023 21:39:47 -0800 Subject: [PATCH 0743/1017] clk: HI655X: select REGMAP instead of depending on it [ Upstream commit 0ffad67784a097beccf34d297ddd1b0773b3b8a3 ] REGMAP is a hidden (not user visible) symbol. Users cannot set it directly thru "make *config", so drivers should select it instead of depending on it if they need it. Consistently using "select" or "depends on" can also help reduce Kconfig circular dependency issues. Therefore, change the use of "depends on REGMAP" to "select REGMAP". Fixes: 3a49afb84ca0 ("clk: enable hi655x common clk automatically") Signed-off-by: Randy Dunlap Cc: Riku Voipio Cc: Stephen Boyd Cc: Michael Turquette Cc: linux-clk@vger.kernel.org Link: https://lore.kernel.org/r/20230226053953.4681-3-rdunlap@infradead.org Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c715d4681a0b..4ae49eae4586 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -79,7 +79,7 @@ config COMMON_CLK_RK808 config COMMON_CLK_HI655X tristate "Clock driver for Hi655x" if EXPERT depends on (MFD_HI655X_PMIC || COMPILE_TEST) - depends on REGMAP + select REGMAP default MFD_HI655X_PMIC help This driver supports the hi655x PMIC clock. This From 79fe786dab5c10b1d5cb40aa3b4cdcc4489626ad Mon Sep 17 00:00:00 2001 From: Glenn Washburn Date: Mon, 27 Feb 2023 12:40:42 -0600 Subject: [PATCH 0744/1017] docs: Correct missing "d_" prefix for dentry_operations member d_weak_revalidate [ Upstream commit 74596085796fae0cfce3e42ee46bf4f8acbdac55 ] The details for struct dentry_operations member d_weak_revalidate is missing a "d_" prefix. Fixes: af96c1e304f7 ("docs: filesystems: vfs: Convert vfs.txt to RST") Signed-off-by: Glenn Washburn Reviewed-by: Matthew Wilcox (Oracle) Link: https://lore.kernel.org/r/20230227184042.2375235-1-development@efficientek.com Signed-off-by: Jonathan Corbet Signed-off-by: Sasha Levin --- Documentation/filesystems/vfs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index ca52c82e5bb5..f7b69a0e71e1 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -1188,7 +1188,7 @@ defined: return -ECHILD and it will be called again in ref-walk mode. -``_weak_revalidate`` +``d_weak_revalidate`` called when the VFS needs to revalidate a "jumped" dentry. This is called when a path-walk ends at dentry that was not acquired by doing a lookup in the parent directory. This includes "/", From 6f0c2f70d9929208d8427ec72c3ed91e2251e289 Mon Sep 17 00:00:00 2001 From: Wenchao Hao Date: Sat, 25 Feb 2023 18:01:36 +0800 Subject: [PATCH 0745/1017] scsi: mpt3sas: Fix NULL pointer access in mpt3sas_transport_port_add() [ Upstream commit d3c57724f1569311e4b81e98fad0931028b9bdcd ] Port is allocated by sas_port_alloc_num() and rphy is allocated by either sas_end_device_alloc() or sas_expander_alloc(), all of which may return NULL. So we need to check the rphy to avoid possible NULL pointer access. If sas_rphy_add() returned with failure, rphy is set to NULL. We would access the rphy in the following lines which would also result NULL pointer access. Fixes: 78316e9dfc24 ("scsi: mpt3sas: Fix possible resource leaks in mpt3sas_transport_port_add()") Signed-off-by: Wenchao Hao Link: https://lore.kernel.org/r/20230225100135.2109330-1-haowenchao2@huawei.com Acked-by: Sathya Prakash Veerichetty Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/mpt3sas/mpt3sas_transport.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index b58f4d9c296a..326265fd7f91 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -670,7 +670,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, goto out_fail; } port = sas_port_alloc_num(sas_node->parent_dev); - if ((sas_port_add(port))) { + if (!port || (sas_port_add(port))) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); goto out_fail; @@ -695,6 +695,12 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, rphy = sas_expander_alloc(port, mpt3sas_port->remote_identify.device_type); + if (!rphy) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + goto out_delete_port; + } + rphy->identify = mpt3sas_port->remote_identify; if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { @@ -714,6 +720,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, __FILE__, __LINE__, __func__); sas_rphy_free(rphy); rphy = NULL; + goto out_delete_port; } if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { @@ -740,7 +747,10 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, rphy_to_expander_device(rphy)); return mpt3sas_port; - out_fail: +out_delete_port: + sas_port_delete(port); + +out_fail: list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list, port_siblings) list_del(&mpt3sas_phy->port_siblings); From 0c6c5abeb471fead787ab12d8cafb9850cf66de2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 7 Mar 2023 15:40:54 -0600 Subject: [PATCH 0746/1017] ALSA: hda: Match only Intel devices with CONTROLLER_IN_GPU() [ Upstream commit ff447886e675979d66b2bc01810035d3baea1b3a ] CONTROLLER_IN_GPU() is clearly intended to match only Intel devices, but previously it checked only the PCI Device ID, not the Vendor ID, so it could match devices from other vendors that happened to use the same Device ID. Update CONTROLLER_IN_GPU() so it matches only Intel devices. Fixes: 535115b5ff51 ("ALSA: hda - Abort the probe without i915 binding for HSW/B") Signed-off-by: Bjorn Helgaas Link: https://lore.kernel.org/r/20230307214054.886721-1-helgaas@kernel.org Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/hda_intel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 494bfd2135a9..de1fe604905f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -365,14 +365,15 @@ enum { #define needs_eld_notify_link(chip) false #endif -#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \ +#define CONTROLLER_IN_GPU(pci) (((pci)->vendor == 0x8086) && \ + (((pci)->device == 0x0a0c) || \ ((pci)->device == 0x0c0c) || \ ((pci)->device == 0x0d0c) || \ ((pci)->device == 0x160c) || \ ((pci)->device == 0x490d) || \ ((pci)->device == 0x4f90) || \ ((pci)->device == 0x4f91) || \ - ((pci)->device == 0x4f92)) + ((pci)->device == 0x4f92))) #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) From eff050d83eee162a88d52b421f55ea9fad0bb826 Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Tue, 7 Mar 2023 23:22:56 +0000 Subject: [PATCH 0747/1017] netfilter: nft_nat: correct length for loading protocol registers [ Upstream commit 068d82e75d537b444303b8c449a11e51ea659565 ] The values in the protocol registers are two bytes wide. However, when parsing the register loads, the code currently uses the larger 16-byte size of a `union nf_inet_addr`. Change it to use the (correct) size of a `union nf_conntrack_man_proto` instead. Fixes: d07db9884a5f ("netfilter: nf_tables: introduce nft_validate_register_load()") Signed-off-by: Jeremy Sowden Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_nat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index db8f9116eeb4..cd4eb4996aff 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c @@ -226,7 +226,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, priv->flags |= NF_NAT_RANGE_MAP_IPS; } - plen = sizeof_field(struct nf_nat_range, min_addr.all); + plen = sizeof_field(struct nf_nat_range, min_proto.all); if (tb[NFTA_NAT_REG_PROTO_MIN]) { err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN], &priv->sreg_proto_min, plen); From 3a0f8ea35ddc9b205dbc04f6e848890ec983065e Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Tue, 7 Mar 2023 23:22:57 +0000 Subject: [PATCH 0748/1017] netfilter: nft_masq: correct length for loading protocol registers [ Upstream commit ec2c5917eb858428b2083d1c74f445aabbe8316b ] The values in the protocol registers are two bytes wide. However, when parsing the register loads, the code currently uses the larger 16-byte size of a `union nf_inet_addr`. Change it to use the (correct) size of a `union nf_conntrack_man_proto` instead. Fixes: 8a6bf5da1aef ("netfilter: nft_masq: support port range") Signed-off-by: Jeremy Sowden Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_masq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c index 9953e8053753..1818dbf089ca 100644 --- a/net/netfilter/nft_masq.c +++ b/net/netfilter/nft_masq.c @@ -43,7 +43,7 @@ static int nft_masq_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { - u32 plen = sizeof_field(struct nf_nat_range, min_addr.all); + u32 plen = sizeof_field(struct nf_nat_range, min_proto.all); struct nft_masq *priv = nft_expr_priv(expr); int err; From c144dff64ea9c924c1a85714d4fcf420c2df3213 Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Tue, 7 Mar 2023 23:22:58 +0000 Subject: [PATCH 0749/1017] netfilter: nft_redir: correct length for loading protocol registers [ Upstream commit 1f617b6b4c7a3d5ea7a56abb83a4c27733b60c2f ] The values in the protocol registers are two bytes wide. However, when parsing the register loads, the code currently uses the larger 16-byte size of a `union nf_inet_addr`. Change it to use the (correct) size of a `union nf_conntrack_man_proto` instead. Fixes: d07db9884a5f ("netfilter: nf_tables: introduce nft_validate_register_load()") Signed-off-by: Jeremy Sowden Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_redir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c index ba09890dddb5..deb7e65c8d82 100644 --- a/net/netfilter/nft_redir.c +++ b/net/netfilter/nft_redir.c @@ -48,7 +48,7 @@ static int nft_redir_init(const struct nft_ctx *ctx, unsigned int plen; int err; - plen = sizeof_field(struct nf_nat_range, min_addr.all); + plen = sizeof_field(struct nf_nat_range, min_proto.all); if (tb[NFTA_REDIR_REG_PROTO_MIN]) { err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN], &priv->sreg_proto_min, plen); From 0fac20b1806b211fc38fa8778208bc1cad7a5df1 Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Tue, 7 Mar 2023 23:22:59 +0000 Subject: [PATCH 0750/1017] netfilter: nft_redir: correct value of inet type `.maxattrs` [ Upstream commit 493924519b1fe3faab13ee621a43b0d0939abab1 ] `nft_redir_inet_type.maxattrs` was being set, presumably because of a cut-and-paste error, to `NFTA_MASQ_MAX`, instead of `NFTA_REDIR_MAX`. Fixes: 63ce3940f3ab ("netfilter: nft_redir: add inet support") Signed-off-by: Jeremy Sowden Reviewed-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_redir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c index deb7e65c8d82..e64f531d66cf 100644 --- a/net/netfilter/nft_redir.c +++ b/net/netfilter/nft_redir.c @@ -232,7 +232,7 @@ static struct nft_expr_type nft_redir_inet_type __read_mostly = { .name = "redir", .ops = &nft_redir_inet_ops, .policy = nft_redir_policy, - .maxattr = NFTA_MASQ_MAX, + .maxattr = NFTA_REDIR_MAX, .owner = THIS_MODULE, }; From be5aa2534188ab5df96508b532bcd59181650e5f Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Mon, 10 May 2021 19:35:26 +0800 Subject: [PATCH 0751/1017] scsi: core: Fix a comment in function scsi_host_dev_release() [ Upstream commit 2dde5c8d912efea43be94d6a83ac9cb74879fa12 ] Commit 3be8828fc507 ("scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops") moved rcu to scsi_cmnd instead of shost. Modify "shost->rcu" to "scmd->rcu" in a comment. Link: https://lore.kernel.org/r/1620646526-193154-1-git-send-email-chenxiang66@hisilicon.com Signed-off-by: Xiang Chen Signed-off-by: Martin K. Petersen Stable-dep-of: be03df3d4bfe ("scsi: core: Fix a procfs host directory removal regression") Signed-off-by: Sasha Levin --- drivers/scsi/hosts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index fae032324210..0fd2487203ff 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -325,7 +325,7 @@ static void scsi_host_dev_release(struct device *dev) /* In case scsi_remove_host() has not been called. */ scsi_proc_hostdir_rm(shost->hostt); - /* Wait for functions invoked through call_rcu(&shost->rcu, ...) */ + /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */ rcu_barrier(); if (shost->tmf_work_q) From 68c665bb185037e7eb66fb792c61da9d7151e99c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 7 Mar 2023 13:44:28 -0800 Subject: [PATCH 0752/1017] scsi: core: Fix a procfs host directory removal regression [ Upstream commit be03df3d4bfe7e8866d4aa43d62e648ffe884f5f ] scsi_proc_hostdir_rm() decreases a reference counter and hence must only be called once per host that is removed. This change does not require a scsi_add_host_with_dma() change since scsi_add_host_with_dma() will return 0 (success) if scsi_proc_host_add() is called. Fixes: fc663711b944 ("scsi: core: Remove the /proc/scsi/${proc_name} directory earlier") Cc: John Garry Reported-by: John Garry Link: https://lore.kernel.org/all/ed6b8027-a9d9-1b45-be8e-df4e8c6c4605@oracle.com/ Reported-by: syzbot+645a4616b87a2f10e398@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-scsi/000000000000890fab05f65342b6@google.com/ Signed-off-by: Bart Van Assche Link: https://lore.kernel.org/r/20230307214428.3703498-1-bvanassche@acm.org Tested-by: John Garry Tested-by: Shin'ichiro Kawasaki Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/hosts.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 0fd2487203ff..18321cf9db5d 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -322,9 +322,6 @@ static void scsi_host_dev_release(struct device *dev) struct Scsi_Host *shost = dev_to_shost(dev); struct device *parent = dev->parent; - /* In case scsi_remove_host() has not been called. */ - scsi_proc_hostdir_rm(shost->hostt); - /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */ rcu_barrier(); From 77ad58bca0119e8cc3e0e9d91a3f22caa66e4dfa Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 8 Mar 2023 11:07:45 -0800 Subject: [PATCH 0753/1017] tcp: tcp_make_synack() can be called from process context [ Upstream commit bced3f7db95ff2e6ca29dc4d1c9751ab5e736a09 ] tcp_rtx_synack() now could be called in process context as explained in 0a375c822497 ("tcp: tcp_rtx_synack() can be called from process context"). tcp_rtx_synack() might call tcp_make_synack(), which will touch per-CPU variables with preemption enabled. This causes the following BUG: BUG: using __this_cpu_add() in preemptible [00000000] code: ThriftIO1/5464 caller is tcp_make_synack+0x841/0xac0 Call Trace: dump_stack_lvl+0x10d/0x1a0 check_preemption_disabled+0x104/0x110 tcp_make_synack+0x841/0xac0 tcp_v6_send_synack+0x5c/0x450 tcp_rtx_synack+0xeb/0x1f0 inet_rtx_syn_ack+0x34/0x60 tcp_check_req+0x3af/0x9e0 tcp_rcv_state_process+0x59b/0x2030 tcp_v6_do_rcv+0x5f5/0x700 release_sock+0x3a/0xf0 tcp_sendmsg+0x33/0x40 ____sys_sendmsg+0x2f2/0x490 __sys_sendmsg+0x184/0x230 do_syscall_64+0x3d/0x90 Avoid calling __TCP_INC_STATS() with will touch per-cpu variables. Use TCP_INC_STATS() which is safe to be called from context switch. Fixes: 8336886f786f ("tcp: TCP Fast Open Server - support TFO listeners") Signed-off-by: Breno Leitao Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20230308190745.780221-1-leitao@debian.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/tcp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index eefd032bc6db..e4ad274ec7a3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3609,7 +3609,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, th->window = htons(min(req->rsk_rcv_wnd, 65535U)); tcp_options_write((__be32 *)(th + 1), NULL, &opts); th->doff = (tcp_header_size >> 2); - __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); + TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); #ifdef CONFIG_TCP_MD5SIG /* Okay, we have all we need - do the md5 hash if needed */ From 2703da78849c47b6b5b4471edb35fc7b7f91dead Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Thu, 9 Mar 2023 19:50:50 +0300 Subject: [PATCH 0754/1017] nfc: pn533: initialize struct pn533_out_arg properly [ Upstream commit 484b7059796e3bc1cb527caa61dfc60da649b4f6 ] struct pn533_out_arg used as a temporary context for out_urb is not initialized properly. Its uninitialized 'phy' field can be dereferenced in error cases inside pn533_out_complete() callback function. It causes the following failure: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.2.0-rc3-next-20230110-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:pn533_out_complete.cold+0x15/0x44 drivers/nfc/pn533/usb.c:441 Call Trace: __usb_hcd_giveback_urb+0x2b6/0x5c0 drivers/usb/core/hcd.c:1671 usb_hcd_giveback_urb+0x384/0x430 drivers/usb/core/hcd.c:1754 dummy_timer+0x1203/0x32d0 drivers/usb/gadget/udc/dummy_hcd.c:1988 call_timer_fn+0x1da/0x800 kernel/time/timer.c:1700 expire_timers+0x234/0x330 kernel/time/timer.c:1751 __run_timers kernel/time/timer.c:2022 [inline] __run_timers kernel/time/timer.c:1995 [inline] run_timer_softirq+0x326/0x910 kernel/time/timer.c:2035 __do_softirq+0x1fb/0xaf6 kernel/softirq.c:571 invoke_softirq kernel/softirq.c:445 [inline] __irq_exit_rcu+0x123/0x180 kernel/softirq.c:650 irq_exit_rcu+0x9/0x20 kernel/softirq.c:662 sysvec_apic_timer_interrupt+0x97/0xc0 arch/x86/kernel/apic/apic.c:1107 Initialize the field with the pn533_usb_phy currently used. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 9dab880d675b ("nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame()") Reported-by: syzbot+1e608ba4217c96d1952f@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230309165050.207390-1-pchelkin@ispras.ru Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/nfc/pn533/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 57b07446bb76..68eb1253f888 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -175,6 +175,7 @@ static int pn533_usb_send_frame(struct pn533 *dev, print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, out->data, out->len, false); + arg.phy = phy; init_completion(&arg.done); cntx = phy->out_urb->context; phy->out_urb->context = &arg; From 91eb59240150f2b5907a88be3fc7ebb7f636cdfd Mon Sep 17 00:00:00 2001 From: Jianguo Wu Date: Thu, 9 Mar 2023 10:03:36 +0800 Subject: [PATCH 0755/1017] ipvlan: Make skb->skb_iif track skb->dev for l3s mode [ Upstream commit 59a0b022aa249e3f5735d93de0849341722c4754 ] For l3s mode, skb->dev is set to ipvlan interface in ipvlan_nf_input(): skb->dev = addr->master->dev but, skb->skb_iif remain unchanged, this will cause socket lookup failed if a target socket is bound to a interface, like the following example: ip link add ipvlan0 link eth0 type ipvlan mode l3s ip addr add dev ipvlan0 192.168.124.111/24 ip link set ipvlan0 up ping -c 1 -I ipvlan0 8.8.8.8 100% packet loss This is because there is no match sk in __raw_v4_lookup() as sk->sk_bound_dev_if != dif(skb->skb_iif). Fix this by make skb->skb_iif track skb->dev in ipvlan_nf_input(). Fixes: c675e06a98a4 ("ipvlan: decouple l3s mode dependencies from other modes") Signed-off-by: Jianguo Wu Reviewed-by: Jiri Pirko Link: https://lore.kernel.org/r/29865b1f-6db7-c07a-de89-949d3721ea30@163.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ipvlan/ipvlan_l3s.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ipvlan/ipvlan_l3s.c b/drivers/net/ipvlan/ipvlan_l3s.c index 943d26cbf39f..71712ea25403 100644 --- a/drivers/net/ipvlan/ipvlan_l3s.c +++ b/drivers/net/ipvlan/ipvlan_l3s.c @@ -101,6 +101,7 @@ static unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb, goto out; skb->dev = addr->master->dev; + skb->skb_iif = skb->dev->ifindex; len = skb->len + ETH_HLEN; ipvlan_count_rx(addr->master, len, true, false); out: From 3cbecb1c9085a00155639404f7addbcbfc987ba3 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Thu, 9 Mar 2023 10:45:09 -0800 Subject: [PATCH 0756/1017] i40e: Fix kernel crash during reboot when adapter is in recovery mode [ Upstream commit 7e4f8a0c495413a50413e8c9f1032ce1bc633bae ] If the driver detects during probe that firmware is in recovery mode then i40e_init_recovery_mode() is called and the rest of probe function is skipped including pci_set_drvdata(). Subsequent i40e_shutdown() called during shutdown/reboot dereferences NULL pointer as pci_get_drvdata() returns NULL. To fix call pci_set_drvdata() also during entering to recovery mode. Reproducer: 1) Lets have i40e NIC with firmware in recovery mode 2) Run reboot Result: [ 139.084698] i40e: Intel(R) Ethernet Connection XL710 Network Driver [ 139.090959] i40e: Copyright (c) 2013 - 2019 Intel Corporation. [ 139.108438] i40e 0000:02:00.0: Firmware recovery mode detected. Limiting functionality. [ 139.116439] i40e 0000:02:00.0: Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode. [ 139.129499] i40e 0000:02:00.0: fw 8.3.64775 api 1.13 nvm 8.30 0x8000b78d 1.3106.0 [8086:1583] [15d9:084a] [ 139.215932] i40e 0000:02:00.0 enp2s0f0: renamed from eth0 [ 139.223292] i40e 0000:02:00.1: Firmware recovery mode detected. Limiting functionality. [ 139.231292] i40e 0000:02:00.1: Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode. [ 139.244406] i40e 0000:02:00.1: fw 8.3.64775 api 1.13 nvm 8.30 0x8000b78d 1.3106.0 [8086:1583] [15d9:084a] [ 139.329209] i40e 0000:02:00.1 enp2s0f1: renamed from eth0 ... [ 156.311376] BUG: kernel NULL pointer dereference, address: 00000000000006c2 [ 156.318330] #PF: supervisor write access in kernel mode [ 156.323546] #PF: error_code(0x0002) - not-present page [ 156.328679] PGD 0 P4D 0 [ 156.331210] Oops: 0002 [#1] PREEMPT SMP NOPTI [ 156.335567] CPU: 26 PID: 15119 Comm: reboot Tainted: G E 6.2.0+ #1 [ 156.343126] Hardware name: Abacus electric, s.r.o. - servis@abacus.cz Super Server/H12SSW-iN, BIOS 2.4 04/13/2022 [ 156.353369] RIP: 0010:i40e_shutdown+0x15/0x130 [i40e] [ 156.358430] Code: c1 fc ff ff 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 55 48 89 fd 53 48 8b 9f 48 01 00 00 80 8b c2 06 00 00 04 f0 80 8b c0 06 00 00 08 48 8d bb 08 08 00 [ 156.377168] RSP: 0018:ffffb223c8447d90 EFLAGS: 00010282 [ 156.382384] RAX: ffffffffc073ee70 RBX: 0000000000000000 RCX: 0000000000000001 [ 156.389510] RDX: 0000000080000001 RSI: 0000000000000246 RDI: ffff95db49988000 [ 156.396634] RBP: ffff95db49988000 R08: ffffffffffffffff R09: ffffffff8bd17d40 [ 156.403759] R10: 0000000000000001 R11: ffffffff8a5e3d28 R12: ffff95db49988000 [ 156.410882] R13: ffffffff89a6fe17 R14: ffff95db49988150 R15: 0000000000000000 [ 156.418007] FS: 00007fe7c0cc3980(0000) GS:ffff95ea8ee80000(0000) knlGS:0000000000000000 [ 156.426083] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 156.431819] CR2: 00000000000006c2 CR3: 00000003092fc005 CR4: 0000000000770ee0 [ 156.438944] PKRU: 55555554 [ 156.441647] Call Trace: [ 156.444096] [ 156.446199] pci_device_shutdown+0x38/0x60 [ 156.450297] device_shutdown+0x163/0x210 [ 156.454215] kernel_restart+0x12/0x70 [ 156.457872] __do_sys_reboot+0x1ab/0x230 [ 156.461789] ? vfs_writev+0xa6/0x1a0 [ 156.465362] ? __pfx_file_free_rcu+0x10/0x10 [ 156.469635] ? __call_rcu_common.constprop.85+0x109/0x5a0 [ 156.475034] do_syscall_64+0x3e/0x90 [ 156.478611] entry_SYSCALL_64_after_hwframe+0x72/0xdc [ 156.483658] RIP: 0033:0x7fe7bff37ab7 Fixes: 4ff0ee1af016 ("i40e: Introduce recovery mode support") Signed-off-by: Ivan Vecera Tested-by: Arpana Arland (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Link: https://lore.kernel.org/r/20230309184509.984639-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 9e8a20a94862..76481ff7074b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -14851,6 +14851,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw) int err; int v_idx; + pci_set_drvdata(pf->pdev, pf); pci_save_state(pf->pdev); /* set up periodic task facility */ From 31817c530768b0199771ec6019571b4f0ddbf230 Mon Sep 17 00:00:00 2001 From: "D. Wythe" Date: Wed, 8 Mar 2023 16:17:12 +0800 Subject: [PATCH 0757/1017] net/smc: fix NULL sndbuf_desc in smc_cdc_tx_handler() [ Upstream commit 22a825c541d775c1dbe7b2402786025acad6727b ] When performing a stress test on SMC-R by rmmod mlx5_ib driver during the wrk/nginx test, we found that there is a probability of triggering a panic while terminating all link groups. This issue dues to the race between smc_smcr_terminate_all() and smc_buf_create(). smc_smcr_terminate_all smc_buf_create /* init */ conn->sndbuf_desc = NULL; ... __smc_lgr_terminate smc_conn_kill smc_close_abort smc_cdc_get_slot_and_msg_send __softirqentry_text_start smc_wr_tx_process_cqe smc_cdc_tx_handler READ(conn->sndbuf_desc->len); /* panic dues to NULL sndbuf_desc */ conn->sndbuf_desc = xxx; This patch tries to fix the issue by always to check the sndbuf_desc before send any cdc msg, to make sure that no null pointer is seen during cqe processing. Fixes: 0b29ec643613 ("net/smc: immediate termination for SMCR link groups") Signed-off-by: D. Wythe Reviewed-by: Tony Lu Reviewed-by: Wenjia Zhang Link: https://lore.kernel.org/r/1678263432-17329-1-git-send-email-alibuda@linux.alibaba.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/smc/smc_cdc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c index 94503f36b9a6..9125d28d9ff5 100644 --- a/net/smc/smc_cdc.c +++ b/net/smc/smc_cdc.c @@ -104,6 +104,9 @@ int smc_cdc_msg_send(struct smc_connection *conn, union smc_host_cursor cfed; int rc; + if (unlikely(!READ_ONCE(conn->sndbuf_desc))) + return -ENOBUFS; + smc_cdc_add_pending_send(conn, pend); conn->tx_cdc_seq++; From 281e86e3fab69294e0a7467d0447d1b0468aa1fd Mon Sep 17 00:00:00 2001 From: Daniil Tatianin Date: Thu, 9 Mar 2023 23:15:56 +0300 Subject: [PATCH 0758/1017] qed/qed_dev: guard against a possible division by zero [ Upstream commit 1a9dc5610ef89d807acdcfbff93a558f341a44da ] Previously we would divide total_left_rate by zero if num_vports happened to be 1 because non_requested_count is calculated as num_vports - req_count. Guard against this by validating num_vports at the beginning and returning an error otherwise. Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Fixes: bcd197c81f63 ("qed: Add vport WFQ configuration APIs") Signed-off-by: Daniil Tatianin Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230309201556.191392-1-d-tatianin@yandex-team.ru Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/qlogic/qed/qed_dev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index d2f5855b2ea7..895b6f0a3984 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -4986,6 +4986,11 @@ static int qed_init_wfq_param(struct qed_hwfn *p_hwfn, num_vports = p_hwfn->qm_info.num_vports; + if (num_vports < 2) { + DP_NOTICE(p_hwfn, "Unexpected num_vports: %d\n", num_vports); + return -EINVAL; + } + /* Accounting for the vports which are configured for WFQ explicitly */ for (i = 0; i < num_vports; i++) { u32 tmp_speed; From be59b87ee4aed81db7c10e44f603866a0ac3ca5d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 10 Mar 2023 19:11:09 +0000 Subject: [PATCH 0759/1017] net: tunnels: annotate lockless accesses to dev->needed_headroom [ Upstream commit 4b397c06cb987935b1b097336532aa6b4210e091 ] IP tunnels can apparently update dev->needed_headroom in their xmit path. This patch takes care of three tunnels xmit, and also the core LL_RESERVED_SPACE() and LL_RESERVED_SPACE_EXTRA() helpers. More changes might be needed for completeness. BUG: KCSAN: data-race in ip_tunnel_xmit / ip_tunnel_xmit read to 0xffff88815b9da0ec of 2 bytes by task 888 on cpu 1: ip_tunnel_xmit+0x1270/0x1730 net/ipv4/ip_tunnel.c:803 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430 dst_output include/net/dst.h:444 [inline] ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126 iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430 dst_output include/net/dst.h:444 [inline] ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126 iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430 dst_output include/net/dst.h:444 [inline] ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126 iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430 dst_output include/net/dst.h:444 [inline] ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126 iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430 dst_output include/net/dst.h:444 [inline] ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126 iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip_finish_output2+0x740/0x840 net/ipv4/ip_output.c:228 ip_finish_output+0xf4/0x240 net/ipv4/ip_output.c:316 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip_output+0xe5/0x1b0 net/ipv4/ip_output.c:430 dst_output include/net/dst.h:444 [inline] ip_local_out+0x64/0x80 net/ipv4/ip_output.c:126 iptunnel_xmit+0x34a/0x4b0 net/ipv4/ip_tunnel_core.c:82 ip_tunnel_xmit+0x1451/0x1730 net/ipv4/ip_tunnel.c:813 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 write to 0xffff88815b9da0ec of 2 bytes by task 2379 on cpu 0: ip_tunnel_xmit+0x1294/0x1730 net/ipv4/ip_tunnel.c:804 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:661 __netdev_start_xmit include/linux/netdevice.h:4881 [inline] netdev_start_xmit include/linux/netdevice.h:4895 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x127/0x400 net/core/dev.c:3596 __dev_queue_xmit+0x1007/0x1eb0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3051 [inline] neigh_direct_output+0x17/0x20 net/core/neighbour.c:1623 neigh_output include/net/neighbour.h:546 [inline] ip6_finish_output2+0x9bc/0xc50 net/ipv6/ip6_output.c:134 __ip6_finish_output net/ipv6/ip6_output.c:195 [inline] ip6_finish_output+0x39a/0x4e0 net/ipv6/ip6_output.c:206 NF_HOOK_COND include/linux/netfilter.h:291 [inline] ip6_output+0xeb/0x220 net/ipv6/ip6_output.c:227 dst_output include/net/dst.h:444 [inline] NF_HOOK include/linux/netfilter.h:302 [inline] mld_sendpack+0x438/0x6a0 net/ipv6/mcast.c:1820 mld_send_cr net/ipv6/mcast.c:2121 [inline] mld_ifc_work+0x519/0x7b0 net/ipv6/mcast.c:2653 process_one_work+0x3e6/0x750 kernel/workqueue.c:2390 worker_thread+0x5f2/0xa10 kernel/workqueue.c:2537 kthread+0x1ac/0x1e0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308 value changed: 0x0dd4 -> 0x0e14 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 2379 Comm: kworker/0:0 Not tainted 6.3.0-rc1-syzkaller-00002-g8ca09d5fa354-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/02/2023 Workqueue: mld mld_ifc_work Fixes: 8eb30be0352d ("ipv6: Create ip6_tnl_xmit") Reported-by: syzbot Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/r/20230310191109.2384387-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/linux/netdevice.h | 6 ++++-- net/ipv4/ip_tunnel.c | 12 ++++++------ net/ipv6/ip6_tunnel.c | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b478a16ef284..9ef63bc14b00 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -270,9 +270,11 @@ struct hh_cache { * relationship HH alignment <= LL alignment. */ #define LL_RESERVED_SPACE(dev) \ - ((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) + ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \ + & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ - ((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) + ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \ + & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) struct header_ops { int (*create) (struct sk_buff *skb, struct net_device *dev, diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index be75b409445c..99f70b990eb1 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -613,10 +613,10 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, } headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len; - if (headroom > dev->needed_headroom) - dev->needed_headroom = headroom; + if (headroom > READ_ONCE(dev->needed_headroom)) + WRITE_ONCE(dev->needed_headroom, headroom); - if (skb_cow_head(skb, dev->needed_headroom)) { + if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) { ip_rt_put(rt); goto tx_dropped; } @@ -797,10 +797,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, max_headroom = LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + rt->dst.header_len + ip_encap_hlen(&tunnel->encap); - if (max_headroom > dev->needed_headroom) - dev->needed_headroom = max_headroom; + if (max_headroom > READ_ONCE(dev->needed_headroom)) + WRITE_ONCE(dev->needed_headroom, max_headroom); - if (skb_cow_head(skb, dev->needed_headroom)) { + if (skb_cow_head(skb, READ_ONCE(dev->needed_headroom))) { ip_rt_put(rt); dev->stats.tx_dropped++; kfree_skb(skb); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 0d4cab94c5dd..a03a322e0cc1 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1267,8 +1267,8 @@ route_lookup: */ max_headroom = LL_RESERVED_SPACE(dst->dev) + sizeof(struct ipv6hdr) + dst->header_len + t->hlen; - if (max_headroom > dev->needed_headroom) - dev->needed_headroom = max_headroom; + if (max_headroom > READ_ONCE(dev->needed_headroom)) + WRITE_ONCE(dev->needed_headroom, max_headroom); err = ip6_tnl_encap(skb, t, &proto, fl6); if (err) From 194248138f8da8a74cbdc359fb5e5a7b116f35da Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 11 Mar 2023 19:34:45 +0100 Subject: [PATCH 0760/1017] net: phy: smsc: bail out in lan87xx_read_status if genphy_read_status fails [ Upstream commit c22c3bbf351e4ce905f082649cffa1ff893ea8c1 ] If genphy_read_status fails then further access to the PHY may result in unpredictable behavior. To prevent this bail out immediately if genphy_read_status fails. Fixes: 4223dbffed9f ("net: phy: smsc: Re-enable EDPD mode for LAN87xx") Signed-off-by: Heiner Kallweit Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/026aa4f2-36f5-1c10-ab9f-cdb17dda6ac4@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/phy/smsc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index caf7291ffaf8..b67de3f9ef18 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -181,8 +181,11 @@ static int lan95xx_config_aneg_ext(struct phy_device *phydev) static int lan87xx_read_status(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; + int err; - int err = genphy_read_status(phydev); + err = genphy_read_status(phydev); + if (err) + return err; if (!phydev->link && priv->energy_enable) { /* Disable EDPD to wake up PHY */ From 43aa468df246175207a7d5d7d6d31b231f15b49c Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Mon, 13 Mar 2023 00:08:37 +0800 Subject: [PATCH 0761/1017] nfc: st-nci: Fix use after free bug in ndlc_remove due to race condition [ Upstream commit 5000fe6c27827a61d8250a7e4a1d26c3298ef4f6 ] This bug influences both st_nci_i2c_remove and st_nci_spi_remove. Take st_nci_i2c_remove as an example. In st_nci_i2c_probe, it called ndlc_probe and bound &ndlc->sm_work with llt_ndlc_sm_work. When it calls ndlc_recv or timeout handler, it will finally call schedule_work to start the work. When we call st_nci_i2c_remove to remove the driver, there may be a sequence as follows: Fix it by finishing the work before cleanup in ndlc_remove CPU0 CPU1 |llt_ndlc_sm_work st_nci_i2c_remove | ndlc_remove | st_nci_remove | nci_free_device| kfree(ndev) | //free ndlc->ndev | |llt_ndlc_rcv_queue |nci_recv_frame |//use ndlc->ndev Fixes: 35630df68d60 ("NFC: st21nfcb: Add driver for STMicroelectronics ST21NFCB NFC chip") Signed-off-by: Zheng Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230312160837.2040857-1-zyytlz.wz@163.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/nfc/st-nci/ndlc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/st-nci/ndlc.c b/drivers/nfc/st-nci/ndlc.c index 5d74c674368a..8ccf5a86ad1b 100644 --- a/drivers/nfc/st-nci/ndlc.c +++ b/drivers/nfc/st-nci/ndlc.c @@ -286,13 +286,15 @@ EXPORT_SYMBOL(ndlc_probe); void ndlc_remove(struct llt_ndlc *ndlc) { - st_nci_remove(ndlc->ndev); - /* cancel timers */ del_timer_sync(&ndlc->t1_timer); del_timer_sync(&ndlc->t2_timer); ndlc->t2_active = false; ndlc->t1_active = false; + /* cancel work */ + cancel_work_sync(&ndlc->sm_work); + + st_nci_remove(ndlc->ndev); skb_queue_purge(&ndlc->rcv_q); skb_queue_purge(&ndlc->send_q); From 9708efad9ba5095b9bb7916e11a135b3bd66c071 Mon Sep 17 00:00:00 2001 From: Wenjia Zhang Date: Mon, 13 Mar 2023 11:08:28 +0100 Subject: [PATCH 0762/1017] net/smc: fix deadlock triggered by cancel_delayed_work_syn() [ Upstream commit 13085e1b5cab8ad802904d72e6a6dae85ae0cd20 ] The following LOCKDEP was detected: Workqueue: events smc_lgr_free_work [smc] WARNING: possible circular locking dependency detected 6.1.0-20221027.rc2.git8.56bc5b569087.300.fc36.s390x+debug #1 Not tainted ------------------------------------------------------ kworker/3:0/176251 is trying to acquire lock: 00000000f1467148 ((wq_completion)smc_tx_wq-00000000#2){+.+.}-{0:0}, at: __flush_workqueue+0x7a/0x4f0 but task is already holding lock: 0000037fffe97dc8 ((work_completion)(&(&lgr->free_work)->work)){+.+.}-{0:0}, at: process_one_work+0x232/0x730 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #4 ((work_completion)(&(&lgr->free_work)->work)){+.+.}-{0:0}: __lock_acquire+0x58e/0xbd8 lock_acquire.part.0+0xe2/0x248 lock_acquire+0xac/0x1c8 __flush_work+0x76/0xf0 __cancel_work_timer+0x170/0x220 __smc_lgr_terminate.part.0+0x34/0x1c0 [smc] smc_connect_rdma+0x15e/0x418 [smc] __smc_connect+0x234/0x480 [smc] smc_connect+0x1d6/0x230 [smc] __sys_connect+0x90/0xc0 __do_sys_socketcall+0x186/0x370 __do_syscall+0x1da/0x208 system_call+0x82/0xb0 -> #3 (smc_client_lgr_pending){+.+.}-{3:3}: __lock_acquire+0x58e/0xbd8 lock_acquire.part.0+0xe2/0x248 lock_acquire+0xac/0x1c8 __mutex_lock+0x96/0x8e8 mutex_lock_nested+0x32/0x40 smc_connect_rdma+0xa4/0x418 [smc] __smc_connect+0x234/0x480 [smc] smc_connect+0x1d6/0x230 [smc] __sys_connect+0x90/0xc0 __do_sys_socketcall+0x186/0x370 __do_syscall+0x1da/0x208 system_call+0x82/0xb0 -> #2 (sk_lock-AF_SMC){+.+.}-{0:0}: __lock_acquire+0x58e/0xbd8 lock_acquire.part.0+0xe2/0x248 lock_acquire+0xac/0x1c8 lock_sock_nested+0x46/0xa8 smc_tx_work+0x34/0x50 [smc] process_one_work+0x30c/0x730 worker_thread+0x62/0x420 kthread+0x138/0x150 __ret_from_fork+0x3c/0x58 ret_from_fork+0xa/0x40 -> #1 ((work_completion)(&(&smc->conn.tx_work)->work)){+.+.}-{0:0}: __lock_acquire+0x58e/0xbd8 lock_acquire.part.0+0xe2/0x248 lock_acquire+0xac/0x1c8 process_one_work+0x2bc/0x730 worker_thread+0x62/0x420 kthread+0x138/0x150 __ret_from_fork+0x3c/0x58 ret_from_fork+0xa/0x40 -> #0 ((wq_completion)smc_tx_wq-00000000#2){+.+.}-{0:0}: check_prev_add+0xd8/0xe88 validate_chain+0x70c/0xb20 __lock_acquire+0x58e/0xbd8 lock_acquire.part.0+0xe2/0x248 lock_acquire+0xac/0x1c8 __flush_workqueue+0xaa/0x4f0 drain_workqueue+0xaa/0x158 destroy_workqueue+0x44/0x2d8 smc_lgr_free+0x9e/0xf8 [smc] process_one_work+0x30c/0x730 worker_thread+0x62/0x420 kthread+0x138/0x150 __ret_from_fork+0x3c/0x58 ret_from_fork+0xa/0x40 other info that might help us debug this: Chain exists of: (wq_completion)smc_tx_wq-00000000#2 --> smc_client_lgr_pending --> (work_completion)(&(&lgr->free_work)->work) Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock((work_completion)(&(&lgr->free_work)->work)); lock(smc_client_lgr_pending); lock((work_completion) (&(&lgr->free_work)->work)); lock((wq_completion)smc_tx_wq-00000000#2); *** DEADLOCK *** 2 locks held by kworker/3:0/176251: #0: 0000000080183548 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x232/0x730 #1: 0000037fffe97dc8 ((work_completion) (&(&lgr->free_work)->work)){+.+.}-{0:0}, at: process_one_work+0x232/0x730 stack backtrace: CPU: 3 PID: 176251 Comm: kworker/3:0 Not tainted Hardware name: IBM 8561 T01 701 (z/VM 7.2.0) Call Trace: [<000000002983c3e4>] dump_stack_lvl+0xac/0x100 [<0000000028b477ae>] check_noncircular+0x13e/0x160 [<0000000028b48808>] check_prev_add+0xd8/0xe88 [<0000000028b49cc4>] validate_chain+0x70c/0xb20 [<0000000028b4bd26>] __lock_acquire+0x58e/0xbd8 [<0000000028b4cf6a>] lock_acquire.part.0+0xe2/0x248 [<0000000028b4d17c>] lock_acquire+0xac/0x1c8 [<0000000028addaaa>] __flush_workqueue+0xaa/0x4f0 [<0000000028addf9a>] drain_workqueue+0xaa/0x158 [<0000000028ae303c>] destroy_workqueue+0x44/0x2d8 [<000003ff8029af26>] smc_lgr_free+0x9e/0xf8 [smc] [<0000000028adf3d4>] process_one_work+0x30c/0x730 [<0000000028adf85a>] worker_thread+0x62/0x420 [<0000000028aeac50>] kthread+0x138/0x150 [<0000000028a63914>] __ret_from_fork+0x3c/0x58 [<00000000298503da>] ret_from_fork+0xa/0x40 INFO: lockdep is turned off. =================================================================== This deadlock occurs because cancel_delayed_work_sync() waits for the work(&lgr->free_work) to finish, while the &lgr->free_work waits for the work(lgr->tx_wq), which needs the sk_lock-AF_SMC, that is already used under the mutex_lock. The solution is to use cancel_delayed_work() instead, which kills off a pending work. Fixes: a52bcc919b14 ("net/smc: improve termination processing") Signed-off-by: Wenjia Zhang Reviewed-by: Jan Karcher Reviewed-by: Karsten Graul Reviewed-by: Tony Lu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/smc/smc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index bf485a2017a4..e84241ff4ac4 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -912,7 +912,7 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft) if (lgr->terminating) return; /* lgr already terminating */ /* cancel free_work sync, will terminate when lgr->freeing is set */ - cancel_delayed_work_sync(&lgr->free_work); + cancel_delayed_work(&lgr->free_work); lgr->terminating = 1; /* kill remaining link group connections */ From e294f0aa47e4844f3d3c8766c02accd5a76a7d4e Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Mon, 13 Mar 2023 23:00:45 +0100 Subject: [PATCH 0763/1017] net: usb: smsc75xx: Limit packet length to skb->len [ Upstream commit d8b228318935044dafe3a5bc07ee71a1f1424b8d ] Packet length retrieved from skb data may be larger than the actual socket buffer length (up to 9026 bytes). In such case the cloned skb passed up the network stack will leak kernel memory contents. Fixes: d0cad871703b ("smsc75xx: SMSC LAN75xx USB gigabit ethernet adapter driver") Signed-off-by: Szymon Heidrich Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/smsc75xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 378a12ae2d95..0b3d11e28faa 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -2211,7 +2211,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) dev->net->stats.rx_frame_errors++; } else { /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { + if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12) || + size > skb->len)) { netif_dbg(dev, rx_err, dev->net, "size err rx_cmd_a=0x%08x\n", rx_cmd_a); From d5e61a859a8aeed4300ce4d067c3440770d9e728 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Tue, 14 Mar 2023 13:50:35 +0800 Subject: [PATCH 0764/1017] drm/bridge: Fix returned array size name for atomic_get_input_bus_fmts kdoc [ Upstream commit 0d3c9333d976af41d7dbc6bf4d9d2e95fbdf9c89 ] The returned array size for input formats is set through atomic_get_input_bus_fmts()'s 'num_input_fmts' argument, so use 'num_input_fmts' to represent the array size in the function's kdoc, not 'num_output_fmts'. Fixes: 91ea83306bfa ("drm/bridge: Fix the bridge kernel doc") Fixes: f32df58acc68 ("drm/bridge: Add the necessary bits to support bus format negotiation") Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230314055035.3731179-1-victor.liu@nxp.com Signed-off-by: Sasha Levin --- include/drm/drm_bridge.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 2195daa289d2..055486e35e68 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -427,11 +427,11 @@ struct drm_bridge_funcs { * * The returned array must be allocated with kmalloc() and will be * freed by the caller. If the allocation fails, NULL should be - * returned. num_output_fmts must be set to the returned array size. + * returned. num_input_fmts must be set to the returned array size. * Formats listed in the returned array should be listed in decreasing * preference order (the core will try all formats until it finds one * that works). When the format is not supported NULL should be - * returned and num_output_fmts should be set to 0. + * returned and num_input_fmts should be set to 0. * * This method is called on all elements of the bridge chain as part of * the bus format negotiation process that happens in From d14d2574a54c2ee7ae6c44a5507973972ecce7f5 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 20 Nov 2020 10:55:19 +0900 Subject: [PATCH 0765/1017] null_blk: Move driver into its own directory [ Upstream commit eebf34a85c8c724676eba502d15202854f199b05 ] Move null_blk driver code into the new sub-directory drivers/block/null_blk. Suggested-by: Bart Van Assche Signed-off-by: Damien Le Moal Reviewed-by: Johannes Thumshirn Signed-off-by: Jens Axboe Stable-dep-of: 63f886597085 ("block: null_blk: Fix handling of fake timeout request") Signed-off-by: Sasha Levin --- drivers/block/Kconfig | 8 +------- drivers/block/Makefile | 7 +------ drivers/block/null_blk/Kconfig | 12 ++++++++++++ drivers/block/null_blk/Makefile | 11 +++++++++++ drivers/block/{null_blk_main.c => null_blk/main.c} | 0 drivers/block/{ => null_blk}/null_blk.h | 0 drivers/block/{null_blk_trace.c => null_blk/trace.c} | 2 +- drivers/block/{null_blk_trace.h => null_blk/trace.h} | 2 +- drivers/block/{null_blk_zoned.c => null_blk/zoned.c} | 2 +- 9 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 drivers/block/null_blk/Kconfig create mode 100644 drivers/block/null_blk/Makefile rename drivers/block/{null_blk_main.c => null_blk/main.c} (100%) rename drivers/block/{ => null_blk}/null_blk.h (100%) rename drivers/block/{null_blk_trace.c => null_blk/trace.c} (93%) rename drivers/block/{null_blk_trace.h => null_blk/trace.h} (97%) rename drivers/block/{null_blk_zoned.c => null_blk/zoned.c} (99%) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 40c53632512b..9617688b58b3 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -16,13 +16,7 @@ menuconfig BLK_DEV if BLK_DEV -config BLK_DEV_NULL_BLK - tristate "Null test block driver" - select CONFIGFS_FS - -config BLK_DEV_NULL_BLK_FAULT_INJECTION - bool "Support fault injection for Null test block driver" - depends on BLK_DEV_NULL_BLK && FAULT_INJECTION +source "drivers/block/null_blk/Kconfig" config BLK_DEV_FD tristate "Normal floppy disk support" diff --git a/drivers/block/Makefile b/drivers/block/Makefile index e1f63117ee94..a3170859e01d 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -41,12 +41,7 @@ obj-$(CONFIG_BLK_DEV_RSXX) += rsxx/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_BLK_DEV_RNBD) += rnbd/ -obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk.o -null_blk-objs := null_blk_main.o -ifeq ($(CONFIG_BLK_DEV_ZONED), y) -null_blk-$(CONFIG_TRACING) += null_blk_trace.o -endif -null_blk-$(CONFIG_BLK_DEV_ZONED) += null_blk_zoned.o +obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ skd-y := skd_main.o swim_mod-y := swim.o swim_asm.o diff --git a/drivers/block/null_blk/Kconfig b/drivers/block/null_blk/Kconfig new file mode 100644 index 000000000000..6bf1f8ca20a2 --- /dev/null +++ b/drivers/block/null_blk/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Null block device driver configuration +# + +config BLK_DEV_NULL_BLK + tristate "Null test block driver" + select CONFIGFS_FS + +config BLK_DEV_NULL_BLK_FAULT_INJECTION + bool "Support fault injection for Null test block driver" + depends on BLK_DEV_NULL_BLK && FAULT_INJECTION diff --git a/drivers/block/null_blk/Makefile b/drivers/block/null_blk/Makefile new file mode 100644 index 000000000000..84c36e512ab8 --- /dev/null +++ b/drivers/block/null_blk/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 + +# needed for trace events +ccflags-y += -I$(src) + +obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk.o +null_blk-objs := main.o +ifeq ($(CONFIG_BLK_DEV_ZONED), y) +null_blk-$(CONFIG_TRACING) += trace.o +endif +null_blk-$(CONFIG_BLK_DEV_ZONED) += zoned.o diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk/main.c similarity index 100% rename from drivers/block/null_blk_main.c rename to drivers/block/null_blk/main.c diff --git a/drivers/block/null_blk.h b/drivers/block/null_blk/null_blk.h similarity index 100% rename from drivers/block/null_blk.h rename to drivers/block/null_blk/null_blk.h diff --git a/drivers/block/null_blk_trace.c b/drivers/block/null_blk/trace.c similarity index 93% rename from drivers/block/null_blk_trace.c rename to drivers/block/null_blk/trace.c index f246e7bff698..3711cba16071 100644 --- a/drivers/block/null_blk_trace.c +++ b/drivers/block/null_blk/trace.c @@ -4,7 +4,7 @@ * * Copyright (C) 2020 Western Digital Corporation or its affiliates. */ -#include "null_blk_trace.h" +#include "trace.h" /* * Helper to use for all null_blk traces to extract disk name. diff --git a/drivers/block/null_blk_trace.h b/drivers/block/null_blk/trace.h similarity index 97% rename from drivers/block/null_blk_trace.h rename to drivers/block/null_blk/trace.h index 4f83032eb544..ce3b430e88c5 100644 --- a/drivers/block/null_blk_trace.h +++ b/drivers/block/null_blk/trace.h @@ -73,7 +73,7 @@ TRACE_EVENT(nullb_report_zones, #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . #undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE null_blk_trace +#define TRACE_INCLUDE_FILE trace /* This part must be outside protection */ #include diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk/zoned.c similarity index 99% rename from drivers/block/null_blk_zoned.c rename to drivers/block/null_blk/zoned.c index f5df82c26c16..41220ce59659 100644 --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -4,7 +4,7 @@ #include "null_blk.h" #define CREATE_TRACE_POINTS -#include "null_blk_trace.h" +#include "trace.h" #define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT) From 4cf15887a41be1e8c723788846c3c412ed856df0 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 14 Mar 2023 13:11:05 +0900 Subject: [PATCH 0766/1017] block: null_blk: Fix handling of fake timeout request [ Upstream commit 63f886597085f346276e3b3c8974de0100d65f32 ] When injecting a fake timeout into the null_blk driver using fail_io_timeout, the request timeout handler does not execute blk_mq_complete_request(), so the complete callback is never executed for a timedout request. The null_blk driver also has a driver-specific fake timeout mechanism which does not have this problem. Fix the problem with fail_io_timeout by using the same meachanism as null_blk internal timeout feature, using the fake_timeout field of null_blk commands. Reported-by: Akinobu Mita Fixes: de3510e52b0a ("null_blk: fix command timeout completion handling") Signed-off-by: Damien Le Moal Reviewed-by: Johannes Thumshirn Link: https://lore.kernel.org/r/20230314041106.19173-2-damien.lemoal@opensource.wdc.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/null_blk/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index c6ba8f9f3f31..25db095e943b 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1309,8 +1309,7 @@ static inline void nullb_complete_cmd(struct nullb_cmd *cmd) case NULL_IRQ_SOFTIRQ: switch (cmd->nq->dev->queue_mode) { case NULL_Q_MQ: - if (likely(!blk_should_fake_timeout(cmd->rq->q))) - blk_mq_complete_request(cmd->rq); + blk_mq_complete_request(cmd->rq); break; case NULL_Q_BIO: /* @@ -1486,7 +1485,8 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, cmd->rq = bd->rq; cmd->error = BLK_STS_OK; cmd->nq = nq; - cmd->fake_timeout = should_timeout_request(bd->rq); + cmd->fake_timeout = should_timeout_request(bd->rq) || + blk_should_fake_timeout(bd->rq->q); blk_mq_start_request(bd->rq); From 9ebc344ce547206de488215eaaa96e5f007548b2 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sat, 4 Mar 2023 07:13:45 +0800 Subject: [PATCH 0767/1017] nvme: fix handling single range discard request [ Upstream commit 37f0dc2ec78af0c3f35dd05578763de059f6fe77 ] When investigating one customer report on warning in nvme_setup_discard, we observed the controller(nvme/tcp) actually exposes queue_max_discard_segments(req->q) == 1. Obviously the current code can't handle this situation, since contiguity merge like normal RW request is taken. Fix the issue by building range from request sector/nr_sectors directly. Fixes: b35ba01ea697 ("nvme: support ranged discard requests") Signed-off-by: Ming Lei Reviewed-by: Chaitanya Kulkarni Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/core.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index e162f1dfbafe..a4b6aa932a8f 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -723,16 +723,26 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req, range = page_address(ns->ctrl->discard_page); } - __rq_for_each_bio(bio, req) { - u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); - u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; + if (queue_max_discard_segments(req->q) == 1) { + u64 slba = nvme_sect_to_lba(ns, blk_rq_pos(req)); + u32 nlb = blk_rq_sectors(req) >> (ns->lba_shift - 9); - if (n < segments) { - range[n].cattr = cpu_to_le32(0); - range[n].nlb = cpu_to_le32(nlb); - range[n].slba = cpu_to_le64(slba); + range[0].cattr = cpu_to_le32(0); + range[0].nlb = cpu_to_le32(nlb); + range[0].slba = cpu_to_le64(slba); + n = 1; + } else { + __rq_for_each_bio(bio, req) { + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); + u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; + + if (n < segments) { + range[n].cattr = cpu_to_le32(0); + range[n].nlb = cpu_to_le32(nlb); + range[n].slba = cpu_to_le64(slba); + } + n++; } - n++; } if (WARN_ON_ONCE(n != segments)) { From a6317235da8aa7cb97529ebc8121cc2a4c4c437a Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Mon, 6 Mar 2023 10:13:13 +0900 Subject: [PATCH 0768/1017] nvmet: avoid potential UAF in nvmet_req_complete() [ Upstream commit 6173a77b7e9d3e202bdb9897b23f2a8afe7bf286 ] An nvme target ->queue_response() operation implementation may free the request passed as argument. Such implementation potentially could result in a use after free of the request pointer when percpu_ref_put() is called in nvmet_req_complete(). Avoid such problem by using a local variable to save the sq pointer before calling __nvmet_req_complete(), thus avoiding dereferencing the req pointer after that function call. Fixes: a07b4970f464 ("nvmet: add a generic NVMe target") Signed-off-by: Damien Le Moal Reviewed-by: Chaitanya Kulkarni Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index bc88ff2912f5..a82a0796a614 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -749,8 +749,10 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status) void nvmet_req_complete(struct nvmet_req *req, u16 status) { + struct nvmet_sq *sq = req->sq; + __nvmet_req_complete(req, status); - percpu_ref_put(&req->sq->ref); + percpu_ref_put(&sq->ref); } EXPORT_SYMBOL_GPL(nvmet_req_complete); From 2f28cb5c2a510185fec4a52e9ca20d78ce72f57d Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 15 Mar 2023 14:20:32 +0800 Subject: [PATCH 0769/1017] block: sunvdc: add check for mdesc_grab() returning NULL [ Upstream commit 6030363199e3a6341afb467ddddbed56640cbf6a ] In vdc_port_probe(), we should check the return value of mdesc_grab() as it may return NULL, which can cause potential NPD bug. Fixes: 43fdf27470b2 ("[SPARC64]: Abstract out mdesc accesses for better MD update handling.") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20230315062032.1741692-1-windhl@126.com [axboe: style cleanup] Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/sunvdc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 39aeebc6837d..d9e41d3bbe71 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -984,6 +984,8 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) print_version(); hp = mdesc_grab(); + if (!hp) + return -ENODEV; err = -ENODEV; if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) { From cccba1ff0798a27f7b8d0c06762ef977400a2afb Mon Sep 17 00:00:00 2001 From: Maciej Fijalkowski Date: Tue, 14 Mar 2023 10:45:43 -0700 Subject: [PATCH 0770/1017] ice: xsk: disable txq irq before flushing hw [ Upstream commit b830c9642386867863ac64295185f896ff2928ac ] ice_qp_dis() intends to stop a given queue pair that is a target of xsk pool attach/detach. One of the steps is to disable interrupts on these queues. It currently is broken in a way that txq irq is turned off *after* HW flush which in turn takes no effect. ice_qp_dis(): -> ice_qvec_dis_irq() --> disable rxq irq --> flush hw -> ice_vsi_stop_tx_ring() -->disable txq irq Below splat can be triggered by following steps: - start xdpsock WITHOUT loading xdp prog - run xdp_rxq_info with XDP_TX action on this interface - start traffic - terminate xdpsock [ 256.312485] BUG: kernel NULL pointer dereference, address: 0000000000000018 [ 256.319560] #PF: supervisor read access in kernel mode [ 256.324775] #PF: error_code(0x0000) - not-present page [ 256.329994] PGD 0 P4D 0 [ 256.332574] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 256.337006] CPU: 3 PID: 32 Comm: ksoftirqd/3 Tainted: G OE 6.2.0-rc5+ #51 [ 256.345218] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0008.031920191559 03/19/2019 [ 256.355807] RIP: 0010:ice_clean_rx_irq_zc+0x9c/0x7d0 [ice] [ 256.361423] Code: b7 8f 8a 00 00 00 66 39 ca 0f 84 f1 04 00 00 49 8b 47 40 4c 8b 24 d0 41 0f b7 45 04 66 25 ff 3f 66 89 04 24 0f 84 85 02 00 00 <49> 8b 44 24 18 0f b7 14 24 48 05 00 01 00 00 49 89 04 24 49 89 44 [ 256.380463] RSP: 0018:ffffc900088bfd20 EFLAGS: 00010206 [ 256.385765] RAX: 000000000000003c RBX: 0000000000000035 RCX: 000000000000067f [ 256.393012] RDX: 0000000000000775 RSI: 0000000000000000 RDI: ffff8881deb3ac80 [ 256.400256] RBP: 000000000000003c R08: ffff889847982710 R09: 0000000000010000 [ 256.407500] R10: ffffffff82c060c0 R11: 0000000000000004 R12: 0000000000000000 [ 256.414746] R13: ffff88811165eea0 R14: ffffc9000d255000 R15: ffff888119b37600 [ 256.421990] FS: 0000000000000000(0000) GS:ffff8897e0cc0000(0000) knlGS:0000000000000000 [ 256.430207] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 256.436036] CR2: 0000000000000018 CR3: 0000000005c0a006 CR4: 00000000007706e0 [ 256.443283] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 256.450527] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 256.457770] PKRU: 55555554 [ 256.460529] Call Trace: [ 256.463015] [ 256.465157] ? ice_xmit_zc+0x6e/0x150 [ice] [ 256.469437] ice_napi_poll+0x46d/0x680 [ice] [ 256.473815] ? _raw_spin_unlock_irqrestore+0x1b/0x40 [ 256.478863] __napi_poll+0x29/0x160 [ 256.482409] net_rx_action+0x136/0x260 [ 256.486222] __do_softirq+0xe8/0x2e5 [ 256.489853] ? smpboot_thread_fn+0x2c/0x270 [ 256.494108] run_ksoftirqd+0x2a/0x50 [ 256.497747] smpboot_thread_fn+0x1c1/0x270 [ 256.501907] ? __pfx_smpboot_thread_fn+0x10/0x10 [ 256.506594] kthread+0xea/0x120 [ 256.509785] ? __pfx_kthread+0x10/0x10 [ 256.513597] ret_from_fork+0x29/0x50 [ 256.517238] In fact, irqs were not disabled and napi managed to be scheduled and run while xsk_pool pointer was still valid, but SW ring of xdp_buff pointers was already freed. To fix this, call ice_qvec_dis_irq() after ice_vsi_stop_tx_ring(). Also while at it, remove redundant ice_clean_rx_ring() call - this is handled in ice_qp_clean_rings(). Fixes: 2d4238f55697 ("ice: Add support for AF_XDP") Signed-off-by: Maciej Fijalkowski Reviewed-by: Larysa Zaremba Tested-by: Chandan Kumar Rout (A Contingent Worker at Intel) Acked-by: John Fastabend Signed-off-by: Tony Nguyen Reviewed-by: Leon Romanovsky Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_xsk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c index 59963b901be0..e0790df700e2 100644 --- a/drivers/net/ethernet/intel/ice/ice_xsk.c +++ b/drivers/net/ethernet/intel/ice/ice_xsk.c @@ -169,8 +169,6 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx) } netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx)); - ice_qvec_dis_irq(vsi, rx_ring, q_vector); - ice_fill_txq_meta(vsi, tx_ring, &txq_meta); err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, tx_ring, &txq_meta); if (err) @@ -185,6 +183,8 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx) if (err) return err; } + ice_qvec_dis_irq(vsi, rx_ring, q_vector); + err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true); if (err) return err; From 1f0586dcc0768e95006c99598fe101302f78fac1 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 14 Mar 2023 20:24:05 +0200 Subject: [PATCH 0771/1017] net: dsa: mv88e6xxx: fix max_mtu of 1492 on 6165, 6191, 6220, 6250, 6290 [ Upstream commit 7e9517375a14f44ee830ca1c3278076dd65fcc8f ] There are 3 classes of switch families that the driver is aware of, as far as mv88e6xxx_change_mtu() is concerned: - MTU configuration is available per port. Here, the chip->info->ops->port_set_jumbo_size() method will be present. - MTU configuration is global to the switch. Here, the chip->info->ops->set_max_frame_size() method will be present. - We don't know how to change the MTU. Here, none of the above methods will be present. Switch families MV88E6165, MV88E6191, MV88E6220, MV88E6250 and MV88E6290 fall in category 3. The blamed commit has adjusted the MTU for all 3 categories by EDSA_HLEN (8 bytes), resulting in a new maximum MTU of 1492 being reported by the driver for these switches. I don't have the hardware to test, but I do have a MV88E6390 switch on which I can simulate this by commenting out its .port_set_jumbo_size definition from mv88e6390_ops. The result is this set of messages at probe time: mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 1 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 2 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 3 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 4 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 5 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 6 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 7 mv88e6085 d0032004.mdio-mii:10: nonfatal error -34 setting MTU to 1500 on port 8 It is highly implausible that there exist Ethernet switches which don't support the standard MTU of 1500 octets, and this is what the DSA framework says as well - the error comes from dsa_slave_create() -> dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN). But the error messages are alarming, and it would be good to suppress them. As a consequence of this unlikeliness, we reimplement mv88e6xxx_get_max_mtu() and mv88e6xxx_change_mtu() on switches from the 3rd category as follows: the maximum supported MTU is 1500, and any request to set the MTU to a value larger than that fails in dev_validate_mtu(). Fixes: b9c587fed61c ("dsa: mv88e6xxx: Include tagger overhead when setting MTU for DSA and CPU ports") Signed-off-by: Vladimir Oltean Reviewed-by: Simon Horman Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/dsa/mv88e6xxx/chip.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 371b345635e6..a253476a52b0 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2734,7 +2734,7 @@ static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port) return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; else if (chip->info->ops->set_max_frame_size) return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; - return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; + return ETH_DATA_LEN; } static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) @@ -2742,6 +2742,17 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) struct mv88e6xxx_chip *chip = ds->priv; int ret = 0; + /* For families where we don't know how to alter the MTU, + * just accept any value up to ETH_DATA_LEN + */ + if (!chip->info->ops->port_set_jumbo_size && + !chip->info->ops->set_max_frame_size) { + if (new_mtu > ETH_DATA_LEN) + return -EINVAL; + + return 0; + } + if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) new_mtu += EDSA_HLEN; @@ -2750,9 +2761,6 @@ static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu); else if (chip->info->ops->set_max_frame_size) ret = chip->info->ops->set_max_frame_size(chip, new_mtu); - else - if (new_mtu > 1522) - ret = -EINVAL; mv88e6xxx_reg_unlock(chip); return ret; From 013fae04b8ff8b00ad7c60633b4d3ae2c22d1086 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 15 Mar 2023 14:40:09 +0200 Subject: [PATCH 0772/1017] ipv4: Fix incorrect table ID in IOCTL path [ Upstream commit 8a2618e14f81604a9b6ad305d57e0c8da939cd65 ] Commit f96a3d74554d ("ipv4: Fix incorrect route flushing when source address is deleted") started to take the table ID field in the FIB info structure into account when determining if two structures are identical or not. This field is initialized using the 'fc_table' field in the route configuration structure, which is not set when adding a route via IOCTL. The above can result in user space being able to install two identical routes that only differ in the table ID field of their associated FIB info. Fix by initializing the table ID field in the route configuration structure in the IOCTL path. Before the fix: # ip route add default via 192.0.2.2 # route add default gw 192.0.2.2 # ip -4 r show default # default via 192.0.2.2 dev dummy10 # default via 192.0.2.2 dev dummy10 After the fix: # ip route add default via 192.0.2.2 # route add default gw 192.0.2.2 SIOCADDRT: File exists # ip -4 r show default default via 192.0.2.2 dev dummy10 Audited the code paths to ensure there are no other paths that do not properly initialize the route configuration structure when installing a route. Fixes: 5a56a0b3a45d ("net: Don't delete routes in different VRFs") Fixes: f96a3d74554d ("ipv4: Fix incorrect route flushing when source address is deleted") Reported-by: gaoxingwang Link: https://lore.kernel.org/netdev/20230314144159.2354729-1-gaoxingwang1@huawei.com/ Tested-by: gaoxingwang Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20230315124009.4015212-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/fib_frontend.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 5f786ef662ea..41f890bf9d4c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -573,6 +573,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, cfg->fc_scope = RT_SCOPE_UNIVERSE; } + if (!cfg->fc_table) + cfg->fc_table = RT_TABLE_MAIN; + if (cmd == SIOCDELRT) return 0; From 2cc46ed406bb325f10a251b03d9a83ae67b3d3d8 Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Thu, 16 Mar 2023 12:05:40 +0100 Subject: [PATCH 0773/1017] net: usb: smsc75xx: Move packet length check to prevent kernel panic in skb_pull [ Upstream commit 43ffe6caccc7a1bb9d7442fbab521efbf6c1378c ] Packet length check needs to be located after size and align_count calculation to prevent kernel panic in skb_pull() in case rx_cmd_a & RX_CMD_A_RED evaluates to true. Fixes: d8b228318935 ("net: usb: smsc75xx: Limit packet length to skb->len") Signed-off-by: Szymon Heidrich Link: https://lore.kernel.org/r/20230316110540.77531-1-szymon.heidrich@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/usb/smsc75xx.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 0b3d11e28faa..fb1389bd0939 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -2199,6 +2199,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING; align_count = (4 - ((size + RXW_PADDING) % 4)) % 4; + if (unlikely(size > skb->len)) { + netif_dbg(dev, rx_err, dev->net, + "size err rx_cmd_a=0x%08x\n", + rx_cmd_a); + return 0; + } + if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { netif_dbg(dev, rx_err, dev->net, "Error rx_cmd_a=0x%08x\n", rx_cmd_a); @@ -2211,8 +2218,7 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) dev->net->stats.rx_frame_errors++; } else { /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12) || - size > skb->len)) { + if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { netif_dbg(dev, rx_err, dev->net, "size err rx_cmd_a=0x%08x\n", rx_cmd_a); From bd2e78462ae18484e55ae4d285df2c86b86bdd12 Mon Sep 17 00:00:00 2001 From: Alexandra Winter Date: Wed, 15 Mar 2023 14:14:35 +0100 Subject: [PATCH 0774/1017] net/iucv: Fix size of interrupt data [ Upstream commit 3d87debb8ed2649608ff432699e7c961c0c6f03b ] iucv_irq_data needs to be 4 bytes larger. These bytes are not used by the iucv module, but written by the z/VM hypervisor in case a CPU is deconfigured. Reported as: BUG dma-kmalloc-64 (Not tainted): kmalloc Redzone overwritten ----------------------------------------------------------------------------- 0x0000000000400564-0x0000000000400567 @offset=1380. First byte 0x80 instead of 0xcc Allocated in iucv_cpu_prepare+0x44/0xd0 age=167839 cpu=2 pid=1 __kmem_cache_alloc_node+0x166/0x450 kmalloc_node_trace+0x3a/0x70 iucv_cpu_prepare+0x44/0xd0 cpuhp_invoke_callback+0x156/0x2f0 cpuhp_issue_call+0xf0/0x298 __cpuhp_setup_state_cpuslocked+0x136/0x338 __cpuhp_setup_state+0xf4/0x288 iucv_init+0xf4/0x280 do_one_initcall+0x78/0x390 do_initcalls+0x11a/0x140 kernel_init_freeable+0x25e/0x2a0 kernel_init+0x2e/0x170 __ret_from_fork+0x3c/0x58 ret_from_fork+0xa/0x40 Freed in iucv_init+0x92/0x280 age=167839 cpu=2 pid=1 __kmem_cache_free+0x308/0x358 iucv_init+0x92/0x280 do_one_initcall+0x78/0x390 do_initcalls+0x11a/0x140 kernel_init_freeable+0x25e/0x2a0 kernel_init+0x2e/0x170 __ret_from_fork+0x3c/0x58 ret_from_fork+0xa/0x40 Slab 0x0000037200010000 objects=32 used=30 fp=0x0000000000400640 flags=0x1ffff00000010200(slab|head|node=0|zone=0| Object 0x0000000000400540 @offset=1344 fp=0x0000000000000000 Redzone 0000000000400500: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ Redzone 0000000000400510: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ Redzone 0000000000400520: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ Redzone 0000000000400530: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ Object 0000000000400540: 00 01 00 03 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object 0000000000400550: f3 86 81 f2 f4 82 f8 82 f0 f0 f0 f0 f0 f0 f0 f2 ................ Object 0000000000400560: 00 00 00 00 80 00 00 00 cc cc cc cc cc cc cc cc ................ Object 0000000000400570: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ................ Redzone 0000000000400580: cc cc cc cc cc cc cc cc ........ Padding 00000000004005d4: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ Padding 00000000004005e4: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ Padding 00000000004005f4: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZ CPU: 6 PID: 121030 Comm: 116-pai-crypto. Not tainted 6.3.0-20230221.rc0.git4.99b8246b2d71.300.fc37.s390x+debug #1 Hardware name: IBM 3931 A01 704 (z/VM 7.3.0) Call Trace: [<000000032aa034ec>] dump_stack_lvl+0xac/0x100 [<0000000329f5a6cc>] check_bytes_and_report+0x104/0x140 [<0000000329f5aa78>] check_object+0x370/0x3c0 [<0000000329f5ede6>] free_debug_processing+0x15e/0x348 [<0000000329f5f06a>] free_to_partial_list+0x9a/0x2f0 [<0000000329f5f4a4>] __slab_free+0x1e4/0x3a8 [<0000000329f61768>] __kmem_cache_free+0x308/0x358 [<000000032a91465c>] iucv_cpu_dead+0x6c/0x88 [<0000000329c2fc66>] cpuhp_invoke_callback+0x156/0x2f0 [<000000032aa062da>] _cpu_down.constprop.0+0x22a/0x5e0 [<0000000329c3243e>] cpu_device_down+0x4e/0x78 [<000000032a61dee0>] device_offline+0xc8/0x118 [<000000032a61e048>] online_store+0x60/0xe0 [<000000032a08b6b0>] kernfs_fop_write_iter+0x150/0x1e8 [<0000000329fab65c>] vfs_write+0x174/0x360 [<0000000329fab9fc>] ksys_write+0x74/0x100 [<000000032aa03a5a>] __do_syscall+0x1da/0x208 [<000000032aa177b2>] system_call+0x82/0xb0 INFO: lockdep is turned off. FIX dma-kmalloc-64: Restoring kmalloc Redzone 0x0000000000400564-0x0000000000400567=0xcc FIX dma-kmalloc-64: Object at 0x0000000000400540 not freed Fixes: 2356f4cb1911 ("[S390]: Rewrite of the IUCV base code, part 2") Signed-off-by: Alexandra Winter Link: https://lore.kernel.org/r/20230315131435.4113889-1-wintera@linux.ibm.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/iucv/iucv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 349c6ac3313f..6f84978a7726 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -83,7 +83,7 @@ struct iucv_irq_data { u16 ippathid; u8 ipflags1; u8 iptype; - u32 res2[8]; + u32 res2[9]; }; struct iucv_irq_list { From 1c06d12237282200566a556be965f4d7801d6ec8 Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Thu, 16 Mar 2023 00:53:53 +0800 Subject: [PATCH 0775/1017] selftests: net: devlink_port_split.py: skip test if no suitable device available [ Upstream commit 24994513ad13ff2c47ba91d2b5df82c3d496c370 ] The `devlink -j port show` command output may not contain the "flavour" key, an example from Ubuntu 22.10 s390x LPAR(5.19.0-37-generic), with mlx4 driver and iproute2-5.15.0: {"port":{"pci/0001:00:00.0/1":{"type":"eth","netdev":"ens301"}, "pci/0001:00:00.0/2":{"type":"eth","netdev":"ens301d1"}, "pci/0002:00:00.0/1":{"type":"eth","netdev":"ens317"}, "pci/0002:00:00.0/2":{"type":"eth","netdev":"ens317d1"}}} This will cause a KeyError exception. Create a validate_devlink_output() to check for this "flavour" from devlink command output to avoid this KeyError exception. Also let it handle the check for `devlink -j dev show` output in main(). Apart from this, if the test was not started because the max lanes of the designated device is 0. The script will still return 0 and thus causing a false-negative test result. Use a found_max_lanes flag to determine if these tests were skipped due to this reason and return KSFT_SKIP to make it more clear. Link: https://bugs.launchpad.net/bugs/1937133 Fixes: f3348a82e727 ("selftests: net: Add port split test") Signed-off-by: Po-Hsu Lin Link: https://lore.kernel.org/r/20230315165353.229590-1-po-hsu.lin@canonical.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- .../selftests/net/devlink_port_split.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tools/testing/selftests/net/devlink_port_split.py b/tools/testing/selftests/net/devlink_port_split.py index 834066d465fc..f0fbd7367f4f 100755 --- a/tools/testing/selftests/net/devlink_port_split.py +++ b/tools/testing/selftests/net/devlink_port_split.py @@ -57,6 +57,8 @@ class devlink_ports(object): assert stderr == "" ports = json.loads(stdout)['port'] + validate_devlink_output(ports, 'flavour') + for port in ports: if dev in port: if ports[port]['flavour'] == 'physical': @@ -218,6 +220,27 @@ def split_splittable_port(port, k, lanes, dev): unsplit(port.bus_info) +def validate_devlink_output(devlink_data, target_property=None): + """ + Determine if test should be skipped by checking: + 1. devlink_data contains values + 2. The target_property exist in devlink_data + """ + skip_reason = None + if any(devlink_data.values()): + if target_property: + skip_reason = "{} not found in devlink output, test skipped".format(target_property) + for key in devlink_data: + if target_property in devlink_data[key]: + skip_reason = None + else: + skip_reason = 'devlink output is empty, test skipped' + + if skip_reason: + print(skip_reason) + sys.exit(KSFT_SKIP) + + def make_parser(): parser = argparse.ArgumentParser(description='A test for port splitting.') parser.add_argument('--dev', @@ -238,6 +261,7 @@ def main(cmdline=None): stdout, stderr = run_command(cmd) assert stderr == "" + validate_devlink_output(json.loads(stdout)) devs = json.loads(stdout)['dev'] dev = list(devs.keys())[0] @@ -249,6 +273,7 @@ def main(cmdline=None): ports = devlink_ports(dev) + found_max_lanes = False for port in ports.if_names: max_lanes = get_max_lanes(port.name) @@ -271,6 +296,11 @@ def main(cmdline=None): split_splittable_port(port, lane, max_lanes, dev) lane //= 2 + found_max_lanes = True + + if not found_max_lanes: + print(f"Test not started, no port of device {dev} reports max_lanes") + sys.exit(KSFT_SKIP) if __name__ == "__main__": From eb80cb66a2c5e94794bcb52fc6272a7ab20152f4 Mon Sep 17 00:00:00 2001 From: Daniil Tatianin Date: Wed, 15 Mar 2023 22:46:18 +0300 Subject: [PATCH 0776/1017] qed/qed_mng_tlv: correctly zero out ->min instead of ->hour [ Upstream commit 470efd68a4653d9819d391489886432cd31bcd0b ] This fixes an issue where ->hour would erroneously get zeroed out instead of ->min because of a bad copy paste. Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Fixes: f240b6882211 ("qed: Add support for processing fcoe tlv request.") Signed-off-by: Daniil Tatianin Link: https://lore.kernel.org/r/20230315194618.579286-1-d-tatianin@yandex-team.ru Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c b/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c index 3e3192a3ad9b..fdbd5f07a185 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mng_tlv.c @@ -422,7 +422,7 @@ qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time, if (p_time->hour > 23) p_time->hour = 0; if (p_time->min > 59) - p_time->hour = 0; + p_time->min = 0; if (p_time->msec > 999) p_time->msec = 0; if (p_time->usec > 999) From d4dbd26f985c1cb9a36610708beb01cf0ed95741 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 15 Mar 2023 14:00:21 +0800 Subject: [PATCH 0777/1017] ethernet: sun: add check for the mdesc_grab() [ Upstream commit 90de546d9a0b3c771667af18bb3f80567eabb89b ] In vnet_port_probe() and vsw_port_probe(), we should check the return value of mdesc_grab() as it may return NULL which can caused NPD bugs. Fixes: 5d01fa0c6bd8 ("ldmvsw: Add ldmvsw.c driver code") Fixes: 43fdf27470b2 ("[SPARC64]: Abstract out mdesc accesses for better MD update handling.") Signed-off-by: Liang He Reviewed-by: Piotr Raczynski Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/sun/ldmvsw.c | 3 +++ drivers/net/ethernet/sun/sunvnet.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c index 01ea0d6f8819..934a4b54784b 100644 --- a/drivers/net/ethernet/sun/ldmvsw.c +++ b/drivers/net/ethernet/sun/ldmvsw.c @@ -290,6 +290,9 @@ static int vsw_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) hp = mdesc_grab(); + if (!hp) + return -ENODEV; + rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); err = -ENODEV; if (!rmac) { diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 96b883f965f6..b6c03adf1e76 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -431,6 +431,9 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) hp = mdesc_grab(); + if (!hp) + return -ENODEV; + vp = vnet_find_parent(hp, vdev->mp, vdev); if (IS_ERR(vp)) { pr_err("Cannot find port parent vnet\n"); From aff84fadba53befed494a28c84544c87fce908c4 Mon Sep 17 00:00:00 2001 From: Tony O'Brien Date: Wed, 22 Feb 2023 13:52:27 +1300 Subject: [PATCH 0778/1017] hwmon: (adt7475) Display smoothing attributes in correct order [ Upstream commit 5f8d1e3b6f9b5971f9c06d5846ce00c49e3a8d94 ] Throughout the ADT7475 driver, attributes relating to the temperature sensors are displayed in the order Remote 1, Local, Remote 2. Make temp_st_show() conform to this expectation so that values set by temp_st_store() can be displayed using the correct attribute. Fixes: 8f05bcc33e74 ("hwmon: (adt7475) temperature smoothing") Signed-off-by: Tony O'Brien Link: https://lore.kernel.org/r/20230222005228.158661-2-tony.obrien@alliedtelesis.co.nz Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/adt7475.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index 9d5b019651f2..c7f19a1ca0a5 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -554,11 +554,11 @@ static ssize_t temp_st_show(struct device *dev, struct device_attribute *attr, val = data->enh_acoustics[0] & 0xf; break; case 1: - val = (data->enh_acoustics[1] >> 4) & 0xf; + val = data->enh_acoustics[1] & 0xf; break; case 2: default: - val = data->enh_acoustics[1] & 0xf; + val = (data->enh_acoustics[1] >> 4) & 0xf; break; } From 4a8c3ad12c9dd6456ae3fade707166935bf29ba5 Mon Sep 17 00:00:00 2001 From: Tony O'Brien Date: Wed, 22 Feb 2023 13:52:28 +1300 Subject: [PATCH 0779/1017] hwmon: (adt7475) Fix masking of hysteresis registers [ Upstream commit 48e8186870d9d0902e712d601ccb7098cb220688 ] The wrong bits are masked in the hysteresis register; indices 0 and 2 should zero bits [7:4] and preserve bits [3:0], and index 1 should zero bits [3:0] and preserve bits [7:4]. Fixes: 1c301fc5394f ("hwmon: Add a driver for the ADT7475 hardware monitoring chip") Signed-off-by: Tony O'Brien Link: https://lore.kernel.org/r/20230222005228.158661-3-tony.obrien@alliedtelesis.co.nz Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/adt7475.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c index c7f19a1ca0a5..6b84822e7d93 100644 --- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -486,10 +486,10 @@ static ssize_t temp_store(struct device *dev, struct device_attribute *attr, val = (temp - val) / 1000; if (sattr->index != 1) { - data->temp[HYSTERSIS][sattr->index] &= 0xF0; + data->temp[HYSTERSIS][sattr->index] &= 0x0F; data->temp[HYSTERSIS][sattr->index] |= (val & 0xF) << 4; } else { - data->temp[HYSTERSIS][sattr->index] &= 0x0F; + data->temp[HYSTERSIS][sattr->index] &= 0xF0; data->temp[HYSTERSIS][sattr->index] |= (val & 0xF); } From 0a73c8b3cc99d214dff83c51805c844240c4f749 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Fri, 10 Mar 2023 16:40:07 +0800 Subject: [PATCH 0780/1017] hwmon: (xgene) Fix use after free bug in xgene_hwmon_remove due to race condition [ Upstream commit cb090e64cf25602b9adaf32d5dfc9c8bec493cd1 ] In xgene_hwmon_probe, &ctx->workq is bound with xgene_hwmon_evt_work. Then it will be started. If we remove the driver which will call xgene_hwmon_remove to clean up, there may be unfinished work. The possible sequence is as follows: Fix it by finishing the work before cleanup in xgene_hwmon_remove. CPU0 CPU1 |xgene_hwmon_evt_work xgene_hwmon_remove | kfifo_free(&ctx->async_msg_fifo);| | |kfifo_out_spinlocked |//use &ctx->async_msg_fifo Fixes: 2ca492e22cb7 ("hwmon: (xgene) Fix crash when alarm occurs before driver probe") Signed-off-by: Zheng Wang Link: https://lore.kernel.org/r/20230310084007.1403388-1-zyytlz.wz@163.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/xgene-hwmon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c index f2a5af239c95..f5d3cf86753f 100644 --- a/drivers/hwmon/xgene-hwmon.c +++ b/drivers/hwmon/xgene-hwmon.c @@ -768,6 +768,7 @@ static int xgene_hwmon_remove(struct platform_device *pdev) { struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev); + cancel_work_sync(&ctx->workq); hwmon_device_unregister(ctx->hwmon_dev); kfifo_free(&ctx->async_msg_fifo); if (acpi_disabled) From 663c3afee81ea56952293b869c623e7dd20548ec Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Fri, 10 Mar 2023 08:50:35 +0100 Subject: [PATCH 0781/1017] hwmon: (ina3221) return prober error code [ Upstream commit c93f5e2ab53243b17febabb9422a697017d3d49a ] ret is set to 0 which do not indicate an error. Return -EINVAL instead. Fixes: a9e9dd9c6de5 ("hwmon: (ina3221) Read channel input source info from DT") Signed-off-by: Marcus Folkesson Link: https://lore.kernel.org/r/20230310075035.246083-1-marcus.folkesson@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/ina3221.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index d3c98115042b..836e7579e166 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -772,7 +772,7 @@ static int ina3221_probe_child_from_dt(struct device *dev, return ret; } else if (val > INA3221_CHANNEL3) { dev_err(dev, "invalid reg %d of %pOFn\n", val, child); - return ret; + return -EINVAL; } input = &ina->inputs[val]; From c5bd9719b53be9afe872bc03a88ba5df3a5fd00e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 12 Mar 2023 09:03:12 -0700 Subject: [PATCH 0782/1017] hwmon: (ucd90320) Add minimum delay between bus accesses [ Upstream commit 8d655e65237643c48ada2c131b83679bf1105373 ] When probing the ucd90320 access to some of the registers randomly fails. Sometimes it NACKs a transfer, sometimes it returns just random data and the PEC check fails. Experimentation shows that this seems to be triggered by a register access directly back to back with a previous register write. Experimentation also shows that inserting a small delay after register writes makes the issue go away. Use a similar solution to what the max15301 driver does to solve the same problem. Create a custom set of bus read and write functions that make sure that the delay is added. Fixes: a470f11c5ba2 ("hwmon: (pmbus/ucd9000) Add support for UCD90320 Power Sequencer") Signed-off-by: Lars-Peter Clausen Link: https://lore.kernel.org/r/20230312160312.2227405-1-lars@metafoo.de Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/pmbus/ucd9000.c | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c index f8017993e2b4..9e26cc084a17 100644 --- a/drivers/hwmon/pmbus/ucd9000.c +++ b/drivers/hwmon/pmbus/ucd9000.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include "pmbus.h" enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090, @@ -65,6 +67,7 @@ struct ucd9000_data { struct gpio_chip gpio; #endif struct dentry *debugfs; + ktime_t write_time; }; #define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info) @@ -73,6 +76,73 @@ struct ucd9000_debugfs_entry { u8 index; }; +/* + * It has been observed that the UCD90320 randomly fails register access when + * doing another access right on the back of a register write. To mitigate this + * make sure that there is a minimum delay between a write access and the + * following access. The 250us is based on experimental data. At a delay of + * 200us the issue seems to go away. Add a bit of extra margin to allow for + * system to system differences. + */ +#define UCD90320_WAIT_DELAY_US 250 + +static inline void ucd90320_wait(const struct ucd9000_data *data) +{ + s64 delta = ktime_us_delta(ktime_get(), data->write_time); + + if (delta < UCD90320_WAIT_DELAY_US) + udelay(UCD90320_WAIT_DELAY_US - delta); +} + +static int ucd90320_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + struct ucd9000_data *data = to_ucd9000_data(info); + + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + + ucd90320_wait(data); + return pmbus_read_word_data(client, page, phase, reg); +} + +static int ucd90320_read_byte_data(struct i2c_client *client, int page, int reg) +{ + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + struct ucd9000_data *data = to_ucd9000_data(info); + + ucd90320_wait(data); + return pmbus_read_byte_data(client, page, reg); +} + +static int ucd90320_write_word_data(struct i2c_client *client, int page, + int reg, u16 word) +{ + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + struct ucd9000_data *data = to_ucd9000_data(info); + int ret; + + ucd90320_wait(data); + ret = pmbus_write_word_data(client, page, reg, word); + data->write_time = ktime_get(); + + return ret; +} + +static int ucd90320_write_byte(struct i2c_client *client, int page, u8 value) +{ + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); + struct ucd9000_data *data = to_ucd9000_data(info); + int ret; + + ucd90320_wait(data); + ret = pmbus_write_byte(client, page, value); + data->write_time = ktime_get(); + + return ret; +} + static int ucd9000_get_fan_config(struct i2c_client *client, int fan) { int fan_config = 0; @@ -598,6 +668,11 @@ static int ucd9000_probe(struct i2c_client *client) info->read_byte_data = ucd9000_read_byte_data; info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12 | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34; + } else if (mid->driver_data == ucd90320) { + info->read_byte_data = ucd90320_read_byte_data; + info->read_word_data = ucd90320_read_word_data; + info->write_byte = ucd90320_write_byte; + info->write_word_data = ucd90320_write_word_data; } ucd9000_probe_gpio(client, mid, data); From a4c3e1132422b8cdb515fbe64162419c3c761a9f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 12 Mar 2023 20:37:23 +0100 Subject: [PATCH 0783/1017] hwmon: tmp512: drop of_match_ptr for ID table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 00d85e81796b17a29a0e096c5a4735daa47adef8 ] The driver will match mostly by DT table (even thought there is regular ID table) so there is little benefit in of_match_ptr (this also allows ACPI matching via PRP0001, even though it might not be relevant here). This also fixes !CONFIG_OF error: drivers/hwmon/tmp513.c:610:34: error: ‘tmp51x_of_match’ defined but not used [-Werror=unused-const-variable=] Fixes: 59dfa75e5d82 ("hwmon: Add driver for Texas Instruments TMP512/513 sensor chips.") Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230312193723.478032-2-krzysztof.kozlowski@linaro.org Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/tmp513.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/tmp513.c b/drivers/hwmon/tmp513.c index 47bbe47e062f..7d5f7441aceb 100644 --- a/drivers/hwmon/tmp513.c +++ b/drivers/hwmon/tmp513.c @@ -758,7 +758,7 @@ static int tmp51x_probe(struct i2c_client *client) static struct i2c_driver tmp51x_driver = { .driver = { .name = "tmp51x", - .of_match_table = of_match_ptr(tmp51x_of_match), + .of_match_table = tmp51x_of_match, }, .probe_new = tmp51x_probe, .id_table = tmp51x_id, From a4c048d502eb24fd8040f88031a493b1f10cd4e9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 14 Mar 2023 02:31:45 -0700 Subject: [PATCH 0784/1017] hwmon: (adm1266) Set `can_sleep` flag for GPIO chip [ Upstream commit a5bb73b3f5db1a4e91402ad132b59b13d2651ed9 ] The adm1266 driver uses I2C bus access in its GPIO chip `set` and `get` implementation. This means these functions can sleep and the GPIO chip should set the `can_sleep` property to true. This will ensure that a warning is printed when trying to set or get the GPIO value from a context that potentially can't sleep. Fixes: d98dfad35c38 ("hwmon: (pmbus/adm1266) Add support for GPIOs") Signed-off-by: Lars-Peter Clausen Link: https://lore.kernel.org/r/20230314093146.2443845-1-lars@metafoo.de Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/pmbus/adm1266.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/pmbus/adm1266.c b/drivers/hwmon/pmbus/adm1266.c index c7b373ba92f2..d1b2e936546f 100644 --- a/drivers/hwmon/pmbus/adm1266.c +++ b/drivers/hwmon/pmbus/adm1266.c @@ -301,6 +301,7 @@ static int adm1266_config_gpio(struct adm1266_data *data) data->gc.label = name; data->gc.parent = &data->client->dev; data->gc.owner = THIS_MODULE; + data->gc.can_sleep = true; data->gc.base = -1; data->gc.names = data->gpio_names; data->gc.ngpio = ARRAY_SIZE(data->gpio_names); From 04eaeaa2f79fa5a4df421d24492e241ac5e0fb28 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 17 Mar 2023 13:51:17 -0700 Subject: [PATCH 0785/1017] media: m5mols: fix off-by-one loop termination error [ Upstream commit efbcbb12ee99f750c9f25c873b55ad774871de2a ] The __find_restype() function loops over the m5mols_default_ffmt[] array, and the termination condition ends up being wrong: instead of stopping when the iterator becomes the size of the array it traverses, it stops after it has already overshot the array. Now, in practice this doesn't likely matter, because the code will always find the entry it looks for, and will thus return early and never hit that last extra iteration. But it turns out that clang will unroll the loop fully, because it has only two iterations (well, three due to the off-by-one bug), and then clang will end up just giving up in the middle of the loop unrolling when it notices that the code walks past the end of the array. And that made 'objtool' very unhappy indeed, because the generated code just falls off the edge of the universe, and ends up falling through to the next function, causing this warning: drivers/media/i2c/m5mols/m5mols.o: warning: objtool: m5mols_set_fmt() falls through to next function m5mols_get_frame_desc() Fix the loop ending condition. Reported-by: Jens Axboe Analyzed-by: Miguel Ojeda Analyzed-by: Nick Desaulniers Link: https://lore.kernel.org/linux-block/CAHk-=wgTSdKYbmB1JYM5vmHMcD9J9UZr0mn7BOYM_LudrP+Xvw@mail.gmail.com/ Fixes: bc125106f8af ("[media] Add support for M-5MOLS 8 Mega Pixel camera ISP") Cc: HeungJun, Kim Cc: Sylwester Nawrocki Cc: Kyungmin Park Cc: Mauro Carvalho Chehab Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 21666d705e37..dcf9e4d4ee6b 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -488,7 +488,7 @@ static enum m5mols_restype __find_restype(u32 code) do { if (code == m5mols_default_ffmt[type].code) return type; - } while (type++ != SIZE_DEFAULT_FFMT); + } while (++type != SIZE_DEFAULT_FFMT); return 0; } From 980d4e70c7085351623ad6c5ff104ea0c5f0abc4 Mon Sep 17 00:00:00 2001 From: Tobias Schramm Date: Fri, 30 Dec 2022 20:43:15 +0100 Subject: [PATCH 0786/1017] mmc: atmel-mci: fix race between stop command and start of next command [ Upstream commit eca5bd666b0aa7dc0bca63292e4778968241134e ] This commit fixes a race between completion of stop command and start of a new command. Previously the command ready interrupt was enabled before stop command was written to the command register. This caused the command ready interrupt to fire immediately since the CMDRDY flag is asserted constantly while there is no command in progress. Consequently the command state machine will immediately advance to the next state when the tasklet function is executed again, no matter actual completion state of the stop command. Thus a new command can then be dispatched immediately, interrupting and corrupting the stop command on the CMD line. Fix that by dropping the command ready interrupt enable before calling atmci_send_stop_cmd. atmci_send_stop_cmd does already enable the command ready interrupt, no further writes to ATMCI_IER are necessary. Signed-off-by: Tobias Schramm Acked-by: Ludovic Desroches Link: https://lore.kernel.org/r/20221230194315.809903-2-t.schramm@manjaro.org Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/atmel-mci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index af85b32c6c1c..c468f9a02ef6 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -1818,7 +1818,6 @@ static void atmci_tasklet_func(unsigned long priv) atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); state = STATE_WAITING_NOTBUSY; } else if (host->mrq->stop) { - atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY); atmci_send_stop_cmd(host, data); state = STATE_SENDING_STOP; } else { @@ -1851,8 +1850,6 @@ static void atmci_tasklet_func(unsigned long priv) * command to send. */ if (host->mrq->stop) { - atmci_writel(host, ATMCI_IER, - ATMCI_CMDRDY); atmci_send_stop_cmd(host, data); state = STATE_SENDING_STOP; } else { From 8e7f26b9565a83e6116ce24512191e21f13c7a7f Mon Sep 17 00:00:00 2001 From: Yifei Liu Date: Wed, 3 Aug 2022 15:53:12 +0000 Subject: [PATCH 0787/1017] jffs2: correct logic when creating a hole in jffs2_write_begin [ Upstream commit 23892d383bee15b64f5463bd7195615734bb2415 ] Bug description and fix: 1. Write data to a file, say all 1s from offset 0 to 16. 2. Truncate the file to a smaller size, say 8 bytes. 3. Write new bytes (say 2s) from an offset past the original size of the file, say at offset 20, for 4 bytes. This is supposed to create a "hole" in the file, meaning that the bytes from offset 8 (where it was truncated above) up to the new write at offset 20, should all be 0s (zeros). 4. Flush all caches using "echo 3 > /proc/sys/vm/drop_caches" (or unmount and remount) the f/s. 5. Check the content of the file. It is wrong. The 1s that used to be between bytes 9 and 16, before the truncation, have REAPPEARED (they should be 0s). We wrote a script and helper C program to reproduce the bug (reproduce_jffs2_write_begin_issue.sh, write_file.c, and Makefile). We can make them available to anyone. The above example is shown when writing a small file within the same first page. But the bug happens for larger files, as long as steps 1, 2, and 3 above all happen within the same page. The problem was traced to the jffs2_write_begin code, where it goes into an 'if' statement intended to handle writes past the current EOF (i.e., writes that may create a hole). The code computes a 'pageofs' that is the floor of the write position (pos), aligned to the page size boundary. In other words, 'pageofs' will never be larger than 'pos'. The code then sets the internal jffs2_raw_inode->isize to the size of max(current inode size, pageofs) but that is wrong: the new file size should be the 'pos', which is larger than both the current inode size and pageofs. Similarly, the code incorrectly sets the internal jffs2_raw_inode->dsize to the difference between the pageofs minus current inode size; instead it should be the current pos minus the current inode size. Finally, inode->i_size was also set incorrectly. The patch below fixes this bug. The bug was discovered using a new tool for finding f/s bugs using model checking, called MCFS (Model Checking File Systems). Signed-off-by: Yifei Liu Signed-off-by: Erez Zadok Signed-off-by: Manish Adkar Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- fs/jffs2/file.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index bd7d58d27bfc..97a3c09fd96b 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -138,19 +138,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); pgoff_t index = pos >> PAGE_SHIFT; - uint32_t pageofs = index << PAGE_SHIFT; int ret = 0; jffs2_dbg(1, "%s()\n", __func__); - if (pageofs > inode->i_size) { - /* Make new hole frag from old EOF to new page */ + if (pos > inode->i_size) { + /* Make new hole frag from old EOF to new position */ struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; uint32_t alloc_len; - jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", - (unsigned int)inode->i_size, pageofs); + jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new position\n", + (unsigned int)inode->i_size, (uint32_t)pos); ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); @@ -170,10 +169,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, ri.mode = cpu_to_jemode(inode->i_mode); ri.uid = cpu_to_je16(i_uid_read(inode)); ri.gid = cpu_to_je16(i_gid_read(inode)); - ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs)); + ri.isize = cpu_to_je32((uint32_t)pos); ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW()); ri.offset = cpu_to_je32(inode->i_size); - ri.dsize = cpu_to_je32(pageofs - inode->i_size); + ri.dsize = cpu_to_je32((uint32_t)pos - inode->i_size); ri.csize = cpu_to_je32(0); ri.compr = JFFS2_COMPR_ZERO; ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); @@ -203,7 +202,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, goto out_err; } jffs2_complete_reservation(c); - inode->i_size = pageofs; + inode->i_size = pos; mutex_unlock(&f->sem); } From 0bf15bc393a15dbb723c28d571326e727c60f298 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Sat, 7 Jan 2023 11:21:25 +0800 Subject: [PATCH 0788/1017] ext4: fail ext4_iget if special inode unallocated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5cd740287ae5e3f9d1c46f5bfe8778972fd6d3fe ] In ext4_fill_super(), EXT4_ORPHAN_FS flag is cleared after ext4_orphan_cleanup() is executed. Therefore, when __ext4_iget() is called to get an inode whose i_nlink is 0 when the flag exists, no error is returned. If the inode is a special inode, a null pointer dereference may occur. If the value of i_nlink is 0 for any inodes (except boot loader inodes) got by using the EXT4_IGET_SPECIAL flag, the current file system is corrupted. Therefore, make the ext4_iget() function return an error if it gets such an abnormal special inode. Link: https://bugzilla.kernel.org/show_bug.cgi?id=199179 Link: https://bugzilla.kernel.org/show_bug.cgi?id=216541 Link: https://bugzilla.kernel.org/show_bug.cgi?id=216539 Reported-by: Luís Henriques Suggested-by: Theodore Ts'o Signed-off-by: Baokun Li Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230107032126.4165860-2-libaokun1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/inode.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 1a654a1f3f46..6ba185b46ba3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4721,13 +4721,6 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, goto bad_inode; raw_inode = ext4_raw_inode(&iloc); - if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { - ext4_error_inode(inode, function, line, 0, - "iget: root inode unallocated"); - ret = -EFSCORRUPTED; - goto bad_inode; - } - if ((flags & EXT4_IGET_HANDLE) && (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) { ret = -ESTALE; @@ -4800,11 +4793,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, * NeilBrown 1999oct15 */ if (inode->i_nlink == 0) { - if ((inode->i_mode == 0 || + if ((inode->i_mode == 0 || flags & EXT4_IGET_SPECIAL || !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) && ino != EXT4_BOOT_LOADER_INO) { - /* this inode is deleted */ - ret = -ESTALE; + /* this inode is deleted or unallocated */ + if (flags & EXT4_IGET_SPECIAL) { + ext4_error_inode(inode, function, line, 0, + "iget: special inode unallocated"); + ret = -EFSCORRUPTED; + } else + ret = -ESTALE; goto bad_inode; } /* The only unlinked inodes we let through here have From a98160d8f3e6242ca9b7f443f26e7ef3a61ba684 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Tue, 10 Jan 2023 21:34:36 +0800 Subject: [PATCH 0789/1017] ext4: fix task hung in ext4_xattr_delete_inode [ Upstream commit 0f7bfd6f8164be32dbbdf36aa1e5d00485c53cd7 ] Syzbot reported a hung task problem: ================================================================== INFO: task syz-executor232:5073 blocked for more than 143 seconds. Not tainted 6.2.0-rc2-syzkaller-00024-g512dee0c00ad #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz-exec232 state:D stack:21024 pid:5073 ppid:5072 flags:0x00004004 Call Trace: context_switch kernel/sched/core.c:5244 [inline] __schedule+0x995/0xe20 kernel/sched/core.c:6555 schedule+0xcb/0x190 kernel/sched/core.c:6631 __wait_on_freeing_inode fs/inode.c:2196 [inline] find_inode_fast+0x35a/0x4c0 fs/inode.c:950 iget_locked+0xb1/0x830 fs/inode.c:1273 __ext4_iget+0x22e/0x3ed0 fs/ext4/inode.c:4861 ext4_xattr_inode_iget+0x68/0x4e0 fs/ext4/xattr.c:389 ext4_xattr_inode_dec_ref_all+0x1a7/0xe50 fs/ext4/xattr.c:1148 ext4_xattr_delete_inode+0xb04/0xcd0 fs/ext4/xattr.c:2880 ext4_evict_inode+0xd7c/0x10b0 fs/ext4/inode.c:296 evict+0x2a4/0x620 fs/inode.c:664 ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 __ext4_fill_super fs/ext4/super.c:5516 [inline] ext4_fill_super+0x81cd/0x8700 fs/ext4/super.c:5644 get_tree_bdev+0x400/0x620 fs/super.c:1282 vfs_get_tree+0x88/0x270 fs/super.c:1489 do_new_mount+0x289/0xad0 fs/namespace.c:3145 do_mount fs/namespace.c:3488 [inline] __do_sys_mount fs/namespace.c:3697 [inline] __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3674 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fa5406fd5ea RSP: 002b:00007ffc7232f968 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fa5406fd5ea RDX: 0000000020000440 RSI: 0000000020000000 RDI: 00007ffc7232f970 RBP: 00007ffc7232f970 R08: 00007ffc7232f9b0 R09: 0000000000000432 R10: 0000000000804a03 R11: 0000000000000202 R12: 0000000000000004 R13: 0000555556a7a2c0 R14: 00007ffc7232f9b0 R15: 0000000000000000 ================================================================== The problem is that the inode contains an xattr entry with ea_inum of 15 when cleaning up an orphan inode <15>. When evict inode <15>, the reference counting of the corresponding EA inode is decreased. When EA inode <15> is found by find_inode_fast() in __ext4_iget(), it is found that the EA inode holds the I_FREEING flag and waits for the EA inode to complete deletion. As a result, when inode <15> is being deleted, we wait for inode <15> to complete the deletion, resulting in an infinite loop and triggering Hung Task. To solve this problem, we only need to check whether the ino of EA inode and parent is the same before getting EA inode. Link: https://syzkaller.appspot.com/bug?extid=77d6fcc37bbb92f26048 Reported-by: syzbot+77d6fcc37bbb92f26048@syzkaller.appspotmail.com Signed-off-by: Baokun Li Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230110133436.996350-1-libaokun1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/xattr.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 60e122761352..f3da1f2d4cb9 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -386,6 +386,17 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, struct inode *inode; int err; + /* + * We have to check for this corruption early as otherwise + * iget_locked() could wait indefinitely for the state of our + * parent inode. + */ + if (parent->i_ino == ea_ino) { + ext4_error(parent->i_sb, + "Parent and EA inode have the same ino %lu", ea_ino); + return -EFSCORRUPTED; + } + inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL); if (IS_ERR(inode)) { err = PTR_ERR(inode); From 6936525142a015e854d0a23e9ad9ea0a28b3843d Mon Sep 17 00:00:00 2001 From: Qu Huang Date: Tue, 21 Feb 2023 11:35:16 +0000 Subject: [PATCH 0790/1017] drm/amdkfd: Fix an illegal memory access [ Upstream commit 4fc8fff378b2f2039f2a666d9f8c570f4e58352c ] In the kfd_wait_on_events() function, the kfd_event_waiter structure is allocated by alloc_event_waiters(), but the event field of the waiter structure is not initialized; When copy_from_user() fails in the kfd_wait_on_events() function, it will enter exception handling to release the previously allocated memory of the waiter structure; Due to the event field of the waiters structure being accessed in the free_waiters() function, this results in illegal memory access and system crash, here is the crash log: localhost kernel: RIP: 0010:native_queued_spin_lock_slowpath+0x185/0x1e0 localhost kernel: RSP: 0018:ffffaa53c362bd60 EFLAGS: 00010082 localhost kernel: RAX: ff3d3d6bff4007cb RBX: 0000000000000282 RCX: 00000000002c0000 localhost kernel: RDX: ffff9e855eeacb80 RSI: 000000000000279c RDI: ffffe7088f6a21d0 localhost kernel: RBP: ffffe7088f6a21d0 R08: 00000000002c0000 R09: ffffaa53c362be64 localhost kernel: R10: ffffaa53c362bbd8 R11: 0000000000000001 R12: 0000000000000002 localhost kernel: R13: ffff9e7ead15d600 R14: 0000000000000000 R15: ffff9e7ead15d698 localhost kernel: FS: 0000152a3d111700(0000) GS:ffff9e855ee80000(0000) knlGS:0000000000000000 localhost kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 localhost kernel: CR2: 0000152938000010 CR3: 000000044d7a4000 CR4: 00000000003506e0 localhost kernel: Call Trace: localhost kernel: _raw_spin_lock_irqsave+0x30/0x40 localhost kernel: remove_wait_queue+0x12/0x50 localhost kernel: kfd_wait_on_events+0x1b6/0x490 [hydcu] localhost kernel: ? ftrace_graph_caller+0xa0/0xa0 localhost kernel: kfd_ioctl+0x38c/0x4a0 [hydcu] localhost kernel: ? kfd_ioctl_set_trap_handler+0x70/0x70 [hydcu] localhost kernel: ? kfd_ioctl_create_queue+0x5a0/0x5a0 [hydcu] localhost kernel: ? ftrace_graph_caller+0xa0/0xa0 localhost kernel: __x64_sys_ioctl+0x8e/0xd0 localhost kernel: ? syscall_trace_enter.isra.18+0x143/0x1b0 localhost kernel: do_syscall_64+0x33/0x80 localhost kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9 localhost kernel: RIP: 0033:0x152a4dff68d7 Allocate the structure with kcalloc, and remove redundant 0-initialization and a redundant loop condition check. Signed-off-by: Qu Huang Signed-off-by: Felix Kuehling Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 159be13ef20b..2c19b3775179 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -528,16 +528,13 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events) struct kfd_event_waiter *event_waiters; uint32_t i; - event_waiters = kmalloc_array(num_events, - sizeof(struct kfd_event_waiter), - GFP_KERNEL); + event_waiters = kcalloc(num_events, sizeof(struct kfd_event_waiter), + GFP_KERNEL); if (!event_waiters) return NULL; - for (i = 0; (event_waiters) && (i < num_events) ; i++) { + for (i = 0; i < num_events; i++) init_wait(&event_waiters[i].wait); - event_waiters[i].activated = false; - } return event_waiters; } From ab7da8d93a6ff68a921b6dffbfb8c463e606517c Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Tue, 24 Jan 2023 22:48:16 +0100 Subject: [PATCH 0791/1017] sh: intc: Avoid spurious sizeof-pointer-div warning [ Upstream commit 250870824c1cf199b032b1ef889c8e8d69d9123a ] GCC warns about the pattern sizeof(void*)/sizeof(void), as it looks like the abuse of a pattern to calculate the array size. This pattern appears in the unevaluated part of the ternary operator in _INTC_ARRAY if the parameter is NULL. The replacement uses an alternate approach to return 0 in case of NULL which does not generate the pattern sizeof(void*)/sizeof(void), but still emits the warning if _INTC_ARRAY is called with a nonarray parameter. This patch is required for successful compilation with -Werror enabled. The idea to use _Generic for type distinction is taken from Comment #7 in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108483 by Jakub Jelinek Signed-off-by: Michael Karcher Acked-by: Randy Dunlap # build-tested Link: https://lore.kernel.org/r/619fa552-c988-35e5-b1d7-fe256c46a272@mkarcher.dialup.fu-berlin.de Signed-off-by: John Paul Adrian Glaubitz Signed-off-by: Sasha Levin --- include/linux/sh_intc.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index c255273b0281..37ad81058d6a 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -97,7 +97,10 @@ struct intc_hw_desc { unsigned int nr_subgroups; }; -#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a) +#define _INTC_SIZEOF_OR_ZERO(a) (_Generic(a, \ + typeof(NULL): 0, \ + default: sizeof(a))) +#define _INTC_ARRAY(a) a, _INTC_SIZEOF_OR_ZERO(a)/sizeof(*a) #define INTC_HW_DESC(vectors, groups, mask_regs, \ prio_regs, sense_regs, ack_regs) \ From 7257070be70e19a9138f39009c1a26c83a8a7cfa Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 11 Jan 2023 09:54:11 -0700 Subject: [PATCH 0792/1017] drm/amd/display: fix shift-out-of-bounds in CalculateVMAndRowBytes [ Upstream commit 031f196d1b1b6d5dfcb0533b431e3ab1750e6189 ] [WHY] When PTEBufferSizeInRequests is zero, UBSAN reports the following warning because dml_log2 returns an unexpected negative value: shift exponent 4294966273 is too large for 32-bit type 'int' [HOW] In the case PTEBufferSizeInRequests is zero, skip the dml_log2() and assign the result directly. Reviewed-by: Jun Lei Acked-by: Qingqing Zhuo Signed-off-by: Alex Hung Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- .../gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index e427f4ffa080..e5b1002d7f3f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -1868,7 +1868,10 @@ static unsigned int CalculateVMAndRowBytes( } if (SurfaceTiling == dm_sw_linear) { - *dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1)); + if (PTEBufferSizeInRequests == 0) + *dpte_row_height = 1; + else + *dpte_row_height = dml_min(128, 1 << (unsigned int) dml_floor(dml_log2(PTEBufferSizeInRequests * *PixelPTEReqWidth / Pitch), 1)); *dpte_row_width_ub = (dml_ceil(((double) SwathWidth - 1) / *PixelPTEReqWidth, 1) + 1) * *PixelPTEReqWidth; *PixelPTEBytesPerRow = *dpte_row_width_ub / *PixelPTEReqWidth * *PTERequestSize; } else if (ScanDirection != dm_vert) { From 020166bc6669ca9fb267ebd96bd88c4fb64a5d46 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 17 Mar 2023 21:53:52 -0400 Subject: [PATCH 0793/1017] ext4: fix possible double unlock when moving a directory commit 70e42feab2e20618ddd0cbfc4ab4b08628236ecd upstream. Fixes: 0813299c586b ("ext4: Fix possible corruption when moving a directory") Link: https://lore.kernel.org/r/5efbe1b9-ad8b-4a4f-b422-24824d2b775c@kili.mountain Reported-by: Dan Carpenter Reported-by: syzbot+0c73d1d8b952c5f3d714@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/namei.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 1f47aeca7142..45f719c1e002 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3934,10 +3934,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, goto end_rename; } retval = ext4_rename_dir_prepare(handle, &old); - if (retval) { - inode_unlock(old.inode); + if (retval) goto end_rename; - } } /* * If we're renaming a file within an inline_data dir and adding or From f5a5150c7066c6fc5d617e277cd432ebbb8f97b4 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Thu, 23 Feb 2023 17:39:41 +0800 Subject: [PATCH 0794/1017] tty: serial: fsl_lpuart: skip waiting for transmission complete when UARTCTRL_SBK is asserted commit 2411fd94ceaa6e11326e95d6ebf876cbfed28d23 upstream. According to LPUART RM, Transmission Complete Flag becomes 0 if queuing a break character by writing 1 to CTRL[SBK], so here need to skip waiting for transmission complete when UARTCTRL_SBK is asserted, otherwise the kernel may stuck here. And actually set_termios() adds transmission completion waiting to avoid data loss or data breakage when changing the baud rate, but we don't need to worry about this when queuing break characters. Signed-off-by: Sherry Sun Cc: stable Link: https://lore.kernel.org/r/20230223093941.31790-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 9cb0e8673f82..32cce52800a7 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2159,9 +2159,15 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); - /* wait transmit engin complete */ - lpuart32_write(&sport->port, 0, UARTMODIR); - lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC); + /* + * LPUART Transmission Complete Flag may never be set while queuing a break + * character, so skip waiting for transmission complete when UARTCTRL_SBK is + * asserted. + */ + if (!(old_ctrl & UARTCTRL_SBK)) { + lpuart32_write(&sport->port, 0, UARTMODIR); + lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC); + } /* disable transmit and receive */ lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE), From 0c16c20b87873801d6eaa79e5a150eadab9145b3 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 27 Feb 2023 11:41:46 +0000 Subject: [PATCH 0795/1017] serial: 8250_em: Fix UART port type commit 32e293be736b853f168cd065d9cbc1b0c69f545d upstream. As per HW manual for EMEV2 "R19UH0040EJ0400 Rev.4.00", the UART IP found on EMMA mobile SoC is Register-compatible with the general-purpose 16750 UART chip. Fix UART port type as 16750 and enable 64-bytes fifo support. Fixes: 22886ee96895 ("serial8250-em: Emma Mobile UART driver V2") Cc: stable@vger.kernel.org Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20230227114152.22265-2-biju.das.jz@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_em.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c index f8e99995eee9..d94c3811a8f7 100644 --- a/drivers/tty/serial/8250/8250_em.c +++ b/drivers/tty/serial/8250/8250_em.c @@ -106,8 +106,8 @@ static int serial8250_em_probe(struct platform_device *pdev) memset(&up, 0, sizeof(up)); up.port.mapbase = regs->start; up.port.irq = irq; - up.port.type = PORT_UNKNOWN; - up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP; + up.port.type = PORT_16750; + up.port.flags = UPF_FIXED_PORT | UPF_IOREMAP | UPF_FIXED_TYPE; up.port.dev = &pdev->dev; up.port.private_data = priv; From b37d3ccbd549494890672136a0e623eb010d46a7 Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Wed, 8 Mar 2023 14:26:02 -0800 Subject: [PATCH 0796/1017] firmware: xilinx: don't make a sleepable memory allocation from an atomic context commit 38ed310c22e7a0fc978b1f8292136a4a4a8b3051 upstream. The following issue was discovered using lockdep: [ 6.691371] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:209 [ 6.694602] in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 1, name: swapper/0 [ 6.702431] 2 locks held by swapper/0/1: [ 6.706300] #0: ffffff8800f6f188 (&dev->mutex){....}-{3:3}, at: __device_driver_lock+0x4c/0x90 [ 6.714900] #1: ffffffc009a2abb8 (enable_lock){....}-{2:2}, at: clk_enable_lock+0x4c/0x140 [ 6.723156] irq event stamp: 304030 [ 6.726596] hardirqs last enabled at (304029): [] _raw_spin_unlock_irqrestore+0xc0/0xd0 [ 6.736142] hardirqs last disabled at (304030): [] clk_enable_lock+0xfc/0x140 [ 6.744742] softirqs last enabled at (303958): [] _stext+0x4f0/0x894 [ 6.752655] softirqs last disabled at (303951): [] irq_exit+0x238/0x280 [ 6.760744] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G U 5.15.36 #2 [ 6.768048] Hardware name: xlnx,zynqmp (DT) [ 6.772179] Call trace: [ 6.774584] dump_backtrace+0x0/0x300 [ 6.778197] show_stack+0x18/0x30 [ 6.781465] dump_stack_lvl+0xb8/0xec [ 6.785077] dump_stack+0x1c/0x38 [ 6.788345] ___might_sleep+0x1a8/0x2a0 [ 6.792129] __might_sleep+0x6c/0xd0 [ 6.795655] kmem_cache_alloc_trace+0x270/0x3d0 [ 6.800127] do_feature_check_call+0x100/0x220 [ 6.804513] zynqmp_pm_invoke_fn+0x8c/0xb0 [ 6.808555] zynqmp_pm_clock_getstate+0x90/0xe0 [ 6.813027] zynqmp_pll_is_enabled+0x8c/0x120 [ 6.817327] zynqmp_pll_enable+0x38/0xc0 [ 6.821197] clk_core_enable+0x144/0x400 [ 6.825067] clk_core_enable+0xd4/0x400 [ 6.828851] clk_core_enable+0xd4/0x400 [ 6.832635] clk_core_enable+0xd4/0x400 [ 6.836419] clk_core_enable+0xd4/0x400 [ 6.840203] clk_core_enable+0xd4/0x400 [ 6.843987] clk_core_enable+0xd4/0x400 [ 6.847771] clk_core_enable+0xd4/0x400 [ 6.851555] clk_core_enable_lock+0x24/0x50 [ 6.855683] clk_enable+0x24/0x40 [ 6.858952] fclk_probe+0x84/0xf0 [ 6.862220] platform_probe+0x8c/0x110 [ 6.865918] really_probe+0x110/0x5f0 [ 6.869530] __driver_probe_device+0xcc/0x210 [ 6.873830] driver_probe_device+0x64/0x140 [ 6.877958] __driver_attach+0x114/0x1f0 [ 6.881828] bus_for_each_dev+0xe8/0x160 [ 6.885698] driver_attach+0x34/0x50 [ 6.889224] bus_add_driver+0x228/0x300 [ 6.893008] driver_register+0xc0/0x1e0 [ 6.896792] __platform_driver_register+0x44/0x60 [ 6.901436] fclk_driver_init+0x1c/0x28 [ 6.905220] do_one_initcall+0x104/0x590 [ 6.909091] kernel_init_freeable+0x254/0x2bc [ 6.913390] kernel_init+0x24/0x130 [ 6.916831] ret_from_fork+0x10/0x20 Fix it by passing the GFP_ATOMIC gfp flag for the corresponding memory allocation. Fixes: acfdd18591ea ("firmware: xilinx: Use hash-table for api feature check") Cc: stable Signed-off-by: Roman Gushchin Cc: Amit Sunil Dhamne Cc: Michal Simek Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20230308222602.123866-1-roman.gushchin@linux.dev Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/xilinx/zynqmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 9e6504592646..300ba2991936 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -171,7 +171,7 @@ static int zynqmp_pm_feature(u32 api_id) } /* Add new entry if not present */ - feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL); + feature_data = kmalloc(sizeof(*feature_data), GFP_ATOMIC); if (!feature_data) return -ENOMEM; From efae80ca13faa94457208852825731da44a788ad Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 6 Mar 2023 08:56:29 +0100 Subject: [PATCH 0797/1017] interconnect: fix mem leak when freeing nodes commit a5904f415e1af72fa8fe6665aa4f554dc2099a95 upstream. The node link array is allocated when adding links to a node but is not deallocated when nodes are destroyed. Fixes: 11f1ceca7031 ("interconnect: Add generic on-chip interconnect API") Cc: stable@vger.kernel.org # 5.1 Reviewed-by: Konrad Dybcio Signed-off-by: Johan Hovold Tested-by: Luca Ceresoli # i.MX8MP MSC SM2-MB-EP1 Board Link: https://lore.kernel.org/r/20230306075651.2449-2-johan+linaro@kernel.org Signed-off-by: Georgi Djakov Signed-off-by: Greg Kroah-Hartman --- drivers/interconnect/core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index ceb6cdc20484..7db6d0fc6ec2 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -850,6 +850,10 @@ void icc_node_destroy(int id) mutex_unlock(&icc_lock); + if (!node) + return; + + kfree(node->links); kfree(node); } EXPORT_SYMBOL_GPL(icc_node_destroy); From de3170bd41dee29039e8a87efa960759ad256a5a Mon Sep 17 00:00:00 2001 From: Sung-hun Kim Date: Tue, 14 Mar 2023 10:37:07 +0900 Subject: [PATCH 0798/1017] tracing: Make splice_read available again commit e400be674a1a40e9dcb2e95f84d6c1fd2d88f31d upstream. Since the commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") is applied to the kernel, splice() and sendfile() calls on the trace file (/sys/kernel/debug/tracing /trace) return EINVAL. This patch restores these system calls by initializing splice_read in file_operations of the trace file. This patch only enables such functionalities for the read case. Link: https://lore.kernel.org/linux-trace-kernel/20230314013707.28814-1-sfoon.kim@samsung.com Cc: stable@vger.kernel.org Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") Signed-off-by: Sung-hun Kim Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8637eab2986e..ce45bdd9077d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4705,6 +4705,8 @@ loff_t tracing_lseek(struct file *file, loff_t offset, int whence) static const struct file_operations tracing_fops = { .open = tracing_open, .read = seq_read, + .read_iter = seq_read_iter, + .splice_read = generic_file_splice_read, .write = tracing_write_stub, .llseek = tracing_lseek, .release = tracing_release, From 8ae86ef7a0580135ac6d0afce3e16e2c9e4b8e96 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 1 Mar 2023 20:00:53 -0500 Subject: [PATCH 0799/1017] tracing: Check field value in hist_field_name() commit 9f116f76fa8c04c81aef33ad870dbf9a158e5b70 upstream. The function hist_field_name() cannot handle being passed a NULL field parameter. It should never be NULL, but due to a previous bug, NULL was passed to the function and the kernel crashed due to a NULL dereference. Mark Rutland reported this to me on IRC. The bug was fixed, but to prevent future bugs from crashing the kernel, check the field and add a WARN_ON() if it is NULL. Link: https://lkml.kernel.org/r/20230302020810.762384440@goodmis.org Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Andrew Morton Reported-by: Mark Rutland Fixes: c6afad49d127f ("tracing: Add hist trigger 'sym' and 'sym-offset' modifiers") Tested-by: Mark Rutland Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events_hist.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index ccc99cd23f3c..9ed65191888e 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -1087,6 +1087,9 @@ static const char *hist_field_name(struct hist_field *field, { const char *field_name = ""; + if (WARN_ON_ONCE(!field)) + return field_name; + if (level > 1) return field_name; From ec663c410ce0023e13f56a95e096be9cd6d471c2 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Fri, 10 Mar 2023 17:28:56 -0500 Subject: [PATCH 0800/1017] tracing: Make tracepoint lockdep check actually test something commit c2679254b9c9980d9045f0f722cf093a2b1f7590 upstream. A while ago where the trace events had the following: rcu_read_lock_sched_notrace(); rcu_dereference_sched(...); rcu_read_unlock_sched_notrace(); If the tracepoint is enabled, it could trigger RCU issues if called in the wrong place. And this warning was only triggered if lockdep was enabled. If the tracepoint was never enabled with lockdep, the bug would not be caught. To handle this, the above sequence was done when lockdep was enabled regardless if the tracepoint was enabled or not (although the always enabled code really didn't do anything, it would still trigger a warning). But a lot has changed since that lockdep code was added. One is, that sequence no longer triggers any warning. Another is, the tracepoint when enabled doesn't even do that sequence anymore. The main check we care about today is whether RCU is "watching" or not. So if lockdep is enabled, always check if rcu_is_watching() which will trigger a warning if it is not (tracepoints require RCU to be watching). Note, that old sequence did add a bit of overhead when lockdep was enabled, and with the latest kernel updates, would cause the system to slow down enough to trigger kernel "stalled" warnings. Link: http://lore.kernel.org/lkml/20140806181801.GA4605@redhat.com Link: http://lore.kernel.org/lkml/20140807175204.C257CAC5@viggo.jf.intel.com Link: https://lore.kernel.org/lkml/20230307184645.521db5c9@gandalf.local.home/ Link: https://lore.kernel.org/linux-trace-kernel/20230310172856.77406446@gandalf.local.home Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Dave Hansen Cc: "Paul E. McKenney" Cc: Mathieu Desnoyers Cc: Joel Fernandes Acked-by: Peter Zijlstra (Intel) Acked-by: Paul E. McKenney Fixes: e6753f23d961 ("tracepoint: Make rcuidle tracepoint callers use SRCU") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- include/linux/tracepoint.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index e4c5df71f0e7..4e1356c35fe6 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -234,12 +234,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) * not add unwanted padding between the beginning of the section and the * structure. Force alignment to the same alignment as the section start. * - * When lockdep is enabled, we make sure to always do the RCU portions of - * the tracepoint code, regardless of whether tracing is on. However, - * don't check if the condition is false, due to interaction with idle - * instrumentation. This lets us find RCU issues triggered with tracepoints - * even when this tracepoint is off. This code has no purpose other than - * poking RCU a bit. + * When lockdep is enabled, we make sure to always test if RCU is + * "watching" regardless if the tracepoint is enabled or not. Tracepoints + * require RCU to be active, and it should always warn at the tracepoint + * site if it is not watching, as it will need to be active when the + * tracepoint is enabled. */ #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ extern int __traceiter_##name(data_proto); \ @@ -253,9 +252,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) TP_ARGS(data_args), \ TP_CONDITION(cond), 0); \ if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ - rcu_read_lock_sched_notrace(); \ - rcu_dereference_sched(__tracepoint_##name.funcs);\ - rcu_read_unlock_sched_notrace(); \ + WARN_ON_ONCE(!rcu_is_watching()); \ } \ } \ __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \ From 7b18dea697e400dd91c2a0447cebf1f5fe9f5d1c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Mar 2023 16:09:54 +0100 Subject: [PATCH 0801/1017] cifs: Fix smb2_set_path_size() commit 211baef0eabf4169ce4f73ebd917749d1a7edd74 upstream. If cifs_get_writable_path() finds a writable file, smb2_compound_op() must use that file's FID and not the COMPOUND_FID. Cc: stable@vger.kernel.org Signed-off-by: Volker Lendecke Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2inode.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 97cd4df04060..e11818801148 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -236,15 +236,32 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, size[0] = 8; /* sizeof __le64 */ data[0] = ptr; - rc = SMB2_set_info_init(tcon, server, - &rqst[num_rqst], COMPOUND_FID, - COMPOUND_FID, current->tgid, - FILE_END_OF_FILE_INFORMATION, - SMB2_O_INFO_FILE, 0, data, size); + if (cfile) { + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], + cfile->fid.persistent_fid, + cfile->fid.volatile_fid, + current->tgid, + FILE_END_OF_FILE_INFORMATION, + SMB2_O_INFO_FILE, 0, + data, size); + } else { + rc = SMB2_set_info_init(tcon, server, + &rqst[num_rqst], + COMPOUND_FID, + COMPOUND_FID, + current->tgid, + FILE_END_OF_FILE_INFORMATION, + SMB2_O_INFO_FILE, 0, + data, size); + if (!rc) { + smb2_set_next_command(tcon, &rqst[num_rqst]); + smb2_set_related(&rqst[num_rqst]); + } + } if (rc) goto finished; - smb2_set_next_command(tcon, &rqst[num_rqst]); - smb2_set_related(&rqst[num_rqst++]); + num_rqst++; trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); break; case SMB2_OP_SET_INFO: From c54974ccaff73525462e278602dfe4069877cfaa Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 10 Mar 2023 11:10:56 -0500 Subject: [PATCH 0802/1017] KVM: nVMX: add missing consistency checks for CR0 and CR4 commit 112e66017bff7f2837030f34c2bc19501e9212d5 upstream. The effective values of the guest CR0 and CR4 registers may differ from those included in the VMCS12. In particular, disabling EPT forces CR4.PAE=1 and disabling unrestricted guest mode forces CR0.PG=CR0.PE=1. Therefore, checks on these bits cannot be delegated to the processor and must be performed by KVM. Reported-by: Reima ISHII Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/nested.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 91371b01eae0..c165ddbb672f 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2998,7 +2998,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, enum vm_entry_failure_code *entry_failure_code) { - bool ia32e; + bool ia32e = !!(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE); *entry_failure_code = ENTRY_FAIL_DEFAULT; @@ -3024,6 +3024,13 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, vmcs12->guest_ia32_perf_global_ctrl))) return -EINVAL; + if (CC((vmcs12->guest_cr0 & (X86_CR0_PG | X86_CR0_PE)) == X86_CR0_PG)) + return -EINVAL; + + if (CC(ia32e && !(vmcs12->guest_cr4 & X86_CR4_PAE)) || + CC(ia32e && !(vmcs12->guest_cr0 & X86_CR0_PG))) + return -EINVAL; + /* * If the load IA32_EFER VM-entry control is 1, the following checks * are performed on the field for the IA32_EFER MSR: @@ -3035,7 +3042,6 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, */ if (to_vmx(vcpu)->nested.nested_run_pending && (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)) { - ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0; if (CC(!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer)) || CC(ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA)) || CC(((vmcs12->guest_cr0 & X86_CR0_PG) && From 9addf5e1050abb5c63cd7d9d40f6b004f2b45cfc Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 6 Mar 2023 15:41:01 +0800 Subject: [PATCH 0803/1017] ALSA: hda: intel-dsp-config: add MTL PCI id commit bbdf904b13a62bb8b1272d92a7dde082dff86fbb upstream. Use SOF as default audio driver. Signed-off-by: Bard Liao Reviewed-by: Gongjun Song Reviewed-by: Kai Vehmanen Cc: Link: https://lore.kernel.org/r/20230306074101.3906707-1-yung-chuan.liao@linux.intel.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/hda/intel-dsp-config.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index 2a5ba9dca6b0..f96e70c85f84 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -359,6 +359,15 @@ static const struct config_entry config_table[] = { }, #endif +/* Meteor Lake */ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_METEORLAKE) + /* Meteorlake-P */ + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = 0x7e28, + }, +#endif + }; static const struct config_entry *snd_intel_dsp_find_config From fbc5ffcce72be7805a1c0da19e86d8e3fddc7399 Mon Sep 17 00:00:00 2001 From: "Hamidreza H. Fard" Date: Tue, 7 Mar 2023 16:37:41 +0000 Subject: [PATCH 0804/1017] ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book2 Pro commit a86e79e3015f5dd8e1b01ccfa49bd5c6e41047a1 upstream. Samsung Galaxy Book2 Pro (13" 2022 NP930XED-KA1DE) with codec SSID 144d:c868 requires the same workaround for enabling the speaker amp like other Samsung models with ALC298 code. Signed-off-by: Hamidreza H. Fard Cc: Link: https://lore.kernel.org/r/20230307163741.3878-1-nitocris@posteo.net Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f2ef75c8de42..2cf6600c9ca8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9091,6 +9091,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP), + SND_PCI_QUIRK(0x144d, 0xc868, "Samsung Galaxy Book2 Pro (NP930XED)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), From 684c7372bbd6447c2e86a2a84e97a1478604d21f Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 9 Jan 2023 00:13:11 +0300 Subject: [PATCH 0805/1017] drm/shmem-helper: Remove another errant put in error path commit ee9adb7a45516cfa536ca92253d7ae59d56db9e4 upstream. drm_gem_shmem_mmap() doesn't own reference in error code path, resulting in the dma-buf shmem GEM object getting prematurely freed leading to a later use-after-free. Fixes: f49a51bfdc8e ("drm/shme-helpers: Fix dma_buf_mmap forwarding bug") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Osipenko Reviewed-by: Rob Clark Link: https://patchwork.freedesktop.org/patch/msgid/20230108211311.3950107-1-dmitry.osipenko@collabora.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_gem_shmem_helper.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index c56656a95cf9..b7bb5610dfe2 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -614,11 +614,14 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) int ret; if (obj->import_attach) { - /* Drop the reference drm_gem_mmap_obj() acquired.*/ - drm_gem_object_put(obj); vma->vm_private_data = NULL; + ret = dma_buf_mmap(obj->dma_buf, vma, 0); - return dma_buf_mmap(obj->dma_buf, vma, 0); + /* Drop the reference drm_gem_mmap_obj() acquired.*/ + if (!ret) + drm_gem_object_put(obj); + + return ret; } shmem = to_drm_gem_shmem_obj(obj); From f9a98b8dde09330c238cbb556a9f75bd965b91aa Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Thu, 9 Mar 2023 15:50:03 +0100 Subject: [PATCH 0806/1017] mptcp: avoid setting TCP_CLOSE state twice commit 3ba14528684f528566fb7d956bfbfb958b591d86 upstream. tcp_set_state() is called from tcp_done() already. There is then no need to first set the state to TCP_CLOSE, then call tcp_done(). Fixes: d582484726c4 ("mptcp: fix fallback for MP_JOIN subflows") Cc: stable@vger.kernel.org Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/362 Acked-by: Paolo Abeni Signed-off-by: Matthieu Baerts Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/mptcp/subflow.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 3b154ad4945c..607519246bf2 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -275,7 +275,6 @@ void mptcp_subflow_reset(struct sock *ssk) struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); struct sock *sk = subflow->conn; - tcp_set_state(ssk, TCP_CLOSE); tcp_send_active_reset(ssk, GFP_ATOMIC); tcp_done(ssk); if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags) && From 83c3b2f4e7c61367c7b24551f4c6eb94bbdda283 Mon Sep 17 00:00:00 2001 From: Chen Zhongjin Date: Thu, 9 Mar 2023 16:02:30 +0800 Subject: [PATCH 0807/1017] ftrace: Fix invalid address access in lookup_rec() when index is 0 commit ee92fa443358f4fc0017c1d0d325c27b37802504 upstream. KASAN reported follow problem: BUG: KASAN: use-after-free in lookup_rec Read of size 8 at addr ffff000199270ff0 by task modprobe CPU: 2 Comm: modprobe Call trace: kasan_report __asan_load8 lookup_rec ftrace_location arch_check_ftrace_location check_kprobe_address_safe register_kprobe When checking pg->records[pg->index - 1].ip in lookup_rec(), it can get a pg which is newly added to ftrace_pages_start in ftrace_process_locs(). Before the first pg->index++, index is 0 and accessing pg->records[-1].ip will cause this problem. Don't check the ip when pg->index is 0. Link: https://lore.kernel.org/linux-trace-kernel/20230309080230.36064-1-chenzhongjin@huawei.com Cc: stable@vger.kernel.org Fixes: 9644302e3315 ("ftrace: Speed up search by skipping pages by address") Suggested-by: Steven Rostedt (Google) Signed-off-by: Chen Zhongjin Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ftrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d97c189695cb..67829b6e07bd 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1538,7 +1538,8 @@ static struct dyn_ftrace *lookup_rec(unsigned long start, unsigned long end) key.flags = end; /* overload flags, as it is unsigned long */ for (pg = ftrace_pages_start; pg; pg = pg->next) { - if (end < pg->records[0].ip || + if (pg->index == 0 || + end < pg->records[0].ip || start >= (pg->records[pg->index - 1].ip + MCOUNT_INSN_SIZE)) continue; rec = bsearch(&key, pg->records, pg->index, From b2747b690cb911263fa6e2cbe32a85446f259165 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 2 Mar 2023 18:54:23 +0100 Subject: [PATCH 0808/1017] mm/userfaultfd: propagate uffd-wp bit when PTE-mapping the huge zeropage commit 42b2af2c9b7eede8ef21d0943f84d135e21a32a3 upstream. Currently, we'd lose the userfaultfd-wp marker when PTE-mapping a huge zeropage, resulting in the next write faults in the PMD range not triggering uffd-wp events. Various actions (partial MADV_DONTNEED, partial mremap, partial munmap, partial mprotect) could trigger this. However, most importantly, un-protecting a single sub-page from the userfaultfd-wp handler when processing a uffd-wp event will PTE-map the shared huge zeropage and lose the uffd-wp bit for the remainder of the PMD. Let's properly propagate the uffd-wp bit to the PMDs. #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include static size_t pagesize; static int uffd; static volatile bool uffd_triggered; #define barrier() __asm__ __volatile__("": : :"memory") static void uffd_wp_range(char *start, size_t size, bool wp) { struct uffdio_writeprotect uffd_writeprotect; uffd_writeprotect.range.start = (unsigned long) start; uffd_writeprotect.range.len = size; if (wp) { uffd_writeprotect.mode = UFFDIO_WRITEPROTECT_MODE_WP; } else { uffd_writeprotect.mode = 0; } if (ioctl(uffd, UFFDIO_WRITEPROTECT, &uffd_writeprotect)) { fprintf(stderr, "UFFDIO_WRITEPROTECT failed: %d\n", errno); exit(1); } } static void *uffd_thread_fn(void *arg) { static struct uffd_msg msg; ssize_t nread; while (1) { struct pollfd pollfd; int nready; pollfd.fd = uffd; pollfd.events = POLLIN; nready = poll(&pollfd, 1, -1); if (nready == -1) { fprintf(stderr, "poll() failed: %d\n", errno); exit(1); } nread = read(uffd, &msg, sizeof(msg)); if (nread <= 0) continue; if (msg.event != UFFD_EVENT_PAGEFAULT || !(msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WP)) { printf("FAIL: wrong uffd-wp event fired\n"); exit(1); } /* un-protect the single page. */ uffd_triggered = true; uffd_wp_range((char *)(uintptr_t)msg.arg.pagefault.address, pagesize, false); } return arg; } static int setup_uffd(char *map, size_t size) { struct uffdio_api uffdio_api; struct uffdio_register uffdio_register; pthread_t thread; uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY); if (uffd < 0) { fprintf(stderr, "syscall() failed: %d\n", errno); return -errno; } uffdio_api.api = UFFD_API; uffdio_api.features = UFFD_FEATURE_PAGEFAULT_FLAG_WP; if (ioctl(uffd, UFFDIO_API, &uffdio_api) < 0) { fprintf(stderr, "UFFDIO_API failed: %d\n", errno); return -errno; } if (!(uffdio_api.features & UFFD_FEATURE_PAGEFAULT_FLAG_WP)) { fprintf(stderr, "UFFD_FEATURE_WRITEPROTECT missing\n"); return -ENOSYS; } uffdio_register.range.start = (unsigned long) map; uffdio_register.range.len = size; uffdio_register.mode = UFFDIO_REGISTER_MODE_WP; if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register) < 0) { fprintf(stderr, "UFFDIO_REGISTER failed: %d\n", errno); return -errno; } pthread_create(&thread, NULL, uffd_thread_fn, NULL); return 0; } int main(void) { const size_t size = 4 * 1024 * 1024ull; char *map, *cur; pagesize = getpagesize(); map = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); if (map == MAP_FAILED) { fprintf(stderr, "mmap() failed\n"); return -errno; } if (madvise(map, size, MADV_HUGEPAGE)) { fprintf(stderr, "MADV_HUGEPAGE failed\n"); return -errno; } if (setup_uffd(map, size)) return 1; /* Read the whole range, populating zeropages. */ madvise(map, size, MADV_POPULATE_READ); /* Write-protect the whole range. */ uffd_wp_range(map, size, true); /* Make sure uffd-wp triggers on each page. */ for (cur = map; cur < map + size; cur += pagesize) { uffd_triggered = false; barrier(); /* Trigger a write fault. */ *cur = 1; barrier(); if (!uffd_triggered) { printf("FAIL: uffd-wp did not trigger\n"); return 1; } } printf("PASS: uffd-wp triggered\n"); return 0; } Link: https://lkml.kernel.org/r/20230302175423.589164-1-david@redhat.com Fixes: e06f1e1dd499 ("userfaultfd: wp: enabled write protection in userfaultfd API") Signed-off-by: David Hildenbrand Acked-by: Peter Xu Cc: Mike Rapoport Cc: Andrea Arcangeli Cc: Jerome Glisse Cc: Shaohua Li Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/huge_memory.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 9b15760e0541..e4c690c21fc9 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1994,7 +1994,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, { struct mm_struct *mm = vma->vm_mm; pgtable_t pgtable; - pmd_t _pmd; + pmd_t _pmd, old_pmd; int i; /* @@ -2005,7 +2005,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, * * See Documentation/vm/mmu_notifier.rst */ - pmdp_huge_clear_flush(vma, haddr, pmd); + old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); pgtable = pgtable_trans_huge_withdraw(mm, pmd); pmd_populate(mm, &_pmd, pgtable); @@ -2014,6 +2014,8 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma, pte_t *pte, entry; entry = pfn_pte(my_zero_pfn(haddr), vma->vm_page_prot); entry = pte_mkspecial(entry); + if (pmd_uffd_wp(old_pmd)) + entry = pte_mkuffd_wp(entry); pte = pte_offset_map(&_pmd, haddr); VM_BUG_ON(!pte_none(*pte)); set_pte_at(mm, haddr, pte, entry); From 03fc29e75e44bac3108068a9403ff1b316f3f0fa Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Mon, 6 Mar 2023 17:27:51 +0100 Subject: [PATCH 0809/1017] mmc: sdhci_am654: lower power-on failed message severity commit 11440da77d6020831ee6f9ce4551b545dea789ee upstream. Lower the power-on failed message severity from warn to info when the controller does not power-up. It's normal to have this situation when the SD card slot is empty, therefore we should not warn the user about it. Fixes: 7ca0f166f5b2 ("mmc: sdhci_am654: Add workaround for card detect debounce timer") Signed-off-by: Francesco Dolcini Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230306162751.163369-1-francesco@dolcini.it Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci_am654.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index 24cd6d3dc647..bf2592774165 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -369,7 +369,7 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg) MAX_POWER_ON_TIMEOUT, false, host, val, reg); if (ret) - dev_warn(mmc_dev(host->mmc), "Power on failed\n"); + dev_info(mmc_dev(host->mmc), "Power on failed\n"); } } From 38742635eda98fb5d3304d921cddaaa62d656814 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 16 Mar 2023 11:38:19 +0100 Subject: [PATCH 0810/1017] fbdev: stifb: Provide valid pixelclock and add fb_check_var() checks commit 203873a535d627c668f293be0cb73e26c30f9cc7 upstream. Find a valid modeline depending on the machine graphic card configuration and add the fb_check_var() function to validate Xorg provided graphics settings. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/stifb.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index 3feb6e40d56d..ef8a4c5fc687 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -921,6 +921,28 @@ SETUP_HCRX(struct stifb_info *fb) /* ------------------- driver specific functions --------------------------- */ +static int +stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct stifb_info *fb = container_of(info, struct stifb_info, info); + + if (var->xres != fb->info.var.xres || + var->yres != fb->info.var.yres || + var->bits_per_pixel != fb->info.var.bits_per_pixel) + return -EINVAL; + + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + var->xoffset = 0; + var->yoffset = 0; + var->grayscale = fb->info.var.grayscale; + var->red.length = fb->info.var.red.length; + var->green.length = fb->info.var.green.length; + var->blue.length = fb->info.var.blue.length; + + return 0; +} + static int stifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) @@ -1145,6 +1167,7 @@ stifb_init_display(struct stifb_info *fb) static const struct fb_ops stifb_ops = { .owner = THIS_MODULE, + .fb_check_var = stifb_check_var, .fb_setcolreg = stifb_setcolreg, .fb_blank = stifb_blank, .fb_fillrect = stifb_fillrect, @@ -1164,6 +1187,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) struct stifb_info *fb; struct fb_info *info; unsigned long sti_rom_address; + char modestr[32]; char *dev_name; int bpp, xres, yres; @@ -1342,6 +1366,9 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) info->flags = FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; info->pseudo_palette = &fb->pseudo_palette; + scnprintf(modestr, sizeof(modestr), "%dx%d-%d", xres, yres, bpp); + fb_find_mode(&info->var, info, modestr, NULL, 0, NULL, bpp); + /* This has to be done !!! */ if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0)) goto out_err1; From 15e926dfd82081e759754ac3917817d427ec2889 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 4 Mar 2023 15:41:07 +0800 Subject: [PATCH 0811/1017] cpuidle: psci: Iterate backwards over list in psci_pd_remove() commit 6b0313c2fa3d2cf991c9ffef6fae6e7ef592ce6d upstream. In case that psci_pd_init_topology() fails for some reason, psci_pd_remove() will be responsible for deleting provider and removing genpd from psci_pd_providers list. There will be a failure when removing the cluster PD, because the cpu (child) PDs haven't been removed. [ 0.050232] CPUidle PSCI: init PM domain cpu0 [ 0.050278] CPUidle PSCI: init PM domain cpu1 [ 0.050329] CPUidle PSCI: init PM domain cpu2 [ 0.050370] CPUidle PSCI: init PM domain cpu3 [ 0.050422] CPUidle PSCI: init PM domain cpu-cluster0 [ 0.050475] PM: genpd_remove: unable to remove cpu-cluster0 [ 0.051412] PM: genpd_remove: removed cpu3 [ 0.051449] PM: genpd_remove: removed cpu2 [ 0.051499] PM: genpd_remove: removed cpu1 [ 0.051546] PM: genpd_remove: removed cpu0 Fix the problem by iterating the provider list reversely, so that parent PD gets removed after child's PDs like below. [ 0.029052] CPUidle PSCI: init PM domain cpu0 [ 0.029076] CPUidle PSCI: init PM domain cpu1 [ 0.029103] CPUidle PSCI: init PM domain cpu2 [ 0.029124] CPUidle PSCI: init PM domain cpu3 [ 0.029151] CPUidle PSCI: init PM domain cpu-cluster0 [ 0.029647] PM: genpd_remove: removed cpu0 [ 0.029666] PM: genpd_remove: removed cpu1 [ 0.029690] PM: genpd_remove: removed cpu2 [ 0.029714] PM: genpd_remove: removed cpu3 [ 0.029738] PM: genpd_remove: removed cpu-cluster0 Fixes: a65a397f2451 ("cpuidle: psci: Add support for PM domains by using genpd") Reviewed-by: Sudeep Holla Reviewed-by: Ulf Hansson Signed-off-by: Shawn Guo Cc: 5.10+ # 5.10+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/cpuidle/cpuidle-psci-domain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index 4a031c62f92a..5098639d41f1 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c @@ -182,7 +182,8 @@ static void psci_pd_remove(void) struct psci_pd_provider *pd_provider, *it; struct generic_pm_domain *genpd; - list_for_each_entry_safe(pd_provider, it, &psci_pd_providers, link) { + list_for_each_entry_safe_reverse(pd_provider, it, + &psci_pd_providers, link) { of_genpd_del_provider(pd_provider->node); genpd = of_genpd_remove_last(pd_provider->node); From 764217184f9ef1fe2c8e1f6abed010dda4a53a94 Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Wed, 1 Mar 2023 22:14:20 +0000 Subject: [PATCH 0812/1017] x86/mce: Make sure logged MCEs are processed after sysfs update commit 4783b9cb374af02d49740e00e2da19fd4ed6dec4 upstream. A recent change introduced a flag to queue up errors found during boot-time polling. These errors will be processed during late init once the MCE subsystem is fully set up. A number of sysfs updates call mce_restart() which goes through a subset of the CPU init flow. This includes polling MCA banks and logging any errors found. Since the same function is used as boot-time polling, errors will be queued. However, the system is now past late init, so the errors will remain queued until another error is found and the workqueue is triggered. Call mce_schedule_work() at the end of mce_restart() so that queued errors are processed. Fixes: 3bff147b187d ("x86/mce: Defer processing of early errors") Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Tony Luck Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230301221420.2203184-1-yazen.ghannam@amd.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/mce/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 1906387a0faf..0b7c81389c50 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -2309,6 +2309,7 @@ static void mce_restart(void) { mce_timer_delete_all(); on_each_cpu(mce_cpu_restart, NULL, 1); + mce_schedule_work(); } /* Toggle features for corrected errors */ From b4a798374f2d269af00886616386beea7388a8ea Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Mon, 6 Mar 2023 08:06:56 -0800 Subject: [PATCH 0813/1017] x86/mm: Fix use of uninitialized buffer in sme_enable() commit cbebd68f59f03633469f3ecf9bea99cd6cce3854 upstream. cmdline_find_option() may fail before doing any initialization of the buffer array. This may lead to unpredictable results when the same buffer is used later in calls to strncmp() function. Fix the issue by returning early if cmdline_find_option() returns an error. Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE. Fixes: aca20d546214 ("x86/mm: Add support to make use of Secure Memory Encryption") Signed-off-by: Nikita Zhandarovich Signed-off-by: Borislav Petkov (AMD) Acked-by: Tom Lendacky Cc: Link: https://lore.kernel.org/r/20230306160656.14844-1-n.zhandarovich@fintech.ru Signed-off-by: Greg Kroah-Hartman --- arch/x86/mm/mem_encrypt_identity.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index 011e042b47ba..5ec47af786dd 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -586,7 +586,8 @@ void __init sme_enable(struct boot_params *bp) cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr | ((u64)bp->ext_cmd_line_ptr << 32)); - cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)); + if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0) + return; if (!strncmp(buffer, cmdline_on, sizeof(buffer))) sme_me_mask = me_mask; From 8f27d432170068709654da9ce7e9e8f3aa2f6b8d Mon Sep 17 00:00:00 2001 From: John Harrison Date: Wed, 15 Feb 2023 17:11:00 -0800 Subject: [PATCH 0814/1017] drm/i915: Don't use stolen memory for ring buffers with LLC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 690e0ec8e63da9a29b39fedc6ed5da09c7c82651 upstream. Direction from hardware is that stolen memory should never be used for ring buffer allocations on platforms with LLC. There are too many caching pitfalls due to the way stolen memory accesses are routed. So it is safest to just not use it. Signed-off-by: John Harrison Fixes: c58b735fc762 ("drm/i915: Allocate rings from stolen") Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: intel-gfx@lists.freedesktop.org Cc: # v4.9+ Tested-by: Jouni Högander Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20230216011101.1909009-2-John.C.Harrison@Intel.com (cherry picked from commit f54c1f6c697c4297f7ed94283c184acc338a5cf8) Signed-off-by: Jani Nikula Signed-off-by: John Harrison Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/gt/intel_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c index 69b2e5509d67..de67b2745258 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring.c +++ b/drivers/gpu/drm/i915/gt/intel_ring.c @@ -108,7 +108,7 @@ static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size) struct i915_vma *vma; obj = ERR_PTR(-ENODEV); - if (i915_ggtt_has_aperture(ggtt)) + if (i915_ggtt_has_aperture(ggtt) && !HAS_LLC(i915)) obj = i915_gem_object_create_stolen(i915, size); if (IS_ERR(obj)) obj = i915_gem_object_create_internal(i915, size); From 5e784a7d07af42057c0576fb647b482f4cb0dc2c Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 2 Mar 2023 13:08:20 +0100 Subject: [PATCH 0815/1017] drm/i915/active: Fix misuse of non-idle barriers as fence trackers commit e0e6b416b25ee14716f3549e0cbec1011b193809 upstream. Users reported oopses on list corruptions when using i915 perf with a number of concurrently running graphics applications. Root cause analysis pointed at an issue in barrier processing code -- a race among perf open / close replacing active barriers with perf requests on kernel context and concurrent barrier preallocate / acquire operations performed during user context first pin / last unpin. When adding a request to a composite tracker, we try to reuse an existing fence tracker, already allocated and registered with that composite. The tracker we obtain may already track another fence, may be an idle barrier, or an active barrier. If the tracker we get occurs a non-idle barrier then we try to delete that barrier from a list of barrier tasks it belongs to. However, while doing that we don't respect return value from a function that performs the barrier deletion. Should the deletion ever fail, we would end up reusing the tracker still registered as a barrier task. Since the same structure field is reused with both fence callback lists and barrier tasks list, list corruptions would likely occur. Barriers are now deleted from a barrier tasks list by temporarily removing the list content, traversing that content with skip over the node to be deleted, then populating the list back with the modified content. Should that intentionally racy concurrent deletion attempts be not serialized, one or more of those may fail because of the list being temporary empty. Related code that ignores the results of barrier deletion was initially introduced in v5.4 by commit d8af05ff38ae ("drm/i915: Allow sharing the idle-barrier from other kernel requests"). However, all users of the barrier deletion routine were apparently serialized at that time, then the issue didn't exhibit itself. Results of git bisect with help of a newly developed igt@gem_barrier_race@remote-request IGT test indicate that list corruptions might start to appear after commit 311770173fac ("drm/i915/gt: Schedule request retirement when timeline idles"), introduced in v5.5. Respect results of barrier deletion attempts -- mark the barrier as idle only if successfully deleted from the list. Then, before proceeding with setting our fence as the one currently tracked, make sure that the tracker we've got is not a non-idle barrier. If that check fails then don't use that tracker but go back and try to acquire a new, usable one. v3: use unlikely() to document what outcome we expect (Andi), - fix bad grammar in commit description. v2: no code changes, - blame commit 311770173fac ("drm/i915/gt: Schedule request retirement when timeline idles"), v5.5, not commit d8af05ff38ae ("drm/i915: Allow sharing the idle-barrier from other kernel requests"), v5.4, - reword commit description. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/6333 Fixes: 311770173fac ("drm/i915/gt: Schedule request retirement when timeline idles") Cc: Chris Wilson Cc: stable@vger.kernel.org # v5.5 Cc: Andi Shyti Signed-off-by: Janusz Krzysztofik Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20230302120820.48740-1-janusz.krzysztofik@linux.intel.com (cherry picked from commit 506006055769b10d1b2b4e22f636f3b45e0e9fc7) Signed-off-by: Jani Nikula Signed-off-by: Janusz Krzysztofik Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_active.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index c4c2d24dc509..0532a5069c04 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -432,8 +432,7 @@ replace_barrier(struct i915_active *ref, struct i915_active_fence *active) * we can use it to substitute for the pending idle-barrer * request that we want to emit on the kernel_context. */ - __active_del_barrier(ref, node_from_active(active)); - return true; + return __active_del_barrier(ref, node_from_active(active)); } int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence) @@ -446,16 +445,19 @@ int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence) if (err) return err; - active = active_instance(ref, idx); - if (!active) { - err = -ENOMEM; - goto out; - } + do { + active = active_instance(ref, idx); + if (!active) { + err = -ENOMEM; + goto out; + } + + if (replace_barrier(ref, active)) { + RCU_INIT_POINTER(active->fence, NULL); + atomic_dec(&ref->count); + } + } while (unlikely(is_barrier(active))); - if (replace_barrier(ref, active)) { - RCU_INIT_POINTER(active->fence, NULL); - atomic_dec(&ref->count); - } if (!__i915_active_fence_set(active, fence)) __i915_active_acquire(ref); From 84e2e393bf9fa47d134eddaeb8319c755e646f30 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Thu, 16 Mar 2023 21:56:16 +0300 Subject: [PATCH 0816/1017] io_uring: avoid null-ptr-deref in io_arm_poll_handler No upstream commit exists for this commit. The issue was introduced with backporting upstream commit c16bda37594f ("io_uring/poll: allow some retries for poll triggering spuriously"). Memory allocation can possibly fail causing invalid pointer be dereferenced just before comparing it to NULL value. Move the pointer check in proper place (upstream has the similar location of the check). In case the request has REQ_F_POLLED flag up, apoll can't be NULL so no need to check there. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Signed-off-by: Fedor Pchelkin Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 445afda927f4..fd799567fc23 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -5792,10 +5792,10 @@ static int io_arm_poll_handler(struct io_kiocb *req) } } else { apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC); + if (unlikely(!apoll)) + return IO_APOLL_ABORTED; apoll->poll.retries = APOLL_MAX_RETRY; } - if (unlikely(!apoll)) - return IO_APOLL_ABORTED; apoll->double_poll = NULL; req->apoll = apoll; req->flags |= REQ_F_POLLED; From b5e0b3d74285f7b5491e7fa5c3c1e0860f924edf Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Tue, 7 Mar 2023 14:35:23 +0100 Subject: [PATCH 0817/1017] s390/ipl: add missing intersection check to ipl_report handling commit a52e5cdbe8016d4e3e6322fd93d71afddb9a5af9 upstream. The code which handles the ipl report is searching for a free location in memory where it could copy the component and certificate entries to. It checks for intersection between the sections required for the kernel and the component/certificate data area, but fails to check whether the data structures linking these data areas together intersect. This might cause the iplreport copy code to overwrite the iplreport itself. Fix this by adding two addtional intersection checks. Cc: Fixes: 9641b8cc733f ("s390/ipl: read IPL report at early boot") Signed-off-by: Sven Schnelle Reviewed-by: Vasily Gorbik Signed-off-by: Vasily Gorbik Signed-off-by: Sven Schnelle Signed-off-by: Greg Kroah-Hartman --- arch/s390/boot/ipl_report.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/s390/boot/ipl_report.c b/arch/s390/boot/ipl_report.c index 0b4965573656..88bacf4999c4 100644 --- a/arch/s390/boot/ipl_report.c +++ b/arch/s390/boot/ipl_report.c @@ -57,11 +57,19 @@ repeat: if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE && intersects(INITRD_START, INITRD_SIZE, safe_addr, size)) safe_addr = INITRD_START + INITRD_SIZE; + if (intersects(safe_addr, size, (unsigned long)comps, comps->len)) { + safe_addr = (unsigned long)comps + comps->len; + goto repeat; + } for_each_rb_entry(comp, comps) if (intersects(safe_addr, size, comp->addr, comp->len)) { safe_addr = comp->addr + comp->len; goto repeat; } + if (intersects(safe_addr, size, (unsigned long)certs, certs->len)) { + safe_addr = (unsigned long)certs + certs->len; + goto repeat; + } for_each_rb_entry(cert, certs) if (intersects(safe_addr, size, cert->addr, cert->len)) { safe_addr = cert->addr + cert->len; From 337aa99f76ea07a0cd9eebe694fd21760c343330 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 15 Jan 2023 09:20:32 +0100 Subject: [PATCH 0818/1017] PCI: Unify delay handling for reset and resume commit ac91e6980563ed53afadd925fa6585ffd2bc4a2c upstream. Sheng Bi reports that pci_bridge_secondary_bus_reset() may fail to wait for devices on the secondary bus to become accessible after reset: Although it does call pci_dev_wait(), it erroneously passes the bridge's pci_dev rather than that of a child. The bridge of course is always accessible while its secondary bus is reset, so pci_dev_wait() returns immediately. Sheng Bi proposes introducing a new pci_bridge_secondary_bus_wait() function which is called from pci_bridge_secondary_bus_reset(): https://lore.kernel.org/linux-pci/20220523171517.32407-1-windy.bi.enflame@gmail.com/ However we already have pci_bridge_wait_for_secondary_bus() which does almost exactly what we need. So far it's only called on resume from D3cold (which implies a Fundamental Reset per PCIe r6.0 sec 5.8). Re-using it for Secondary Bus Resets is a leaner and more rational approach than introducing a new function. That only requires a few minor tweaks: - Amend pci_bridge_wait_for_secondary_bus() to await accessibility of the first device on the secondary bus by calling pci_dev_wait() after performing the prescribed delays. pci_dev_wait() needs two parameters, a reset reason and a timeout, which callers must now pass to pci_bridge_wait_for_secondary_bus(). The timeout is 1 sec for resume (PCIe r6.0 sec 6.6.1) and 60 sec for reset (commit 821cdad5c46c ("PCI: Wait up to 60 seconds for device to become ready after FLR")). Introduce a PCI_RESET_WAIT macro for the 1 sec timeout. - Amend pci_bridge_wait_for_secondary_bus() to return 0 on success or -ENOTTY on error for consumption by pci_bridge_secondary_bus_reset(). - Drop an unnecessary 1 sec delay from pci_reset_secondary_bus() which is now performed by pci_bridge_wait_for_secondary_bus(). A static delay this long is only necessary for Conventional PCI, so modern PCIe systems benefit from shorter reset times as a side effect. Fixes: 6b2f1351af56 ("PCI: Wait for device to become ready after secondary bus reset") Link: https://lore.kernel.org/r/da77c92796b99ec568bd070cbe4725074a117038.1673769517.git.lukas@wunner.de Reported-by: Sheng Bi Tested-by: Ravi Kishore Koppuravuri Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg Reviewed-by: Kuppuswamy Sathyanarayanan Cc: stable@vger.kernel.org # v4.17+ Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 4 +-- drivers/pci/pci.c | 54 ++++++++++++++++++---------------------- drivers/pci/pci.h | 10 +++++++- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8b587fc97f7b..c22cc20db1a7 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -911,7 +911,7 @@ static int pci_pm_resume_noirq(struct device *dev) pcie_pme_root_status_cleanup(pci_dev); if (!skip_bus_pm && prev_state == PCI_D3cold) - pci_bridge_wait_for_secondary_bus(pci_dev); + pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); if (pci_has_legacy_pm_support(pci_dev)) return 0; @@ -1298,7 +1298,7 @@ static int pci_pm_runtime_resume(struct device *dev) pci_pm_default_resume(pci_dev); if (prev_state == PCI_D3cold) - pci_bridge_wait_for_secondary_bus(pci_dev); + pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); if (pm && pm->runtime_resume) error = pm->runtime_resume(dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 744a2e05635b..f1a3f165f88a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1221,7 +1221,7 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) return -ENOTTY; } - if (delay > 1000) + if (delay > PCI_RESET_WAIT) pci_info(dev, "not ready %dms after %s; waiting\n", delay - 1, reset_type); @@ -1230,7 +1230,7 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) pci_read_config_dword(dev, PCI_COMMAND, &id); } - if (delay > 1000) + if (delay > PCI_RESET_WAIT) pci_info(dev, "ready %dms after %s\n", delay - 1, reset_type); @@ -4792,24 +4792,31 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus) /** * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible * @dev: PCI bridge + * @reset_type: reset type in human-readable form + * @timeout: maximum time to wait for devices on secondary bus (milliseconds) * * Handle necessary delays before access to the devices on the secondary - * side of the bridge are permitted after D3cold to D0 transition. + * side of the bridge are permitted after D3cold to D0 transition + * or Conventional Reset. * * For PCIe this means the delays in PCIe 5.0 section 6.6.1. For * conventional PCI it means Tpvrh + Trhfa specified in PCI 3.0 section * 4.3.2. + * + * Return 0 on success or -ENOTTY if the first device on the secondary bus + * failed to become accessible. */ -void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) +int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, + int timeout) { struct pci_dev *child; int delay; if (pci_dev_is_disconnected(dev)) - return; + return 0; if (!pci_is_bridge(dev)) - return; + return 0; down_read(&pci_bus_sem); @@ -4821,14 +4828,14 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) */ if (!dev->subordinate || list_empty(&dev->subordinate->devices)) { up_read(&pci_bus_sem); - return; + return 0; } /* Take d3cold_delay requirements into account */ delay = pci_bus_max_d3cold_delay(dev->subordinate); if (!delay) { up_read(&pci_bus_sem); - return; + return 0; } child = list_first_entry(&dev->subordinate->devices, struct pci_dev, @@ -4837,14 +4844,12 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) /* * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before - * accessing the device after reset (that is 1000 ms + 100 ms). In - * practice this should not be needed because we don't do power - * management for them (see pci_bridge_d3_possible()). + * accessing the device after reset (that is 1000 ms + 100 ms). */ if (!pci_is_pcie(dev)) { pci_dbg(dev, "waiting %d ms for secondary bus\n", 1000 + delay); msleep(1000 + delay); - return; + return 0; } /* @@ -4861,11 +4866,11 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) * configuration requests if we only wait for 100 ms (see * https://bugzilla.kernel.org/show_bug.cgi?id=203885). * - * Therefore we wait for 100 ms and check for the device presence. - * If it is still not present give it an additional 100 ms. + * Therefore we wait for 100 ms and check for the device presence + * until the timeout expires. */ if (!pcie_downstream_port(dev)) - return; + return 0; if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) { pci_dbg(dev, "waiting %d ms for downstream link\n", delay); @@ -4876,14 +4881,11 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) if (!pcie_wait_for_link_delay(dev, true, delay)) { /* Did not train, no need to wait any further */ pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n"); - return; + return -ENOTTY; } } - if (!pci_device_is_present(child)) { - pci_dbg(child, "waiting additional %d ms to become accessible\n", delay); - msleep(delay); - } + return pci_dev_wait(child, reset_type, timeout - delay); } void pci_reset_secondary_bus(struct pci_dev *dev) @@ -4902,15 +4904,6 @@ void pci_reset_secondary_bus(struct pci_dev *dev) ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); - - /* - * Trhfa for conventional PCI is 2^25 clock cycles. - * Assuming a minimum 33MHz clock this results in a 1s - * delay before we can consider subordinate devices to - * be re-initialized. PCIe has some ways to shorten this, - * but we don't make use of them yet. - */ - ssleep(1); } void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) @@ -4929,7 +4922,8 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev) { pcibios_reset_secondary_bus(dev); - return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS); + return pci_bridge_wait_for_secondary_bus(dev, "bus reset", + PCIE_RESET_READY_POLL_MS); } EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9197d7362731..77dd7bbe861d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -47,6 +47,13 @@ int pci_bus_error_reset(struct pci_dev *dev); #define PCI_PM_D3HOT_WAIT 10 /* msec */ #define PCI_PM_D3COLD_WAIT 100 /* msec */ +/* + * Following exit from Conventional Reset, devices must be ready within 1 sec + * (PCIe r6.0 sec 6.6.1). A D3cold to D0 transition implies a Conventional + * Reset (PCIe r6.0 sec 5.8). + */ +#define PCI_RESET_WAIT 1000 /* msec */ + /** * struct pci_platform_pm_ops - Firmware PM callbacks * @@ -108,7 +115,8 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev); bool pci_bridge_d3_possible(struct pci_dev *dev); void pci_bridge_d3_update(struct pci_dev *dev); -void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev); +int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, + int timeout); static inline void pci_wakeup_event(struct pci_dev *dev) { From d0292124bb5787a2f1ab1316509e801ca89c10fb Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 15 Jan 2023 09:20:33 +0100 Subject: [PATCH 0819/1017] PCI/DPC: Await readiness of secondary bus after reset commit 53b54ad074de1896f8b021615f65b27f557ce874 upstream. pci_bridge_wait_for_secondary_bus() is called after a Secondary Bus Reset, but not after a DPC-induced Hot Reset. As a result, the delays prescribed by PCIe r6.0 sec 6.6.1 are not observed and devices on the secondary bus may be accessed before they're ready. One affected device is Intel's Ponte Vecchio HPC GPU. It comprises a PCIe switch whose upstream port is not immediately ready after reset. Because its config space is restored too early, it remains in D0uninitialized, its subordinate devices remain inaccessible and DPC recovery fails with messages such as: i915 0000:8c:00.0: can't change power state from D3cold to D0 (config space inaccessible) intel_vsec 0000:8e:00.1: can't change power state from D3cold to D0 (config space inaccessible) pcieport 0000:89:02.0: AER: device recovery failed Fix it. Link: https://lore.kernel.org/r/9f5ff00e1593d8d9a4b452398b98aa14d23fca11.1673769517.git.lukas@wunner.de Tested-by: Ravi Kishore Koppuravuri Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Reviewed-by: Mika Westerberg Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 3 --- drivers/pci/pci.h | 6 ++++++ drivers/pci/pcie/dpc.c | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f1a3f165f88a..d37013d007b6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -157,9 +157,6 @@ static int __init pcie_port_pm_setup(char *str) } __setup("pcie_port_pm=", pcie_port_pm_setup); -/* Time to wait after a reset for device to become responsive */ -#define PCIE_RESET_READY_POLL_MS 60000 - /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children * @bus: pointer to PCI bus structure to search diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 77dd7bbe861d..72436000ff25 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -53,6 +53,12 @@ int pci_bus_error_reset(struct pci_dev *dev); * Reset (PCIe r6.0 sec 5.8). */ #define PCI_RESET_WAIT 1000 /* msec */ +/* + * Devices may extend the 1 sec period through Request Retry Status completions + * (PCIe r6.0 sec 2.3.1). The spec does not provide an upper limit, but 60 sec + * ought to be enough for any device to become responsive. + */ +#define PCIE_RESET_READY_POLL_MS 60000 /* msec */ /** * struct pci_platform_pm_ops - Firmware PM callbacks diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index c556e7beafe3..f21d64ae4ffc 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -170,8 +170,8 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev) pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS, PCI_EXP_DPC_STATUS_TRIGGER); - if (!pcie_wait_for_link(pdev, true)) { - pci_info(pdev, "Data Link Layer Link Active not set in 1000 msec\n"); + if (pci_bridge_wait_for_secondary_bus(pdev, "DPC", + PCIE_RESET_READY_POLL_MS)) { clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags); ret = PCI_ERS_RESULT_DISCONNECT; } else { From d6f223cfef322d92305a697b848852ba4c2caecc Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 18 Mar 2023 12:15:15 +0200 Subject: [PATCH 0820/1017] xfs: don't assert fail on perag references on teardown commit 5b55cbc2d72632e874e50d2e36bce608e55aaaea upstream. [backport for 5.10.y, prior to perag refactoring in v5.14] Not fatal, the assert is there to catch developer attention. I'm seeing this occasionally during recoveryloop testing after a shutdown, and I don't want this to stop an overnight recoveryloop run as it is currently doing. Convert the ASSERT to a XFS_IS_CORRUPT() check so it will dump a corruption report into the log and cause a test failure that way, but it won't stop the machine dead. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_mount.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a2a5a0fd9233..402cf828cc91 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -126,7 +126,6 @@ __xfs_free_perag( { struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head); - ASSERT(atomic_read(&pag->pag_ref) == 0); kmem_free(pag); } @@ -145,7 +144,7 @@ xfs_free_perag( pag = radix_tree_delete(&mp->m_perag_tree, agno); spin_unlock(&mp->m_perag_lock); ASSERT(pag); - ASSERT(atomic_read(&pag->pag_ref) == 0); + XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0); xfs_iunlink_destroy(pag); xfs_buf_hash_destroy(pag); call_rcu(&pag->rcu_head, __xfs_free_perag); From be60f08c03dedb2e78d4c472de92b812ac2e5dca Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 18 Mar 2023 12:15:16 +0200 Subject: [PATCH 0821/1017] xfs: purge dquots after inode walk fails during quotacheck commit 86d40f1e49e9a909d25c35ba01bea80dbcd758cb upstream. [add XFS_QMOPT_QUOTALL flag to xfs_qm_dqpurge_all() for 5.10.y backport] xfs/434 and xfs/436 have been reporting occasional memory leaks of xfs_dquot objects. These tests themselves were the messenger, not the culprit, since they unload the xfs module, which trips the slub debugging code while tearing down all the xfs slab caches: ============================================================================= BUG xfs_dquot (Tainted: G W ): Objects remaining in xfs_dquot on __kmem_cache_shutdown() ----------------------------------------------------------------------------- Slab 0xffffea000606de00 objects=30 used=5 fp=0xffff888181b78a78 flags=0x17ff80000010200(slab|head|node=0|zone=2|lastcpupid=0xfff) CPU: 0 PID: 3953166 Comm: modprobe Tainted: G W 5.18.0-rc6-djwx #rc6 d5824be9e46a2393677bda868f9b154d917ca6a7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20171121_152543-x86-ol7-builder-01.us.oracle.com-4.el7.1 04/01/2014 Since we don't generally rmmod the xfs module between fstests, this means that xfs/434 is really just the canary in the coal mine -- something leaked a dquot, but we don't know who. After days of pounding on fstests with kmemleak enabled, I finally got it to spit this out: unreferenced object 0xffff8880465654c0 (size 536): comm "u10:4", pid 88, jiffies 4294935810 (age 29.512s) hex dump (first 32 bytes): 60 4a 56 46 80 88 ff ff 58 ea e4 5c 80 88 ff ff `JVF....X..\.... 00 e0 52 49 80 88 ff ff 01 00 01 00 00 00 00 00 ..RI............ backtrace: [] xfs_dquot_alloc+0x2c/0x530 [xfs] [] xfs_qm_dqread+0x6f/0x330 [xfs] [] xfs_qm_dqget+0x132/0x4e0 [xfs] [] xfs_qm_quotacheck_dqadjust+0xa0/0x3e0 [xfs] [] xfs_qm_dqusage_adjust+0x35d/0x4f0 [xfs] [] xfs_iwalk_ag_recs+0x348/0x5d0 [xfs] [] xfs_iwalk_run_callbacks+0x273/0x540 [xfs] [] xfs_iwalk_ag+0x5ed/0x890 [xfs] [] xfs_iwalk_ag_work+0xff/0x170 [xfs] [] xfs_pwork_work+0x79/0x130 [xfs] [] process_one_work+0x672/0x1040 [] worker_thread+0x59b/0xec0 [] kthread+0x29e/0x340 [] ret_from_fork+0x1f/0x30 Now we know that quotacheck is at fault, but even this report was canaryish -- it was triggered by xfs/494, which doesn't actually mount any filesystems. (kmemleak can be a little slow to notice leaks, even with fstests repeatedly whacking it to look for them.) Looking at the *previous* fstest, however, showed that the test run before xfs/494 was xfs/117. The tipoff to the problem is in this excerpt from dmesg: XFS (sda4): Quotacheck needed: Please wait. XFS (sda4): Metadata corruption detected at xfs_dinode_verify.part.0+0xdb/0x7b0 [xfs], inode 0x119 dinode XFS (sda4): Unmount and run xfs_repair XFS (sda4): First 128 bytes of corrupted metadata buffer: 00000000: 49 4e 81 a4 03 02 00 00 00 00 00 00 00 00 00 00 IN.............. 00000010: 00 00 00 01 00 00 00 00 00 90 57 54 54 1a 4c 68 ..........WTT.Lh 00000020: 81 f9 7d e1 6d ee 16 00 34 bd 7d e1 6d ee 16 00 ..}.m...4.}.m... 00000030: 34 bd 7d e1 6d ee 16 00 00 00 00 00 00 00 00 00 4.}.m........... 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 00 00 00 02 00 00 00 00 00 00 00 00 96 80 f3 ab ................ 00000060: ff ff ff ff da 57 7b 11 00 00 00 00 00 00 00 03 .....W{......... 00000070: 00 00 00 01 00 00 00 10 00 00 00 00 00 00 00 08 ................ XFS (sda4): Quotacheck: Unsuccessful (Error -117): Disabling quotas. The dinode verifier decided that the inode was corrupt, which causes iget to return with EFSCORRUPTED. Since this happened during quotacheck, it is obvious that the kernel aborted the inode walk on account of the corruption error and disabled quotas. Unfortunately, we neglect to purge the dquot cache before doing that, which is how the dquots leaked. The problems started 10 years ago in commit b84a3a, when the dquot lists were converted to a radix tree, but the error handling behavior was not correctly preserved -- in that commit, if the bulkstat failed and usrquota was enabled, the bulkstat failure code would be overwritten by the result of flushing all the dquots to disk. As long as that succeeds, we'd continue the quota mount as if everything were ok, but instead we're now operating with a corrupt inode and incorrect quota usage counts. I didn't notice this bug in 2019 when I wrote commit ebd126a, which changed quotacheck to skip the dqflush when the scan doesn't complete due to inode walk failures. Introduced-by: b84a3a96751f ("xfs: remove the per-filesystem list of dquots") Fixes: ebd126a651f8 ("xfs: convert quotacheck to use the new iwalk functions") Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_qm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 64e5da33733b..3c17e0c0f816 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -1318,8 +1318,15 @@ xfs_qm_quotacheck( error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true, NULL); - if (error) + if (error) { + /* + * The inode walk may have partially populated the dquot + * caches. We must purge them before disabling quota and + * tearing down the quotainfo, or else the dquots will leak. + */ + xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL); goto error_return; + } /* * We've made all the changes that we need to make incore. Flush them From c84fb2962680fa85d9916d67026e4f01ea4cadca Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 18 Mar 2023 12:15:17 +0200 Subject: [PATCH 0822/1017] xfs: don't leak btree cursor when insrec fails after a split commit a54f78def73d847cb060b18c4e4a3d1d26c9ca6d upstream. The recent patch to improve btree cycle checking caused a regression when I rebased the in-memory btree branch atop the 5.19 for-next branch, because in-memory short-pointer btrees do not have AG numbers. This produced the following complaint from kmemleak: unreferenced object 0xffff88803d47dde8 (size 264): comm "xfs_io", pid 4889, jiffies 4294906764 (age 24.072s) hex dump (first 32 bytes): 90 4d 0b 0f 80 88 ff ff 00 a0 bd 05 80 88 ff ff .M.............. e0 44 3a a0 ff ff ff ff 00 df 08 06 80 88 ff ff .D:............. backtrace: [] xfbtree_dup_cursor+0x49/0xc0 [xfs] [] xfs_btree_dup_cursor+0x3b/0x200 [xfs] [] __xfs_btree_split+0x6ad/0x820 [xfs] [] xfs_btree_split+0x60/0x110 [xfs] [] xfs_btree_make_block_unfull+0x19a/0x1f0 [xfs] [] xfs_btree_insrec+0x3aa/0x810 [xfs] [] xfs_btree_insert+0xb3/0x240 [xfs] [] xfs_rmap_insert+0x99/0x200 [xfs] [] xfs_rmap_map_shared+0x192/0x5f0 [xfs] [] xfs_rmap_map_raw+0x6b/0x90 [xfs] [] xrep_rmap_stash+0xd5/0x1d0 [xfs] [] xrep_rmap_visit_bmbt+0xa0/0xf0 [xfs] [] xrep_rmap_scan_iext+0x56/0xa0 [xfs] [] xrep_rmap_scan_ifork+0xd8/0x160 [xfs] [] xrep_rmap_scan_inode+0x35/0x80 [xfs] [] xrep_rmap_find_rmaps+0x10e/0x270 [xfs] I noticed that xfs_btree_insrec has a bunch of debug code that return out of the function immediately, without freeing the "new" btree cursor that can be returned when _make_block_unfull calls xfs_btree_split. Fix the error return in this function to free the btree cursor. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/libxfs/xfs_btree.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 24c7d30e41df..0926363179a7 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -3190,7 +3190,7 @@ xfs_btree_insrec( struct xfs_btree_block *block; /* btree block */ struct xfs_buf *bp; /* buffer for block */ union xfs_btree_ptr nptr; /* new block ptr */ - struct xfs_btree_cur *ncur; /* new btree cursor */ + struct xfs_btree_cur *ncur = NULL; /* new btree cursor */ union xfs_btree_key nkey; /* new block key */ union xfs_btree_key *lkey; int optr; /* old key/record index */ @@ -3270,7 +3270,7 @@ xfs_btree_insrec( #ifdef DEBUG error = xfs_btree_check_block(cur, block, level, bp); if (error) - return error; + goto error0; #endif /* @@ -3290,7 +3290,7 @@ xfs_btree_insrec( for (i = numrecs - ptr; i >= 0; i--) { error = xfs_btree_debug_check_ptr(cur, pp, i, level); if (error) - return error; + goto error0; } xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1); @@ -3375,6 +3375,8 @@ xfs_btree_insrec( return 0; error0: + if (ncur) + xfs_btree_del_cursor(ncur, error); return error; } From 35f049abbae3954fe2c3d57d62fe6624d9b29df6 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 18 Mar 2023 12:15:18 +0200 Subject: [PATCH 0823/1017] xfs: remove XFS_PREALLOC_SYNC commit 472c6e46f589c26057596dcba160712a5b3e02c5 upstream. [partial backport for dependency - xfs_ioc_space() still uses XFS_PREALLOC_SYNC] Callers can acheive the same thing by calling xfs_log_force_inode() after making their modifications. There is no need for xfs_update_prealloc_flags() to do this. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_file.c | 13 +++++++------ fs/xfs/xfs_pnfs.c | 6 ++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 4d6bf8d4974f..630525b1da77 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -94,8 +94,6 @@ xfs_update_prealloc_flags( ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - if (flags & XFS_PREALLOC_SYNC) - xfs_trans_set_sync(tp); return xfs_trans_commit(tp); } @@ -1000,9 +998,6 @@ xfs_file_fallocate( } } - if (file->f_flags & O_DSYNC) - flags |= XFS_PREALLOC_SYNC; - error = xfs_update_prealloc_flags(ip, flags); if (error) goto out_unlock; @@ -1024,8 +1019,14 @@ xfs_file_fallocate( * leave shifted extents past EOF and hence losing access to * the data that is contained within them. */ - if (do_file_insert) + if (do_file_insert) { error = xfs_insert_file_space(ip, offset, len); + if (error) + goto out_unlock; + } + + if (file->f_flags & O_DSYNC) + error = xfs_log_force_inode(ip); out_unlock: xfs_iunlock(ip, iolock); diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index f3082a957d5e..64ab54f2fe81 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c @@ -164,10 +164,12 @@ xfs_fs_map_blocks( * that the blocks allocated and handed out to the client are * guaranteed to be present even after a server crash. */ - error = xfs_update_prealloc_flags(ip, - XFS_PREALLOC_SET | XFS_PREALLOC_SYNC); + error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET); + if (!error) + error = xfs_log_force_inode(ip); if (error) goto out_unlock; + } else { xfs_iunlock(ip, lock_flags); } From 308dfe49eb753d7263fa4e001251d733c710ed14 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 18 Mar 2023 12:15:19 +0200 Subject: [PATCH 0824/1017] xfs: fallocate() should call file_modified() commit fbe7e520036583a783b13ff9744e35c2a329d9a4 upstream. In XFS, we always update the inode change and modification time when any fallocate() operation succeeds. Furthermore, as various fallocate modes can change the file contents (extending EOF, punching holes, zeroing things, shifting extents), we should drop file privileges like suid just like we do for a regular write(). There's already a VFS helper that figures all this out for us, so use that. The net effect of this is that we no longer drop suid/sgid if the caller is root, but we also now drop file capabilities. We also move the xfs_update_prealloc_flags() function so that it now is only called by the scope that needs to set the the prealloc flag. Based on a patch from Darrick Wong. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_file.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 630525b1da77..a95af57a59a7 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -895,6 +895,10 @@ xfs_file_fallocate( goto out_unlock; } + error = file_modified(file); + if (error) + goto out_unlock; + if (mode & FALLOC_FL_PUNCH_HOLE) { error = xfs_free_file_space(ip, offset, len); if (error) @@ -996,11 +1000,12 @@ xfs_file_fallocate( if (error) goto out_unlock; } - } - error = xfs_update_prealloc_flags(ip, flags); - if (error) - goto out_unlock; + error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET); + if (error) + goto out_unlock; + + } /* Change file size if needed */ if (new_size) { From 8cf9400f8948781cc9175f94666421e77622d639 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 18 Mar 2023 12:15:20 +0200 Subject: [PATCH 0825/1017] xfs: set prealloc flag in xfs_alloc_file_space() commit 0b02c8c0d75a738c98c35f02efb36217c170d78c upstream. [backport for 5.10.y] Now that we only call xfs_update_prealloc_flags() from xfs_file_fallocate() in the case where we need to set the preallocation flag, do this in xfs_alloc_file_space() where we already have the inode joined into a transaction and get rid of the call to xfs_update_prealloc_flags() from the fallocate code. This also means that we now correctly avoid setting the XFS_DIFLAG_PREALLOC flag when xfs_is_always_cow_inode() is true, as these inodes will never have preallocated extents. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_bmap_util.c | 9 +++------ fs/xfs/xfs_file.c | 8 -------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 7371a7f7c652..fbab1042bc90 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -800,9 +800,6 @@ xfs_alloc_file_space( quota_flag = XFS_QMOPT_RES_REGBLKS; } - /* - * Allocate and setup the transaction. - */ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, resrtextents, 0, &tp); @@ -830,9 +827,9 @@ xfs_alloc_file_space( if (error) goto error0; - /* - * Complete the transaction - */ + ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + error = xfs_trans_commit(tp); xfs_iunlock(ip, XFS_ILOCK_EXCL); if (error) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index a95af57a59a7..9b6c5ba5fdfb 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -850,7 +850,6 @@ xfs_file_fallocate( struct inode *inode = file_inode(file); struct xfs_inode *ip = XFS_I(inode); long error; - enum xfs_prealloc_flags flags = 0; uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; loff_t new_size = 0; bool do_file_insert = false; @@ -948,8 +947,6 @@ xfs_file_fallocate( } do_file_insert = true; } else { - flags |= XFS_PREALLOC_SET; - if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + len > i_size_read(inode)) { new_size = offset + len; @@ -1000,11 +997,6 @@ xfs_file_fallocate( if (error) goto out_unlock; } - - error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET); - if (error) - goto out_unlock; - } /* Change file size if needed */ From f60b68c46444e4e9321a4313efd5ea0eddd77fb7 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 18 Mar 2023 12:15:21 +0200 Subject: [PATCH 0826/1017] xfs: use setattr_copy to set vfs inode attributes commit e014f37db1a2d109afa750042ac4d69cf3e3d88e upstream. [remove userns argument of setattr_copy() for 5.10.y backport] Filipe Manana pointed out that XFS' behavior w.r.t. setuid/setgid revocation isn't consistent with btrfs[1] or ext4. Those two filesystems use the VFS function setattr_copy to convey certain attributes from struct iattr into the VFS inode structure. Andrey Zhadchenko reported[2] that XFS uses the wrong user namespace to decide if it should clear setgid and setuid on a file attribute update. This is a second symptom of the problem that Filipe noticed. XFS, on the other hand, open-codes setattr_copy in xfs_setattr_mode, xfs_setattr_nonsize, and xfs_setattr_time. Regrettably, setattr_copy is /not/ a simple copy function; it contains additional logic to clear the setgid bit when setting the mode, and XFS' version no longer matches. The VFS implements its own setuid/setgid stripping logic, which establishes consistent behavior. It's a tad unfortunate that it's scattered across notify_change, should_remove_suid, and setattr_copy but XFS should really follow the Linux VFS. Adapt XFS to use the VFS functions and get rid of the old functions. [1] https://lore.kernel.org/fstests/CAL3q7H47iNQ=Wmk83WcGB-KBJVOEtR9+qGczzCeXJ9Y2KCV25Q@mail.gmail.com/ [2] https://lore.kernel.org/linux-xfs/20220221182218.748084-1-andrey.zhadchenko@virtuozzo.com/ Fixes: 7fa294c8991c ("userns: Allow chown and setgid preservation") Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Reviewed-by: Christian Brauner Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_iops.c | 56 +++-------------------------------------------- fs/xfs/xfs_pnfs.c | 3 ++- 2 files changed, 5 insertions(+), 54 deletions(-) diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 6a3026e78a9b..69fef29df428 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -595,37 +595,6 @@ xfs_vn_getattr( return 0; } -static void -xfs_setattr_mode( - struct xfs_inode *ip, - struct iattr *iattr) -{ - struct inode *inode = VFS_I(ip); - umode_t mode = iattr->ia_mode; - - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - - inode->i_mode &= S_IFMT; - inode->i_mode |= mode & ~S_IFMT; -} - -void -xfs_setattr_time( - struct xfs_inode *ip, - struct iattr *iattr) -{ - struct inode *inode = VFS_I(ip); - - ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - - if (iattr->ia_valid & ATTR_ATIME) - inode->i_atime = iattr->ia_atime; - if (iattr->ia_valid & ATTR_CTIME) - inode->i_ctime = iattr->ia_ctime; - if (iattr->ia_valid & ATTR_MTIME) - inode->i_mtime = iattr->ia_mtime; -} - static int xfs_vn_change_ok( struct dentry *dentry, @@ -740,16 +709,6 @@ xfs_setattr_nonsize( goto out_cancel; } - /* - * CAP_FSETID overrides the following restrictions: - * - * The set-user-ID and set-group-ID bits of a file will be - * cleared upon successful return from chown() - */ - if ((inode->i_mode & (S_ISUID|S_ISGID)) && - !capable(CAP_FSETID)) - inode->i_mode &= ~(S_ISUID|S_ISGID); - /* * Change the ownerships and register quota modifications * in the transaction. @@ -761,7 +720,6 @@ xfs_setattr_nonsize( olddquot1 = xfs_qm_vop_chown(tp, ip, &ip->i_udquot, udqp); } - inode->i_uid = uid; } if (!gid_eq(igid, gid)) { if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) { @@ -772,15 +730,10 @@ xfs_setattr_nonsize( olddquot2 = xfs_qm_vop_chown(tp, ip, &ip->i_gdquot, gdqp); } - inode->i_gid = gid; } } - if (mask & ATTR_MODE) - xfs_setattr_mode(ip, iattr); - if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) - xfs_setattr_time(ip, iattr); - + setattr_copy(inode, iattr); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); XFS_STATS_INC(mp, xs_ig_attrchg); @@ -1025,11 +978,8 @@ xfs_setattr_size( xfs_inode_clear_eofblocks_tag(ip); } - if (iattr->ia_valid & ATTR_MODE) - xfs_setattr_mode(ip, iattr); - if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) - xfs_setattr_time(ip, iattr); - + ASSERT(!(iattr->ia_valid & (ATTR_UID | ATTR_GID))); + setattr_copy(inode, iattr); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); XFS_STATS_INC(mp, xs_ig_attrchg); diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index 64ab54f2fe81..053b99929f83 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c @@ -285,7 +285,8 @@ xfs_fs_commit_blocks( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - xfs_setattr_time(ip, iattr); + ASSERT(!(iattr->ia_valid & (ATTR_UID | ATTR_GID))); + setattr_copy(inode, iattr); if (update_isize) { i_size_write(inode, iattr->ia_size); ip->i_d.di_size = iattr->ia_size; From 347750e1b69cef62966fbc5bd7dc579b4c00688a Mon Sep 17 00:00:00 2001 From: Yang Xu Date: Sat, 18 Mar 2023 12:15:22 +0200 Subject: [PATCH 0827/1017] fs: add mode_strip_sgid() helper commit 2b3416ceff5e6bd4922f6d1c61fb68113dd82302 upstream. [remove userns argument of helper for 5.10.y backport] Add a dedicated helper to handle the setgid bit when creating a new file in a setgid directory. This is a preparatory patch for moving setgid stripping into the vfs. The patch contains no functional changes. Currently the setgid stripping logic is open-coded directly in inode_init_owner() and the individual filesystems are responsible for handling setgid inheritance. Since this has proven to be brittle as evidenced by old issues we uncovered over the last months (see [1] to [3] below) we will try to move this logic into the vfs. Link: e014f37db1a2 ("xfs: use setattr_copy to set vfs inode attributes") [1] Link: 01ea173e103e ("xfs: fix up non-directory creation in SGID directories") [2] Link: fd84bfdddd16 ("ceph: fix up non-directory creation in SGID directories") [3] Link: https://lore.kernel.org/r/1657779088-2242-1-git-send-email-xuyang2018.jy@fujitsu.com Reviewed-by: Darrick J. Wong Reviewed-by: Christian Brauner (Microsoft) Reviewed-and-Tested-by: Jeff Layton Signed-off-by: Yang Xu Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/inode.c | 34 ++++++++++++++++++++++++++++++---- include/linux/fs.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 9f49e0bdc2f7..23d03abcb0ff 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -2147,10 +2147,8 @@ void inode_init_owner(struct inode *inode, const struct inode *dir, /* Directories are special, and always inherit S_ISGID */ if (S_ISDIR(mode)) mode |= S_ISGID; - else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) && - !in_group_p(inode->i_gid) && - !capable_wrt_inode_uidgid(dir, CAP_FSETID)) - mode &= ~S_ISGID; + else + mode = mode_strip_sgid(dir, mode); } else inode->i_gid = current_fsgid(); inode->i_mode = mode; @@ -2382,3 +2380,31 @@ int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa, return 0; } EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); + +/** + * mode_strip_sgid - handle the sgid bit for non-directories + * @dir: parent directory inode + * @mode: mode of the file to be created in @dir + * + * If the @mode of the new file has both the S_ISGID and S_IXGRP bit + * raised and @dir has the S_ISGID bit raised ensure that the caller is + * either in the group of the parent directory or they have CAP_FSETID + * in their user namespace and are privileged over the parent directory. + * In all other cases, strip the S_ISGID bit from @mode. + * + * Return: the new mode to use for the file + */ +umode_t mode_strip_sgid(const struct inode *dir, umode_t mode) +{ + if ((mode & (S_ISGID | S_IXGRP)) != (S_ISGID | S_IXGRP)) + return mode; + if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID)) + return mode; + if (in_group_p(dir->i_gid)) + return mode; + if (capable_wrt_inode_uidgid(dir, CAP_FSETID)) + return mode; + + return mode & ~S_ISGID; +} +EXPORT_SYMBOL(mode_strip_sgid); diff --git a/include/linux/fs.h b/include/linux/fs.h index 74e19bccbf73..527791e4860b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1768,6 +1768,7 @@ extern long compat_ptr_ioctl(struct file *file, unsigned int cmd, extern void inode_init_owner(struct inode *inode, const struct inode *dir, umode_t mode); extern bool may_open_dev(const struct path *path); +umode_t mode_strip_sgid(const struct inode *dir, umode_t mode); /* * This is the "filldir" function type, used by readdir() to let From 94ac142c19f1016283a1860b07de7fa555385d31 Mon Sep 17 00:00:00 2001 From: Yang Xu Date: Sat, 18 Mar 2023 12:15:23 +0200 Subject: [PATCH 0828/1017] fs: move S_ISGID stripping into the vfs_*() helpers commit 1639a49ccdce58ea248841ed9b23babcce6dbb0b upstream. [remove userns argument of helpers for 5.10.y backport] Move setgid handling out of individual filesystems and into the VFS itself to stop the proliferation of setgid inheritance bugs. Creating files that have both the S_IXGRP and S_ISGID bit raised in directories that themselves have the S_ISGID bit set requires additional privileges to avoid security issues. When a filesystem creates a new inode it needs to take care that the caller is either in the group of the newly created inode or they have CAP_FSETID in their current user namespace and are privileged over the parent directory of the new inode. If any of these two conditions is true then the S_ISGID bit can be raised for an S_IXGRP file and if not it needs to be stripped. However, there are several key issues with the current implementation: * S_ISGID stripping logic is entangled with umask stripping. If a filesystem doesn't support or enable POSIX ACLs then umask stripping is done directly in the vfs before calling into the filesystem. If the filesystem does support POSIX ACLs then unmask stripping may be done in the filesystem itself when calling posix_acl_create(). Since umask stripping has an effect on S_ISGID inheritance, e.g., by stripping the S_IXGRP bit from the file to be created and all relevant filesystems have to call posix_acl_create() before inode_init_owner() where we currently take care of S_ISGID handling S_ISGID handling is order dependent. IOW, whether or not you get a setgid bit depends on POSIX ACLs and umask and in what order they are called. Note that technically filesystems are free to impose their own ordering between posix_acl_create() and inode_init_owner() meaning that there's additional ordering issues that influence S_SIGID inheritance. * Filesystems that don't rely on inode_init_owner() don't get S_ISGID stripping logic. While that may be intentional (e.g. network filesystems might just defer setgid stripping to a server) it is often just a security issue. This is not just ugly it's unsustainably messy especially since we do still have bugs in this area years after the initial round of setgid bugfixes. So the current state is quite messy and while we won't be able to make it completely clean as posix_acl_create() is still a filesystem specific call we can improve the S_SIGD stripping situation quite a bit by hoisting it out of inode_init_owner() and into the vfs creation operations. This means we alleviate the burden for filesystems to handle S_ISGID stripping correctly and can standardize the ordering between S_ISGID and umask stripping in the vfs. We add a new helper vfs_prepare_mode() so S_ISGID handling is now done in the VFS before umask handling. This has S_ISGID handling is unaffected unaffected by whether umask stripping is done by the VFS itself (if no POSIX ACLs are supported or enabled) or in the filesystem in posix_acl_create() (if POSIX ACLs are supported). The vfs_prepare_mode() helper is called directly in vfs_*() helpers that create new filesystem objects. We need to move them into there to make sure that filesystems like overlayfs hat have callchains like: sys_mknod() -> do_mknodat(mode) -> .mknod = ovl_mknod(mode) -> ovl_create(mode) -> vfs_mknod(mode) get S_ISGID stripping done when calling into lower filesystems via vfs_*() creation helpers. Moving vfs_prepare_mode() into e.g. vfs_mknod() takes care of that. This is in any case semantically cleaner because S_ISGID stripping is VFS security requirement. Security hooks so far have seen the mode with the umask applied but without S_ISGID handling done. The relevant hooks are called outside of vfs_*() creation helpers so by calling vfs_prepare_mode() from vfs_*() helpers the security hooks would now see the mode without umask stripping applied. For now we fix this by passing the mode with umask settings applied to not risk any regressions for LSM hooks. IOW, nothing changes for LSM hooks. It is worth pointing out that security hooks never saw the mode that is seen by the filesystem when actually creating the file. They have always been completely misplaced for that to work. The following filesystems use inode_init_owner() and thus relied on S_ISGID stripping: spufs, 9p, bfs, btrfs, ext2, ext4, f2fs, hfsplus, hugetlbfs, jfs, minix, nilfs2, ntfs3, ocfs2, omfs, overlayfs, ramfs, reiserfs, sysv, ubifs, udf, ufs, xfs, zonefs, bpf, tmpfs. All of the above filesystems end up calling inode_init_owner() when new filesystem objects are created through the ->mkdir(), ->mknod(), ->create(), ->tmpfile(), ->rename() inode operations. Since directories always inherit the S_ISGID bit with the exception of xfs when irix_sgid_inherit mode is turned on S_ISGID stripping doesn't apply. The ->symlink() and ->link() inode operations trivially inherit the mode from the target and the ->rename() inode operation inherits the mode from the source inode. All other creation inode operations will get S_ISGID handling via vfs_prepare_mode() when called from their relevant vfs_*() helpers. In addition to this there are filesystems which allow the creation of filesystem objects through ioctl()s or - in the case of spufs - circumventing the vfs in other ways. If filesystem objects are created through ioctl()s the vfs doesn't know about it and can't apply regular permission checking including S_ISGID logic. Therfore, a filesystem relying on S_ISGID stripping in inode_init_owner() in their ioctl() callpath will be affected by moving this logic into the vfs. We audited those filesystems: * btrfs allows the creation of filesystem objects through various ioctls(). Snapshot creation literally takes a snapshot and so the mode is fully preserved and S_ISGID stripping doesn't apply. Creating a new subvolum relies on inode_init_owner() in btrfs_new_subvol_inode() but only creates directories and doesn't raise S_ISGID. * ocfs2 has a peculiar implementation of reflinks. In contrast to e.g. xfs and btrfs FICLONE/FICLONERANGE ioctl() that is only concerned with the actual extents ocfs2 uses a separate ioctl() that also creates the target file. Iow, ocfs2 circumvents the vfs entirely here and did indeed rely on inode_init_owner() to strip the S_ISGID bit. This is the only place where a filesystem needs to call mode_strip_sgid() directly but this is self-inflicted pain. * spufs doesn't go through the vfs at all and doesn't use ioctl()s either. Instead it has a dedicated system call spufs_create() which allows the creation of filesystem objects. But spufs only creates directories and doesn't allo S_SIGID bits, i.e. it specifically only allows 0777 bits. * bpf uses vfs_mkobj() but also doesn't allow S_ISGID bits to be created. The patch will have an effect on ext2 when the EXT2_MOUNT_GRPID mount option is used, on ext4 when the EXT4_MOUNT_GRPID mount option is used, and on xfs when the XFS_FEAT_GRPID mount option is used. When any of these filesystems are mounted with their respective GRPID option then newly created files inherit the parent directories group unconditionally. In these cases non of the filesystems call inode_init_owner() and thus did never strip the S_ISGID bit for newly created files. Moving this logic into the VFS means that they now get the S_ISGID bit stripped. This is a user visible change. If this leads to regressions we will either need to figure out a better way or we need to revert. However, given the various setgid bugs that we found just in the last two years this is a regression risk we should take. Associated with this change is a new set of fstests to enforce the semantics for all new filesystems. Link: https://lore.kernel.org/ceph-devel/20220427092201.wvsdjbnc7b4dttaw@wittgenstein [1] Link: e014f37db1a2 ("xfs: use setattr_copy to set vfs inode attributes") [2] Link: 01ea173e103e ("xfs: fix up non-directory creation in SGID directories") [3] Link: fd84bfdddd16 ("ceph: fix up non-directory creation in SGID directories") [4] Link: https://lore.kernel.org/r/1657779088-2242-3-git-send-email-xuyang2018.jy@fujitsu.com Suggested-by: Dave Chinner Suggested-by: Christian Brauner (Microsoft) Reviewed-by: Darrick J. Wong Reviewed-and-Tested-by: Jeff Layton Signed-off-by: Yang Xu [: rewrote commit message] Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/inode.c | 2 -- fs/namei.c | 80 ++++++++++++++++++++++++++++++++++++++++-------- fs/ocfs2/namei.c | 1 + 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 23d03abcb0ff..52f834b6a3ad 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -2147,8 +2147,6 @@ void inode_init_owner(struct inode *inode, const struct inode *dir, /* Directories are special, and always inherit S_ISGID */ if (S_ISDIR(mode)) mode |= S_ISGID; - else - mode = mode_strip_sgid(dir, mode); } else inode->i_gid = current_fsgid(); inode->i_mode = mode; diff --git a/fs/namei.c b/fs/namei.c index 4159c140fa47..3d98db9802a7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,6 +2798,63 @@ void unlock_rename(struct dentry *p1, struct dentry *p2) } EXPORT_SYMBOL(unlock_rename); +/** + * mode_strip_umask - handle vfs umask stripping + * @dir: parent directory of the new inode + * @mode: mode of the new inode to be created in @dir + * + * Umask stripping depends on whether or not the filesystem supports POSIX + * ACLs. If the filesystem doesn't support it umask stripping is done directly + * in here. If the filesystem does support POSIX ACLs umask stripping is + * deferred until the filesystem calls posix_acl_create(). + * + * Returns: mode + */ +static inline umode_t mode_strip_umask(const struct inode *dir, umode_t mode) +{ + if (!IS_POSIXACL(dir)) + mode &= ~current_umask(); + return mode; +} + +/** + * vfs_prepare_mode - prepare the mode to be used for a new inode + * @dir: parent directory of the new inode + * @mode: mode of the new inode + * @mask_perms: allowed permission by the vfs + * @type: type of file to be created + * + * This helper consolidates and enforces vfs restrictions on the @mode of a new + * object to be created. + * + * Umask stripping depends on whether the filesystem supports POSIX ACLs (see + * the kernel documentation for mode_strip_umask()). Moving umask stripping + * after setgid stripping allows the same ordering for both non-POSIX ACL and + * POSIX ACL supporting filesystems. + * + * Note that it's currently valid for @type to be 0 if a directory is created. + * Filesystems raise that flag individually and we need to check whether each + * filesystem can deal with receiving S_IFDIR from the vfs before we enforce a + * non-zero type. + * + * Returns: mode to be passed to the filesystem + */ +static inline umode_t vfs_prepare_mode(const struct inode *dir, umode_t mode, + umode_t mask_perms, umode_t type) +{ + mode = mode_strip_sgid(dir, mode); + mode = mode_strip_umask(dir, mode); + + /* + * Apply the vfs mandated allowed permission mask and set the type of + * file to be created before we call into the filesystem. + */ + mode &= (mask_perms & ~S_IFMT); + mode |= (type & S_IFMT); + + return mode; +} + int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { @@ -2807,8 +2864,8 @@ int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, if (!dir->i_op->create) return -EACCES; /* shouldn't it be ENOSYS? */ - mode &= S_IALLUGO; - mode |= S_IFREG; + + mode = vfs_prepare_mode(dir, mode, S_IALLUGO, S_IFREG); error = security_inode_create(dir, dentry, mode); if (error) return error; @@ -3072,8 +3129,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file, if (open_flag & O_CREAT) { if (open_flag & O_EXCL) open_flag &= ~O_TRUNC; - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current_umask(); + mode = vfs_prepare_mode(dir->d_inode, mode, mode, mode); if (likely(got_write)) create_error = may_o_create(&nd->path, dentry, mode); else @@ -3286,8 +3342,7 @@ struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) child = d_alloc(dentry, &slash_name); if (unlikely(!child)) goto out_err; - if (!IS_POSIXACL(dir)) - mode &= ~current_umask(); + mode = vfs_prepare_mode(dir, mode, mode, mode); error = dir->i_op->tmpfile(dir, child, mode); if (error) goto out_err; @@ -3548,6 +3603,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) if (!dir->i_op->mknod) return -EPERM; + mode = vfs_prepare_mode(dir, mode, mode, mode); error = devcgroup_inode_mknod(mode, dev); if (error) return error; @@ -3596,9 +3652,8 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) - mode &= ~current_umask(); - error = security_path_mknod(&path, dentry, mode, dev); + error = security_path_mknod(&path, dentry, + mode_strip_umask(path.dentry->d_inode, mode), dev); if (error) goto out; switch (mode & S_IFMT) { @@ -3646,7 +3701,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (!dir->i_op->mkdir) return -EPERM; - mode &= (S_IRWXUGO|S_ISVTX); + mode = vfs_prepare_mode(dir, mode, S_IRWXUGO | S_ISVTX, 0); error = security_inode_mkdir(dir, dentry, mode); if (error) return error; @@ -3673,9 +3728,8 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) - mode &= ~current_umask(); - error = security_path_mkdir(&path, dentry, mode); + error = security_path_mkdir(&path, dentry, + mode_strip_umask(path.dentry->d_inode, mode)); if (!error) error = vfs_mkdir(path.dentry->d_inode, dentry, mode); done_path_create(&path, dentry); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 856474b0a1ae..df1f6b7aa797 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -198,6 +198,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode) * callers. */ if (S_ISDIR(mode)) set_nlink(inode, 2); + mode = mode_strip_sgid(dir, mode); inode_init_owner(inode, dir, mode); status = dquot_initialize(inode); if (status) From 24378d6f748649060f4d0c3eea8a1efe5bccfd1d Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sat, 18 Mar 2023 12:15:24 +0200 Subject: [PATCH 0829/1017] attr: add in_group_or_capable() commit 11c2a8700cdcabf9b639b7204a1e38e2a0b6798e upstream. [backported to 5.10.y, prior to idmapped mounts] In setattr_{copy,prepare}() we need to perform the same permission checks to determine whether we need to drop the setgid bit or not. Instead of open-coding it twice add a simple helper the encapsulates the logic. We will reuse this helpers to make dropping the setgid bit during write operations more consistent in a follow up patch. Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/attr.c | 11 +++++------ fs/inode.c | 25 +++++++++++++++++++++---- fs/internal.h | 1 + 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 848ffe6e3c24..300ba5153868 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -18,6 +18,8 @@ #include #include +#include "internal.h" + static bool chown_ok(const struct inode *inode, kuid_t uid) { if (uid_eq(current_fsuid(), inode->i_uid) && @@ -90,9 +92,8 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr) if (!inode_owner_or_capable(inode)) return -EPERM; /* Also check the setgid bit! */ - if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : - inode->i_gid) && - !capable_wrt_inode_uidgid(inode, CAP_FSETID)) + if (!in_group_or_capable(inode, (ia_valid & ATTR_GID) ? + attr->ia_gid : inode->i_gid)) attr->ia_mode &= ~S_ISGID; } @@ -193,9 +194,7 @@ void setattr_copy(struct inode *inode, const struct iattr *attr) inode->i_ctime = attr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; - - if (!in_group_p(inode->i_gid) && - !capable_wrt_inode_uidgid(inode, CAP_FSETID)) + if (!in_group_or_capable(inode, inode->i_gid)) mode &= ~S_ISGID; inode->i_mode = mode; } diff --git a/fs/inode.c b/fs/inode.c index 52f834b6a3ad..63f86aeda7fd 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -2379,6 +2379,26 @@ int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa, } EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); +/** + * in_group_or_capable - check whether caller is CAP_FSETID privileged + * @inode: inode to check + * @gid: the new/current gid of @inode + * + * Check wether @gid is in the caller's group list or if the caller is + * privileged with CAP_FSETID over @inode. This can be used to determine + * whether the setgid bit can be kept or must be dropped. + * + * Return: true if the caller is sufficiently privileged, false if not. + */ +bool in_group_or_capable(const struct inode *inode, kgid_t gid) +{ + if (in_group_p(gid)) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_FSETID)) + return true; + return false; +} + /** * mode_strip_sgid - handle the sgid bit for non-directories * @dir: parent directory inode @@ -2398,11 +2418,8 @@ umode_t mode_strip_sgid(const struct inode *dir, umode_t mode) return mode; if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID)) return mode; - if (in_group_p(dir->i_gid)) + if (in_group_or_capable(dir, dir->i_gid)) return mode; - if (capable_wrt_inode_uidgid(dir, CAP_FSETID)) - return mode; - return mode & ~S_ISGID; } EXPORT_SYMBOL(mode_strip_sgid); diff --git a/fs/internal.h b/fs/internal.h index 06d313b9beec..0fe920d9f393 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -149,6 +149,7 @@ extern int vfs_open(const struct path *, struct file *); extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc); extern void inode_add_lru(struct inode *inode); extern int dentry_needs_remove_privs(struct dentry *dentry); +bool in_group_or_capable(const struct inode *inode, kgid_t gid); /* * fs-writeback.c From baea3ae425fb3d65a3aef15e58724e717a746a0b Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sat, 18 Mar 2023 12:15:25 +0200 Subject: [PATCH 0830/1017] fs: move should_remove_suid() commit e243e3f94c804ecca9a8241b5babe28f35258ef4 upstream. Move the helper from inode.c to attr.c. This keeps the the core of the set{g,u}id stripping logic in one place when we add follow-up changes. It is the better place anyway, since should_remove_suid() returns ATTR_KILL_S{G,U}ID flags. Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/attr.c | 29 +++++++++++++++++++++++++++++ fs/inode.c | 29 ----------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 300ba5153868..666489157978 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -20,6 +20,35 @@ #include "internal.h" +/* + * The logic we want is + * + * if suid or (sgid and xgrp) + * remove privs + */ +int should_remove_suid(struct dentry *dentry) +{ + umode_t mode = d_inode(dentry)->i_mode; + int kill = 0; + + /* suid always must be killed */ + if (unlikely(mode & S_ISUID)) + kill = ATTR_KILL_SUID; + + /* + * sgid without any exec bits is just a mandatory locking mark; leave + * it alone. If some exec bits are set, it's a real sgid; kill it. + */ + if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) + kill |= ATTR_KILL_SGID; + + if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode))) + return kill; + + return 0; +} +EXPORT_SYMBOL(should_remove_suid); + static bool chown_ok(const struct inode *inode, kuid_t uid) { if (uid_eq(current_fsuid(), inode->i_uid) && diff --git a/fs/inode.c b/fs/inode.c index 63f86aeda7fd..f52dd6feea98 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1854,35 +1854,6 @@ skip_update: } EXPORT_SYMBOL(touch_atime); -/* - * The logic we want is - * - * if suid or (sgid and xgrp) - * remove privs - */ -int should_remove_suid(struct dentry *dentry) -{ - umode_t mode = d_inode(dentry)->i_mode; - int kill = 0; - - /* suid always must be killed */ - if (unlikely(mode & S_ISUID)) - kill = ATTR_KILL_SUID; - - /* - * sgid without any exec bits is just a mandatory locking mark; leave - * it alone. If some exec bits are set, it's a real sgid; kill it. - */ - if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) - kill |= ATTR_KILL_SGID; - - if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode))) - return kill; - - return 0; -} -EXPORT_SYMBOL(should_remove_suid); - /* * Return mask of changes for notify_change() that need to be done as a * response to write or truncate. Return 0 if nothing has to be changed. From 240b96ffece8fc959c1b7d8647b178503a51255b Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sat, 18 Mar 2023 12:15:26 +0200 Subject: [PATCH 0831/1017] attr: add setattr_should_drop_sgid() commit 72ae017c5451860443a16fb2a8c243bff3e396b8 upstream. [backported to 5.10.y, prior to idmapped mounts] The current setgid stripping logic during write and ownership change operations is inconsistent and strewn over multiple places. In order to consolidate it and make more consistent we'll add a new helper setattr_should_drop_sgid(). The function retains the old behavior where we remove the S_ISGID bit unconditionally when S_IXGRP is set but also when it isn't set and the caller is neither in the group of the inode nor privileged over the inode. We will use this helper both in write operation permission removal such as file_remove_privs() as well as in ownership change operations. Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/attr.c | 25 +++++++++++++++++++++++++ fs/internal.h | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/fs/attr.c b/fs/attr.c index 666489157978..c8049ae34a2e 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -20,6 +20,31 @@ #include "internal.h" +/** + * setattr_should_drop_sgid - determine whether the setgid bit needs to be + * removed + * @inode: inode to check + * + * This function determines whether the setgid bit needs to be removed. + * We retain backwards compatibility and require setgid bit to be removed + * unconditionally if S_IXGRP is set. Otherwise we have the exact same + * requirements as setattr_prepare() and setattr_copy(). + * + * Return: ATTR_KILL_SGID if setgid bit needs to be removed, 0 otherwise. + */ +int setattr_should_drop_sgid(const struct inode *inode) +{ + umode_t mode = inode->i_mode; + + if (!(mode & S_ISGID)) + return 0; + if (mode & S_IXGRP) + return ATTR_KILL_SGID; + if (!in_group_or_capable(inode, inode->i_gid)) + return ATTR_KILL_SGID; + return 0; +} + /* * The logic we want is * diff --git a/fs/internal.h b/fs/internal.h index 0fe920d9f393..d5d9fcdae10c 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -197,3 +197,8 @@ int sb_init_dio_done_wq(struct super_block *sb); */ int do_statx(int dfd, const char __user *filename, unsigned flags, unsigned int mask, struct statx __user *buffer); + +/* + * fs/attr.c + */ +int setattr_should_drop_sgid(const struct inode *inode); From 0e9dbde96cacd0e95e05e862b50f3079146917f2 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sat, 18 Mar 2023 12:15:27 +0200 Subject: [PATCH 0832/1017] attr: use consistent sgid stripping checks commit ed5a7047d2011cb6b2bf84ceb6680124cc6a7d95 upstream. [backported to 5.10.y, prior to idmapped mounts] Currently setgid stripping in file_remove_privs()'s should_remove_suid() helper is inconsistent with other parts of the vfs. Specifically, it only raises ATTR_KILL_SGID if the inode is S_ISGID and S_IXGRP but not if the inode isn't in the caller's groups and the caller isn't privileged over the inode although we require this already in setattr_prepare() and setattr_copy() and so all filesystem implement this requirement implicitly because they have to use setattr_{prepare,copy}() anyway. But the inconsistency shows up in setgid stripping bugs for overlayfs in xfstests (e.g., generic/673, generic/683, generic/685, generic/686, generic/687). For example, we test whether suid and setgid stripping works correctly when performing various write-like operations as an unprivileged user (fallocate, reflink, write, etc.): echo "Test 1 - qa_user, non-exec file $verb" setup_testfile chmod a+rws $junk_file commit_and_check "$qa_user" "$verb" 64k 64k The test basically creates a file with 6666 permissions. While the file has the S_ISUID and S_ISGID bits set it does not have the S_IXGRP set. On a regular filesystem like xfs what will happen is: sys_fallocate() -> vfs_fallocate() -> xfs_file_fallocate() -> file_modified() -> __file_remove_privs() -> dentry_needs_remove_privs() -> should_remove_suid() -> __remove_privs() newattrs.ia_valid = ATTR_FORCE | kill; -> notify_change() -> setattr_copy() In should_remove_suid() we can see that ATTR_KILL_SUID is raised unconditionally because the file in the test has S_ISUID set. But we also see that ATTR_KILL_SGID won't be set because while the file is S_ISGID it is not S_IXGRP (see above) which is a condition for ATTR_KILL_SGID being raised. So by the time we call notify_change() we have attr->ia_valid set to ATTR_KILL_SUID | ATTR_FORCE. Now notify_change() sees that ATTR_KILL_SUID is set and does: ia_valid = attr->ia_valid |= ATTR_MODE attr->ia_mode = (inode->i_mode & ~S_ISUID); which means that when we call setattr_copy() later we will definitely update inode->i_mode. Note that attr->ia_mode still contains S_ISGID. Now we call into the filesystem's ->setattr() inode operation which will end up calling setattr_copy(). Since ATTR_MODE is set we will hit: if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode); if (!vfsgid_in_group_p(vfsgid) && !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID)) mode &= ~S_ISGID; inode->i_mode = mode; } and since the caller in the test is neither capable nor in the group of the inode the S_ISGID bit is stripped. But assume the file isn't suid then ATTR_KILL_SUID won't be raised which has the consequence that neither the setgid nor the suid bits are stripped even though it should be stripped because the inode isn't in the caller's groups and the caller isn't privileged over the inode. If overlayfs is in the mix things become a bit more complicated and the bug shows up more clearly. When e.g., ovl_setattr() is hit from ovl_fallocate()'s call to file_remove_privs() then ATTR_KILL_SUID and ATTR_KILL_SGID might be raised but because the check in notify_change() is questioning the ATTR_KILL_SGID flag again by requiring S_IXGRP for it to be stripped the S_ISGID bit isn't removed even though it should be stripped: sys_fallocate() -> vfs_fallocate() -> ovl_fallocate() -> file_remove_privs() -> dentry_needs_remove_privs() -> should_remove_suid() -> __remove_privs() newattrs.ia_valid = ATTR_FORCE | kill; -> notify_change() -> ovl_setattr() // TAKE ON MOUNTER'S CREDS -> ovl_do_notify_change() -> notify_change() // GIVE UP MOUNTER'S CREDS // TAKE ON MOUNTER'S CREDS -> vfs_fallocate() -> xfs_file_fallocate() -> file_modified() -> __file_remove_privs() -> dentry_needs_remove_privs() -> should_remove_suid() -> __remove_privs() newattrs.ia_valid = attr_force | kill; -> notify_change() The fix for all of this is to make file_remove_privs()'s should_remove_suid() helper to perform the same checks as we already require in setattr_prepare() and setattr_copy() and have notify_change() not pointlessly requiring S_IXGRP again. It doesn't make any sense in the first place because the caller must calculate the flags via should_remove_suid() anyway which would raise ATTR_KILL_SGID. While we're at it we move should_remove_suid() from inode.c to attr.c where it belongs with the rest of the iattr helpers. Especially since it returns ATTR_KILL_S{G,U}ID flags. We also rename it to setattr_should_drop_suidgid() to better reflect that it indicates both setuid and setgid bit removal and also that it returns attr flags. Running xfstests with this doesn't report any regressions. We should really try and use consistent checks. Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- Documentation/trace/ftrace.rst | 2 +- fs/attr.c | 31 +++++++++++++++++-------------- fs/inode.c | 2 +- fs/ocfs2/file.c | 4 ++-- fs/open.c | 6 +++--- include/linux/fs.h | 2 +- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst index 87cf5c010d5d..ed2e45f9b762 100644 --- a/Documentation/trace/ftrace.rst +++ b/Documentation/trace/ftrace.rst @@ -2923,7 +2923,7 @@ Produces:: bash-1994 [000] .... 4342.324898: ima_get_action <-process_measurement bash-1994 [000] .... 4342.324898: ima_match_policy <-ima_get_action bash-1994 [000] .... 4342.324899: do_truncate <-do_last - bash-1994 [000] .... 4342.324899: should_remove_suid <-do_truncate + bash-1994 [000] .... 4342.324899: setattr_should_drop_suidgid <-do_truncate bash-1994 [000] .... 4342.324899: notify_change <-do_truncate bash-1994 [000] .... 4342.324900: current_fs_time <-notify_change bash-1994 [000] .... 4342.324900: current_kernel_time <-current_fs_time diff --git a/fs/attr.c b/fs/attr.c index c8049ae34a2e..326a0db3296d 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -45,34 +45,37 @@ int setattr_should_drop_sgid(const struct inode *inode) return 0; } -/* - * The logic we want is +/** + * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to + * be dropped + * @inode: inode to check * - * if suid or (sgid and xgrp) - * remove privs + * This function determines whether the set{g,u}id bits need to be removed. + * If the setuid bit needs to be removed ATTR_KILL_SUID is returned. If the + * setgid bit needs to be removed ATTR_KILL_SGID is returned. If both + * set{g,u}id bits need to be removed the corresponding mask of both flags is + * returned. + * + * Return: A mask of ATTR_KILL_S{G,U}ID indicating which - if any - setid bits + * to remove, 0 otherwise. */ -int should_remove_suid(struct dentry *dentry) +int setattr_should_drop_suidgid(struct inode *inode) { - umode_t mode = d_inode(dentry)->i_mode; + umode_t mode = inode->i_mode; int kill = 0; /* suid always must be killed */ if (unlikely(mode & S_ISUID)) kill = ATTR_KILL_SUID; - /* - * sgid without any exec bits is just a mandatory locking mark; leave - * it alone. If some exec bits are set, it's a real sgid; kill it. - */ - if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) - kill |= ATTR_KILL_SGID; + kill |= setattr_should_drop_sgid(inode); if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode))) return kill; return 0; } -EXPORT_SYMBOL(should_remove_suid); +EXPORT_SYMBOL(setattr_should_drop_suidgid); static bool chown_ok(const struct inode *inode, kuid_t uid) { @@ -350,7 +353,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de } } if (ia_valid & ATTR_KILL_SGID) { - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { + if (mode & S_ISGID) { if (!(ia_valid & ATTR_MODE)) { ia_valid = attr->ia_valid |= ATTR_MODE; attr->ia_mode = inode->i_mode; diff --git a/fs/inode.c b/fs/inode.c index f52dd6feea98..7ec90788d8be 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1868,7 +1868,7 @@ int dentry_needs_remove_privs(struct dentry *dentry) if (IS_NOSEC(inode)) return 0; - mask = should_remove_suid(dentry); + mask = setattr_should_drop_suidgid(inode); ret = security_inode_need_killpriv(dentry); if (ret < 0) return ret; diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 1470b49adb2d..ca00cac5a12f 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1994,7 +1994,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, } } - if (file && should_remove_suid(file->f_path.dentry)) { + if (file && setattr_should_drop_suidgid(file_inode(file))) { ret = __ocfs2_write_remove_suid(inode, di_bh); if (ret) { mlog_errno(ret); @@ -2282,7 +2282,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file, * inode. There's also the dinode i_size state which * can be lost via setattr during extending writes (we * set inode->i_size at the end of a write. */ - if (should_remove_suid(dentry)) { + if (setattr_should_drop_suidgid(inode)) { if (meta_level == 0) { ocfs2_inode_unlock_for_extent_tree(inode, &di_bh, diff --git a/fs/open.c b/fs/open.c index b3fbb4300fc9..1ca4b236fdbe 100644 --- a/fs/open.c +++ b/fs/open.c @@ -665,10 +665,10 @@ retry_deleg: newattrs.ia_valid |= ATTR_GID; newattrs.ia_gid = gid; } - if (!S_ISDIR(inode->i_mode)) - newattrs.ia_valid |= - ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; inode_lock(inode); + if (!S_ISDIR(inode->i_mode)) + newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV | + setattr_should_drop_sgid(inode); error = security_path_chown(path, uid, gid); if (!error) error = notify_change(path->dentry, &newattrs, &delegated_inode); diff --git a/include/linux/fs.h b/include/linux/fs.h index 527791e4860b..57afa4fa5e7b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2960,7 +2960,7 @@ extern void __destroy_inode(struct inode *); extern struct inode *new_inode_pseudo(struct super_block *sb); extern struct inode *new_inode(struct super_block *sb); extern void free_inode_nonrcu(struct inode *inode); -extern int should_remove_suid(struct dentry *); +extern int setattr_should_drop_suidgid(struct inode *); extern int file_remove_privs(struct file *); extern void __insert_inode_hash(struct inode *, unsigned long hashval); From 183ca919544c898dfbb40f6b26d33bfe8765a986 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sat, 18 Mar 2023 12:15:28 +0200 Subject: [PATCH 0833/1017] fs: use consistent setgid checks in is_sxid() commit 8d84e39d76bd83474b26cb44f4b338635676e7e8 upstream. Now that we made the VFS setgid checking consistent an inode can't be marked security irrelevant even if the setgid bit is still set. Make this function consistent with all other helpers. Note that enforcing consistent setgid stripping checks for file modification and mode- and ownership changes will cause the setgid bit to be lost in more cases than useed to be the case. If an unprivileged user wrote to a non-executable setgid file that they don't have privilege over the setgid bit will be dropped. This will lead to temporary failures in some xfstests until they have been updated. Reported-by: Miklos Szeredi Signed-off-by: Christian Brauner (Microsoft) Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index 57afa4fa5e7b..8ce9e5c61ede 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3408,7 +3408,7 @@ int __init get_filesystem_list(char *buf); static inline bool is_sxid(umode_t mode) { - return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP)); + return mode & (S_ISUID | S_ISGID); } static inline int check_sticky(struct inode *dir, struct inode *inode) From daa97e770e780b5e74d85afd236849359711a8d0 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Sat, 18 Mar 2023 12:15:29 +0200 Subject: [PATCH 0834/1017] xfs: remove xfs_setattr_time() declaration commit b0463b9dd7030a766133ad2f1571f97f204d7bdf upstream. xfs_setattr_time() has been removed since commit e014f37db1a2 ("xfs: use setattr_copy to set vfs inode attributes"), so remove it. Signed-off-by: Gaosheng Cui Reviewed-by: Carlos Maiolino Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_iops.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/xfs/xfs_iops.h b/fs/xfs/xfs_iops.h index 4d24ff309f59..dd1bd0332f8e 100644 --- a/fs/xfs/xfs_iops.h +++ b/fs/xfs/xfs_iops.h @@ -18,7 +18,6 @@ extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size); */ #define XFS_ATTR_NOACL 0x01 /* Don't call posix_acl_chmod */ -extern void xfs_setattr_time(struct xfs_inode *ip, struct iattr *iattr); extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, int flags); extern int xfs_vn_setattr_nonsize(struct dentry *dentry, struct iattr *vap); From 9bc878756b017f2e1d8dc4f261faa64f69c4c2ee Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 20 Mar 2023 13:06:31 +0000 Subject: [PATCH 0835/1017] HID: core: Provide new max_buffer_size attribute to over-ride the default commit b1a37ed00d7908a991c1d0f18a8cba3c2aa99bdc upstream. Presently, when a report is processed, its proposed size, provided by the user of the API (as Report Size * Report Count) is compared against the subsystem default HID_MAX_BUFFER_SIZE (16k). However, some low-level HID drivers allocate a reduced amount of memory to their buffers (e.g. UHID only allocates UHID_DATA_MAX (4k) buffers), rending this check inadequate in some cases. In these circumstances, if the received report ends up being smaller than the proposed report size, the remainder of the buffer is zeroed. That is, the space between sizeof(csize) (size of the current report) and the rsize (size proposed i.e. Report Size * Report Count), which can be handled up to HID_MAX_BUFFER_SIZE (16k). Meaning that memset() shoots straight past the end of the buffer boundary and starts zeroing out in-use values, often resulting in calamity. This patch introduces a new variable into 'struct hid_ll_driver' where individual low-level drivers can over-ride the default maximum value of HID_MAX_BUFFER_SIZE (16k) with something more sympathetic to the interface. Signed-off-by: Lee Jones Signed-off-by: Jiri Kosina [Lee: Backported to v5.10.y] Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 18 +++++++++++++----- include/linux/hid.h | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5f9ec1d1464a..524d6d712e72 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -258,6 +258,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign { struct hid_report *report; struct hid_field *field; + unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE; unsigned int usages; unsigned int offset; unsigned int i; @@ -288,8 +289,11 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign offset = report->size; report->size += parser->global.report_size * parser->global.report_count; + if (parser->device->ll_driver->max_buffer_size) + max_buffer_size = parser->device->ll_driver->max_buffer_size; + /* Total size check: Allow for possible report index byte */ - if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { + if (report->size > (max_buffer_size - 1) << 3) { hid_err(parser->device, "report is too long\n"); return -1; } @@ -1752,6 +1756,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; + int max_buffer_size = HID_MAX_BUFFER_SIZE; unsigned int a; u32 rsize, csize = size; u8 *cdata = data; @@ -1768,10 +1773,13 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, rsize = hid_compute_report_size(report); - if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) - rsize = HID_MAX_BUFFER_SIZE - 1; - else if (rsize > HID_MAX_BUFFER_SIZE) - rsize = HID_MAX_BUFFER_SIZE; + if (hid->ll_driver->max_buffer_size) + max_buffer_size = hid->ll_driver->max_buffer_size; + + if (report_enum->numbered && rsize >= max_buffer_size) + rsize = max_buffer_size - 1; + else if (rsize > max_buffer_size) + rsize = max_buffer_size; if (csize < rsize) { dbg_hid("report %d is too short, (%d < %d)\n", report->id, diff --git a/include/linux/hid.h b/include/linux/hid.h index 2ba33d708942..256f34f49167 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -798,6 +798,7 @@ struct hid_driver { * @raw_request: send raw report request to device (e.g. feature report) * @output_report: send output report to device * @idle: send idle request to device + * @max_buffer_size: over-ride maximum data buffer size (default: HID_MAX_BUFFER_SIZE) */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -822,6 +823,8 @@ struct hid_ll_driver { int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len); int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); + + unsigned int max_buffer_size; }; extern struct hid_ll_driver i2c_hid_ll_driver; From e57f797e3ffafb09eafb9be69d065d1e0331da61 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 20 Mar 2023 13:06:32 +0000 Subject: [PATCH 0836/1017] HID: uhid: Over-ride the default maximum data buffer value with our own commit 1c5d4221240a233df2440fe75c881465cdf8da07 upstream. The default maximum data buffer size for this interface is UHID_DATA_MAX (4k). When data buffers are being processed, ensure this value is used when ensuring the sanity, rather than a value between the user provided value and HID_MAX_BUFFER_SIZE (16k). Signed-off-by: Lee Jones Signed-off-by: Jiri Kosina Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/hid/uhid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index fc06d8bb42e0..ba0ca652b9da 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -395,6 +395,7 @@ struct hid_ll_driver uhid_hid_driver = { .parse = uhid_hid_parse, .raw_request = uhid_hid_raw_request, .output_report = uhid_hid_output_report, + .max_buffer_size = UHID_DATA_MAX, }; EXPORT_SYMBOL_GPL(uhid_hid_driver); From ca9787bdecfa2174b0a169a54916e22b89b0ef5b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 22 Mar 2023 13:30:08 +0100 Subject: [PATCH 0837/1017] Linux 5.10.176 Link: https://lore.kernel.org/r/20230320145443.333824603@linuxfoundation.org Tested-by: Chris Paterson (CIP) Tested-by: Florian Fainelli Tested-by: Linux Kernel Functional Testing Tested-by: Shuah Khan Tested-by: Jon Hunter Tested-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e6b09052f222..71caf5938361 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 175 +SUBLEVEL = 176 EXTRAVERSION = NAME = Dare mighty things From a880d7ebc53ec8595200175f860f35ef8755e91f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 13 Mar 2023 15:39:31 +0000 Subject: [PATCH 0838/1017] ANDROID: remove CONFIG_NET_CLS_TCINDEX from gki_defconfig The tcindex code was removed from the tree in 5.10.173, so remove the config option from the gki_defconfig files to fix up the build. Fixes: 18c3fa7a7fdb ("net/sched: Retire tcindex classifier") Change-Id: Id4927815ec2fd0ebc8065d891dfb721551f3dbc6 Signed-off-by: Greg Kroah-Hartman --- arch/arm64/configs/gki_defconfig | 1 - arch/x86/configs/gki_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 2ff6b13c9fe6..89281967589c 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -244,7 +244,6 @@ CONFIG_NET_SCH_FQ_CODEL=y CONFIG_NET_SCH_FQ=y CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_BASIC=y -CONFIG_NET_CLS_TCINDEX=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 8c486248e3dd..a317546d3098 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -220,7 +220,6 @@ CONFIG_NET_SCH_FQ_CODEL=y CONFIG_NET_SCH_FQ=y CONFIG_NET_SCH_INGRESS=y CONFIG_NET_CLS_BASIC=y -CONFIG_NET_CLS_TCINDEX=y CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_U32=y CONFIG_CLS_U32_MARK=y From 1aaaa18b4a4abab3b5643bee9093f9cc32d4e581 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Mar 2023 14:40:28 +0000 Subject: [PATCH 0839/1017] Revert "PCI: loongson: Add more devices that need MRRS quirk" This reverts commit faa050d2ff8820f450b69b84645e74b6934ed5ad which is commit c768f8c5f40fcdc6f058cc2f02592163d6c6716c upstream. It breaks the Android kernel abi and it not needed for any Android devices at this time. If it is needed, it can be brought back in an ABI-safe way. Bug: 161946584 Change-Id: I0d81c2395d7e4e42c81631040b40e936f2ccdf6a Signed-off-by: Greg Kroah-Hartman --- drivers/pci/controller/pci-loongson.c | 33 ++++++++------------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index e73e18a73833..dc7b4e4293ce 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -13,14 +13,9 @@ #include "../pci.h" /* Device IDs */ -#define DEV_LS2K_PCIE_PORT0 0x1a05 -#define DEV_LS7A_PCIE_PORT0 0x7a09 -#define DEV_LS7A_PCIE_PORT1 0x7a19 -#define DEV_LS7A_PCIE_PORT2 0x7a29 -#define DEV_LS7A_PCIE_PORT3 0x7a39 -#define DEV_LS7A_PCIE_PORT4 0x7a49 -#define DEV_LS7A_PCIE_PORT5 0x7a59 -#define DEV_LS7A_PCIE_PORT6 0x7a69 +#define DEV_PCIE_PORT_0 0x7a09 +#define DEV_PCIE_PORT_1 0x7a19 +#define DEV_PCIE_PORT_2 0x7a29 #define DEV_LS2K_APB 0x7a02 #define DEV_LS7A_CONF 0x7a10 @@ -43,11 +38,11 @@ static void bridge_class_quirk(struct pci_dev *dev) dev->class = PCI_CLASS_BRIDGE_PCI << 8; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT0, bridge_class_quirk); + DEV_PCIE_PORT_0, bridge_class_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT1, bridge_class_quirk); + DEV_PCIE_PORT_1, bridge_class_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT2, bridge_class_quirk); + DEV_PCIE_PORT_2, bridge_class_quirk); static void system_bus_quirk(struct pci_dev *pdev) { @@ -77,21 +72,11 @@ static void loongson_mrrs_quirk(struct pci_dev *pdev) bridge->no_inc_mrrs = 1; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS2K_PCIE_PORT0, loongson_mrrs_quirk); + DEV_PCIE_PORT_0, loongson_mrrs_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT0, loongson_mrrs_quirk); + DEV_PCIE_PORT_1, loongson_mrrs_quirk); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT1, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT2, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT3, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT4, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT5, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_LS7A_PCIE_PORT6, loongson_mrrs_quirk); + DEV_PCIE_PORT_2, loongson_mrrs_quirk); static void __iomem *cfg1_map(struct loongson_pci *priv, int bus, unsigned int devfn, int where) From 04d892b6169308165b25d962be72f85de26c039d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Mar 2023 14:40:41 +0000 Subject: [PATCH 0840/1017] Revert "PCI: loongson: Prevent LS7A MRRS increases" This reverts commit 654ae539254d10042869fdc77ad04c09e7eff1fd which is commit 8b3517f88ff2983f52698893519227c10aac90b2 upstream. It breaks the Android kernel abi and it not needed for any Android devices at this time. If it is needed, it can be brought back in an ABI-safe way. Bug: 161946584 Signed-off-by: Greg Kroah-Hartman Change-Id: I8543def5fb03133f4772ba1976f882d182bba677 --- drivers/pci/controller/pci-loongson.c | 42 ++++++++++++++++++--------- drivers/pci/pci.c | 10 ------- include/linux/pci.h | 1 - 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index dc7b4e4293ce..48169b1e3817 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -60,23 +60,37 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_LPC, system_bus_quirk); -static void loongson_mrrs_quirk(struct pci_dev *pdev) +static void loongson_mrrs_quirk(struct pci_dev *dev) { - /* - * Some Loongson PCIe ports have h/w limitations of maximum read - * request size. They can't handle anything larger than this. So - * force this limit on any devices attached under these ports. - */ - struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); + struct pci_bus *bus = dev->bus; + struct pci_dev *bridge; + static const struct pci_device_id bridge_devids[] = { + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_0) }, + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_1) }, + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_2) }, + { 0, }, + }; - bridge->no_inc_mrrs = 1; + /* look for the matching bridge */ + while (!pci_is_root_bus(bus)) { + bridge = bus->self; + bus = bus->parent; + /* + * Some Loongson PCIe ports have a h/w limitation of + * 256 bytes maximum read request size. They can't handle + * anything larger than this. So force this limit on + * any devices attached under these ports. + */ + if (pci_match_id(bridge_devids, bridge)) { + if (pcie_get_readrq(dev) > 256) { + pci_info(dev, "limiting MRRS to 256\n"); + pcie_set_readrq(dev, 256); + } + break; + } + } } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_0, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_1, loongson_mrrs_quirk); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, - DEV_PCIE_PORT_2, loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_mrrs_quirk); static void __iomem *cfg1_map(struct loongson_pci *priv, int bus, unsigned int devfn, int where) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8faf263f0d11..da01b31c29ef 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5746,7 +5746,6 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) { u16 v; int ret; - struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); if (rq < 128 || rq > 4096 || !is_power_of_2(rq)) return -EINVAL; @@ -5765,15 +5764,6 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) v = (ffs(rq) - 8) << 12; - if (bridge->no_inc_mrrs) { - int max_mrrs = pcie_get_readrq(dev); - - if (rq > max_mrrs) { - pci_info(dev, "can't set Max_Read_Request_Size to %d; max is %d\n", rq, max_mrrs); - return -EINVAL; - } - } - ret = pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_READRQ, v); diff --git a/include/linux/pci.h b/include/linux/pci.h index 62a7a1c25166..3abe5ddb5c03 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -545,7 +545,6 @@ struct pci_host_bridge { struct msi_controller *msi; unsigned int ignore_reset_delay:1; /* For entire hierarchy */ unsigned int no_ext_tags:1; /* No Extended Tags */ - unsigned int no_inc_mrrs:1; /* No Increase MRRS */ unsigned int native_aer:1; /* OS may use PCIe AER */ unsigned int native_pcie_hotplug:1; /* OS may use PCIe hotplug */ unsigned int native_shpc_hotplug:1; /* OS may use SHPC hotplug */ From 9b0fcb1986c55b90c8676bb175e3200d3c6b9806 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 22 Mar 2023 10:38:59 +0000 Subject: [PATCH 0841/1017] ANDROID: preserve CRC for __irq_domain_add() The __irq_domain_add() function changed in commit bb7597777c13 ("irqdomain: Change the type of 'size' in __irq_domain_add() to be consistent") in order to make later commits in the series able to be applied easier. The commit does not actually change any functionality, but the CRC is now changed, so trick the CRC tools to think all is still the same. function symbol changed from 'struct irq_domain * __irq_domain_add(struct fwnode_handle *, int, irq_hw_number_t, int, const struct irq_domain_ops *, void *)' to 'struct irq_domain * __irq_domain_add(struct fwnode_handle *, unsigned int, irq_hw_number_t, int, const struct irq_domain_ops *, void *)' type changed from 'struct irq_domain *(struct fwnode_handle *, int, irq_hw_number_t, int, const struct irq_domain_ops *, void *)' to 'struct irq_domain *(struct fwnode_handle *, unsigned int, irq_hw_number_t, int, const struct irq_domain_ops *, void *)' parameter 2 ('size') type changed from 'int' to 'unsigned int' encoding changed from signed integer to unsigned integer Bug: 161946584 Fixes: bb7597777c13 ("irqdomain: Change the type of 'size' in __irq_domain_add() to be consistent") Change-Id: I3065753600072c4ab4def2c3b1d6420e1946bdeb Signed-off-by: Greg Kroah-Hartman --- android/abi_gki_aarch64.xml | 2104 +++++++++++++++++------------------ include/linux/irqdomain.h | 4 + 2 files changed, 1056 insertions(+), 1052 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 291958b75232..5acd11e5aec7 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -7478,15 +7478,15 @@ - + - + - + - + @@ -22344,9 +22344,9 @@ - + - + @@ -25186,7 +25186,7 @@ - + @@ -35379,21 +35379,21 @@ - + - + - + - + - + - + @@ -38599,18 +38599,18 @@ - + - + - + - + - + @@ -43819,7 +43819,7 @@ - + @@ -48886,7 +48886,7 @@ - + @@ -67722,39 +67722,39 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -70490,7 +70490,7 @@ - + @@ -77728,9 +77728,9 @@ - + - + @@ -82189,30 +82189,30 @@ - + - + - + - + - + - + - + - + - + @@ -109974,7 +109974,7 @@ - + @@ -112428,120 +112428,120 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -115875,15 +115875,15 @@ - + - + - + - + @@ -116291,9 +116291,9 @@ - - - + + + @@ -116411,9 +116411,9 @@ - - - + + + @@ -116504,17 +116504,17 @@ - - - + + + - - + + - - + + @@ -116577,18 +116577,18 @@ - - + + - - - + + + - - - + + + @@ -116597,9 +116597,9 @@ - - - + + + @@ -116664,9 +116664,9 @@ - - - + + + @@ -116757,19 +116757,19 @@ - - - - - + + + + + - - - - - - + + + + + + @@ -116850,9 +116850,9 @@ - - - + + + @@ -116937,8 +116937,8 @@ - - + + @@ -117044,16 +117044,16 @@ - - - - + + + + - - - - + + + + @@ -117208,13 +117208,13 @@ - - - - - - - + + + + + + + @@ -117267,8 +117267,8 @@ - - + + @@ -117426,21 +117426,21 @@ - - + + - - + + - - - + + + @@ -117449,8 +117449,8 @@ - - + + @@ -117631,16 +117631,16 @@ - - - - - + + + + + - - - + + + @@ -117861,12 +117861,12 @@ - - + + - - + + @@ -117885,16 +117885,16 @@ - - - - + + + + - - - - + + + + @@ -121230,10 +121230,10 @@ - - - - + + + + @@ -121857,13 +121857,13 @@ - - - - - - - + + + + + + + @@ -121877,12 +121877,12 @@ - - - - - - + + + + + + @@ -122437,16 +122437,16 @@ - - + + - - + + - - + + @@ -122454,22 +122454,22 @@ - - - + + + - - - + + + - - + + - - + + @@ -122485,15 +122485,15 @@ - - + + - - - - - + + + + + @@ -122506,44 +122506,44 @@ - - + + - - - + + + - - + + - - - + + + - - - + + + - - + + - - + + - - - + + + @@ -122553,22 +122553,22 @@ - - + + - - - + + + - - + + - - - + + + @@ -122593,9 +122593,9 @@ - - - + + + @@ -122608,10 +122608,10 @@ - - - - + + + + @@ -122953,7 +122953,7 @@ - + @@ -123211,14 +123211,14 @@ - - - + + + - - - + + + @@ -123484,9 +123484,9 @@ - - - + + + @@ -123594,14 +123594,14 @@ - - + + - - + + @@ -123613,59 +123613,59 @@ - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - + + + @@ -123691,24 +123691,24 @@ - - - + + + - - - + + + - - - - + + + + - - + + @@ -123727,9 +123727,9 @@ - - - + + + @@ -123740,27 +123740,27 @@ - - - + + + - - - + + + - - + + - - - + + + @@ -123838,42 +123838,42 @@ - - - + + + - - - - + + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - + + @@ -124073,8 +124073,8 @@ - - + + @@ -125292,16 +125292,16 @@ - - - - + + + + - - - - + + + + @@ -125336,9 +125336,9 @@ - - - + + + @@ -125370,9 +125370,9 @@ - - - + + + @@ -125716,19 +125716,19 @@ - - + + - - - - + + + + - - - + + + @@ -126193,9 +126193,9 @@ - - - + + + @@ -126210,9 +126210,9 @@ - - - + + + @@ -126551,15 +126551,15 @@ - - - - + + + + - - - + + + @@ -126589,25 +126589,25 @@ - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -127605,8 +127605,8 @@ - - + + @@ -127886,14 +127886,14 @@ - - - + + + - - - + + + @@ -127906,8 +127906,8 @@ - - + + @@ -127920,9 +127920,9 @@ - - - + + + @@ -128207,8 +128207,8 @@ - - + + @@ -128683,18 +128683,18 @@ - - - - - - + + + + + + - - - - + + + + @@ -128713,10 +128713,10 @@ - - - - + + + + @@ -128724,8 +128724,8 @@ - - + + @@ -128769,9 +128769,9 @@ - - - + + + @@ -128805,66 +128805,66 @@ - - - - - + + + + + - - - + + + - - - - - + + + + + - - - + + + - - - - + + + + - - - - + + + + - - - + + + - - + + - - - - - - - + + + + + + + @@ -129024,14 +129024,14 @@ - - + + - - - - + + + + @@ -129391,9 +129391,9 @@ - - - + + + @@ -129417,22 +129417,22 @@ - - - + + + - - - - + + + + - - - - - + + + + + @@ -129440,10 +129440,10 @@ - - - - + + + + @@ -129566,8 +129566,8 @@ - - + + @@ -130171,9 +130171,9 @@ - - - + + + @@ -130555,16 +130555,16 @@ - - + + - - - - - - + + + + + + @@ -130823,8 +130823,8 @@ - - + + @@ -131117,8 +131117,8 @@ - - + + @@ -132567,41 +132567,41 @@ - - + + - + - - + + - - + + - - + + - - - + + + - - + + - - - - - - + + + + + + @@ -132614,16 +132614,16 @@ - - - - - - + + + + + + - - + + @@ -133480,8 +133480,8 @@ - - + + @@ -134173,22 +134173,22 @@ - - + + - - - - + + + + - - + + - - + + @@ -134197,125 +134197,125 @@ - - - - - - - + + + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - - - + + + + + + + - - - + + + - - - - + + + + - - - - + + + + - - - + + + - - + + - - - - - - + + + + + + - - - - - - - - - + + + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - + + + - - - + + + @@ -134477,11 +134477,11 @@ - - - - - + + + + + @@ -134706,12 +134706,12 @@ - - + + - - + + @@ -134742,9 +134742,9 @@ - - - + + + @@ -135260,14 +135260,14 @@ - - - - + + + + - - + + @@ -135390,9 +135390,9 @@ - - - + + + @@ -135730,11 +135730,11 @@ - - + + - + @@ -135762,7 +135762,7 @@ - + @@ -136055,13 +136055,13 @@ - - - + + + - - + + @@ -136570,55 +136570,55 @@ - - - + + + - - - + + + - - + + - - - + + + - - - + + + - - + + - - + + - - - - + + + + - - - + + + - - - - - + + + + + @@ -136626,9 +136626,9 @@ - - - + + + @@ -136636,44 +136636,44 @@ - - + + - - - - - - - - - - - - - + - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + - - - + + + @@ -136681,10 +136681,10 @@ - - - - + + + + @@ -136692,43 +136692,43 @@ - - - - + + + + - - + + - - - + + + - - + + - - - - + + + + - - - + + + - - - + + + @@ -136740,39 +136740,39 @@ - - + + - - + + - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + @@ -136795,13 +136795,13 @@ - - - + + + - - + + @@ -137021,61 +137021,61 @@ - - - + + + - - + + - - - + + + - - - - + + + + - - - - + + + + - - - + + + - - + + - - - - - + + + + + - - - - - + + + + + - - + + @@ -137093,59 +137093,59 @@ - - - - + + + + - - - - + + + + - - + + - - - + + + - - - + + + - - + + - - + + - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -137153,14 +137153,14 @@ - - - + + + - - - + + + @@ -137620,14 +137620,14 @@ - - - + + + - - - + + + @@ -138167,10 +138167,10 @@ - - - - + + + + @@ -138198,8 +138198,8 @@ - - + + @@ -138936,15 +138936,15 @@ - - - - + + + + - - - + + + @@ -139330,9 +139330,9 @@ - - - + + + @@ -140156,13 +140156,13 @@ - - - + + + - - + + @@ -140215,11 +140215,11 @@ - - - - - + + + + + @@ -140264,8 +140264,8 @@ - - + + @@ -140492,10 +140492,10 @@ - + - + @@ -140544,9 +140544,9 @@ - - - + + + @@ -140731,12 +140731,12 @@ - - + + - - + + @@ -141220,8 +141220,8 @@ - - + + @@ -141737,7 +141737,7 @@ - + @@ -142049,9 +142049,9 @@ - - - + + + @@ -142099,10 +142099,10 @@ - - - - + + + + @@ -142166,17 +142166,17 @@ - - - + + + - - + + - - + + @@ -142191,8 +142191,8 @@ - - + + @@ -143171,7 +143171,7 @@ - + @@ -143189,7 +143189,7 @@ - + @@ -143242,31 +143242,31 @@ - - - - - + + + + + - - - - - + + + + + - - + + - - - + + + - - + + @@ -143276,21 +143276,21 @@ - - - + + + - - - + + + - - - - - + + + + + @@ -143307,35 +143307,35 @@ - - - - - + + + + + - - - + + + - - + + - - + + - - - - + + + + - - - + + + @@ -143349,49 +143349,49 @@ - - - - + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + @@ -143406,33 +143406,33 @@ - - - - - + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - + + + @@ -144635,7 +144635,7 @@ - + @@ -144682,20 +144682,20 @@ - - - - - + + + + + - - - + + + @@ -145326,19 +145326,19 @@ - + - + - + - + @@ -146363,8 +146363,8 @@ - - + + @@ -146421,8 +146421,8 @@ - - + + @@ -146430,14 +146430,14 @@ - - - + + + - - - + + + @@ -146456,13 +146456,13 @@ - - - + + + - - + + @@ -147071,21 +147071,21 @@ - - + + - - + + - - - + + + @@ -147402,8 +147402,8 @@ - - + + @@ -147703,9 +147703,9 @@ - - - + + + @@ -147812,8 +147812,8 @@ - - + + @@ -147844,8 +147844,8 @@ - - + + @@ -147882,8 +147882,8 @@ - - + + @@ -147953,8 +147953,8 @@ - - + + @@ -149547,7 +149547,7 @@ - + diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 7e90612af3ac..1d62f241cd87 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -262,7 +262,11 @@ static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa) } void irq_domain_free_fwnode(struct fwnode_handle *fwnode); +#ifdef __GENKSYMS__ /* Android KABI hack to preserve CRC checker */ +struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size, +#else struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size, +#endif irq_hw_number_t hwirq_max, int direct_max, const struct irq_domain_ops *ops, void *host_data); From f1b6325b25bd4fbd37b60ee67dd9814710446b9c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Mar 2023 07:05:52 +0000 Subject: [PATCH 0842/1017] Revert "HID: uhid: Over-ride the default maximum data buffer value with our own" This reverts commit e57f797e3ffafb09eafb9be69d065d1e0331da61 which is commit 1c5d4221240a233df2440fe75c881465cdf8da07 upstream. It breaks the Android KABI and if needed, should come back in an abi-safe way. Bug: 161946584 Cc: Lee Jones Change-Id: I9a460d9dbc41512ee71ff607e875f2da9be7f9f6 Signed-off-by: Greg Kroah-Hartman --- drivers/hid/uhid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index ba0ca652b9da..fc06d8bb42e0 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -395,7 +395,6 @@ struct hid_ll_driver uhid_hid_driver = { .parse = uhid_hid_parse, .raw_request = uhid_hid_raw_request, .output_report = uhid_hid_output_report, - .max_buffer_size = UHID_DATA_MAX, }; EXPORT_SYMBOL_GPL(uhid_hid_driver); From 90eb02302b5e03f83d83287f5486e754b7c15826 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Mar 2023 07:05:58 +0000 Subject: [PATCH 0843/1017] Revert "HID: core: Provide new max_buffer_size attribute to over-ride the default" This reverts commit 9bc878756b017f2e1d8dc4f261faa64f69c4c2ee which is commit b1a37ed00d7908a991c1d0f18a8cba3c2aa99bdc upstream. It breaks the Android KABI and if needed, should come back in an abi-safe way. Bug: 161946584 Cc: Lee Jones Change-Id: I1f160797720e8bdf4960542e711fd17940a975d9 Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 18 +++++------------- include/linux/hid.h | 3 --- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 524d6d712e72..5f9ec1d1464a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -258,7 +258,6 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign { struct hid_report *report; struct hid_field *field; - unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE; unsigned int usages; unsigned int offset; unsigned int i; @@ -289,11 +288,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign offset = report->size; report->size += parser->global.report_size * parser->global.report_count; - if (parser->device->ll_driver->max_buffer_size) - max_buffer_size = parser->device->ll_driver->max_buffer_size; - /* Total size check: Allow for possible report index byte */ - if (report->size > (max_buffer_size - 1) << 3) { + if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { hid_err(parser->device, "report is too long\n"); return -1; } @@ -1756,7 +1752,6 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; - int max_buffer_size = HID_MAX_BUFFER_SIZE; unsigned int a; u32 rsize, csize = size; u8 *cdata = data; @@ -1773,13 +1768,10 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, rsize = hid_compute_report_size(report); - if (hid->ll_driver->max_buffer_size) - max_buffer_size = hid->ll_driver->max_buffer_size; - - if (report_enum->numbered && rsize >= max_buffer_size) - rsize = max_buffer_size - 1; - else if (rsize > max_buffer_size) - rsize = max_buffer_size; + if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE - 1; + else if (rsize > HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE; if (csize < rsize) { dbg_hid("report %d is too short, (%d < %d)\n", report->id, diff --git a/include/linux/hid.h b/include/linux/hid.h index 256f34f49167..2ba33d708942 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -798,7 +798,6 @@ struct hid_driver { * @raw_request: send raw report request to device (e.g. feature report) * @output_report: send output report to device * @idle: send idle request to device - * @max_buffer_size: over-ride maximum data buffer size (default: HID_MAX_BUFFER_SIZE) */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -823,8 +822,6 @@ struct hid_ll_driver { int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len); int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); - - unsigned int max_buffer_size; }; extern struct hid_ll_driver i2c_hid_ll_driver; From 29ee1495e8577d2433b294417f29a3c4d65b4d9e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 5 Jan 2023 02:22:19 +0200 Subject: [PATCH 0844/1017] interconnect: qcom: osm-l3: fix icc_onecell_data allocation [ Upstream commit f77ebdda0ee652124061c2ac42399bb6c367e729 ] This is a struct with a trailing zero-length array of icc_node pointers but it's allocated as if it were a single array of icc_nodes instead. Fortunately this overallocates memory rather then allocating less memory than required. Fix by replacing devm_kcalloc() with devm_kzalloc() and struct_size() macro. Fixes: 5bc9900addaf ("interconnect: qcom: Add OSM L3 interconnect provider support") Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20230105002221.1416479-2-dmitry.baryshkov@linaro.org Signed-off-by: Georgi Djakov Signed-off-by: Sasha Levin --- drivers/interconnect/qcom/osm-l3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c index 695f28789e98..08a282d57320 100644 --- a/drivers/interconnect/qcom/osm-l3.c +++ b/drivers/interconnect/qcom/osm-l3.c @@ -258,7 +258,7 @@ static int qcom_osm_l3_probe(struct platform_device *pdev) qnodes = desc->nodes; num_nodes = desc->num_nodes; - data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes), GFP_KERNEL); if (!data) return -ENOMEM; From ddcf8320003638a06eb1e46412e045d0c5701575 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Tue, 14 Mar 2023 04:47:35 +0000 Subject: [PATCH 0845/1017] perf/core: Fix perf_output_begin parameter is incorrectly invoked in perf_event_bpf_output [ Upstream commit eb81a2ed4f52be831c9fb879752d89645a312c13 ] syzkaller reportes a KASAN issue with stack-out-of-bounds. The call trace is as follows: dump_stack+0x9c/0xd3 print_address_description.constprop.0+0x19/0x170 __kasan_report.cold+0x6c/0x84 kasan_report+0x3a/0x50 __perf_event_header__init_id+0x34/0x290 perf_event_header__init_id+0x48/0x60 perf_output_begin+0x4a4/0x560 perf_event_bpf_output+0x161/0x1e0 perf_iterate_sb_cpu+0x29e/0x340 perf_iterate_sb+0x4c/0xc0 perf_event_bpf_event+0x194/0x2c0 __bpf_prog_put.constprop.0+0x55/0xf0 __cls_bpf_delete_prog+0xea/0x120 [cls_bpf] cls_bpf_delete_prog_work+0x1c/0x30 [cls_bpf] process_one_work+0x3c2/0x730 worker_thread+0x93/0x650 kthread+0x1b8/0x210 ret_from_fork+0x1f/0x30 commit 267fb27352b6 ("perf: Reduce stack usage of perf_output_begin()") use on-stack struct perf_sample_data of the caller function. However, perf_event_bpf_output uses incorrect parameter to convert small-sized data (struct perf_bpf_event) into large-sized data (struct perf_sample_data), which causes memory overwriting occurs in __perf_event_header__init_id. Fixes: 267fb27352b6 ("perf: Reduce stack usage of perf_output_begin()") Signed-off-by: Yang Jihong Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20230314044735.56551-1-yangjihong1@huawei.com Signed-off-by: Sasha Levin --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index d7b61116f15b..eb8660ed1abb 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8710,7 +8710,7 @@ static void perf_event_bpf_output(struct perf_event *event, void *data) perf_event_header__init_id(&bpf_event->event_id.header, &sample, event); - ret = perf_output_begin(&handle, data, event, + ret = perf_output_begin(&handle, &sample, event, bpf_event->event_id.header.size); if (ret) return; From 18dd825b865117db0e0e5557ddb3f7e0322739db Mon Sep 17 00:00:00 2001 From: Song Liu Date: Mon, 13 Mar 2023 10:16:08 -0700 Subject: [PATCH 0846/1017] perf: fix perf_event_context->time [ Upstream commit baf1b12a67f5b24f395baca03e442ce27cab0c18 ] Time readers rely on perf_event_context->[time|timestamp|timeoffset] to get accurate time_enabled and time_running for an event. The difference between ctx->timestamp and ctx->time is the among of time when the context is not enabled. __update_context_time(ctx, false) is used to increase timestamp, but not time. Therefore, it should only be called in ctx_sched_in() when EVENT_TIME was not enabled. Fixes: 09f5e7dc7ad7 ("perf: Fix perf_event_read_local() time") Signed-off-by: Song Liu Signed-off-by: Peter Zijlstra (Intel) Acked-by: Namhyung Kim Link: https://lkml.kernel.org/r/20230313171608.298734-1-song@kernel.org Signed-off-by: Sasha Levin --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index eb8660ed1abb..e2e1371fbb9d 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3817,7 +3817,7 @@ ctx_sched_in(struct perf_event_context *ctx, if (likely(!ctx->nr_events)) return; - if (is_active ^ EVENT_TIME) { + if (!(is_active & EVENT_TIME)) { /* start ctx time */ __update_context_time(ctx, false); perf_cgroup_set_timestamp(task, ctx); From 4d57c90f24e1f197faa8bc472a6082fbbdbed259 Mon Sep 17 00:00:00 2001 From: Liguang Zhang Date: Mon, 1 Mar 2021 22:05:15 +0800 Subject: [PATCH 0847/1017] ipmi:ssif: make ssif_i2c_send() void [ Upstream commit dcd10526ac5a0d6cc94ce60b9acfca458163277b ] This function actually needs no return value. So remove the unneeded check and make it void. Signed-off-by: Liguang Zhang Message-Id: <20210301140515.18951-1-zhangliguang@linux.alibaba.com> Signed-off-by: Corey Minyard Stable-dep-of: 00bb7e763ec9 ("ipmi:ssif: Add a timer between request retries") Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 81 +++++++++-------------------------- 1 file changed, 20 insertions(+), 61 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 0f2bac24e564..e9775b17dc92 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -510,7 +510,7 @@ static int ipmi_ssif_thread(void *data) return 0; } -static int ssif_i2c_send(struct ssif_info *ssif_info, +static void ssif_i2c_send(struct ssif_info *ssif_info, ssif_i2c_done handler, int read_write, int command, unsigned char *data, unsigned int size) @@ -522,7 +522,6 @@ static int ssif_i2c_send(struct ssif_info *ssif_info, ssif_info->i2c_data = data; ssif_info->i2c_size = size; complete(&ssif_info->wake_thread); - return 0; } @@ -531,22 +530,12 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, static void start_get(struct ssif_info *ssif_info) { - int rv; - ssif_info->rtc_us_timer = 0; ssif_info->multi_pos = 0; - rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, - SSIF_IPMI_RESPONSE, - ssif_info->recv, I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - /* request failed, just return the error. */ - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(5)\n"); - - msg_done_handler(ssif_info, -EIO, NULL, 0); - } + ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, + SSIF_IPMI_RESPONSE, + ssif_info->recv, I2C_SMBUS_BLOCK_DATA); } static void retry_timeout(struct timer_list *t) @@ -620,7 +609,6 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, { struct ipmi_smi_msg *msg; unsigned long oflags, *flags; - int rv; /* * We are single-threaded here, so no need for a lock until we @@ -666,17 +654,10 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, ssif_info->multi_len = len; ssif_info->multi_pos = 1; - rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, - SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, - ssif_info->recv, I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(1)\n"); - - result = -EIO; - } else - return; + ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, + SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, + ssif_info->recv, I2C_SMBUS_BLOCK_DATA); + return; } else if (ssif_info->multi_pos) { /* Middle of multi-part read. Start the next transaction. */ int i; @@ -738,19 +719,12 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, ssif_info->multi_pos++; - rv = ssif_i2c_send(ssif_info, msg_done_handler, - I2C_SMBUS_READ, - SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, - ssif_info->recv, - I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from ssif_i2c_send\n"); - - result = -EIO; - } else - return; + ssif_i2c_send(ssif_info, msg_done_handler, + I2C_SMBUS_READ, + SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, + ssif_info->recv, + I2C_SMBUS_BLOCK_DATA); + return; } } @@ -931,8 +905,6 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, static void msg_written_handler(struct ssif_info *ssif_info, int result, unsigned char *data, unsigned int len) { - int rv; - /* We are single-threaded here, so no need for a lock. */ if (result < 0) { ssif_info->retries_left--; @@ -995,18 +967,9 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, ssif_info->multi_data = NULL; } - rv = ssif_i2c_send(ssif_info, msg_written_handler, - I2C_SMBUS_WRITE, cmd, - data_to_send, I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - /* request failed, just return the error. */ - ssif_inc_stat(ssif_info, send_errors); - - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(3)\n"); - msg_done_handler(ssif_info, -EIO, NULL, 0); - } + ssif_i2c_send(ssif_info, msg_written_handler, + I2C_SMBUS_WRITE, cmd, + data_to_send, I2C_SMBUS_BLOCK_DATA); } else { /* Ready to request the result. */ unsigned long oflags, *flags; @@ -1035,7 +998,6 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, static int start_resend(struct ssif_info *ssif_info) { - int rv; int command; ssif_info->got_alert = false; @@ -1057,12 +1019,9 @@ static int start_resend(struct ssif_info *ssif_info) ssif_info->data[0] = ssif_info->data_len; } - rv = ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, - command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); - if (rv && (ssif_info->ssif_debug & SSIF_DEBUG_MSG)) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(4)\n"); - return rv; + ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, + command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); + return 0; } static int start_send(struct ssif_info *ssif_info, From cd35cbde00786872b473b01abd6c3ef97b837480 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Thu, 3 Nov 2022 15:03:11 -0500 Subject: [PATCH 0848/1017] ipmi:ssif: Increase the message retry time [ Upstream commit 39721d62bbc16ebc9bb2bdc2c163658f33da3b0b ] The spec states that the minimum message retry time is 60ms, but it was set to 20ms. Correct it. Reported by: Tony Camuso Signed-off-by: Corey Minyard Stable-dep-of: 00bb7e763ec9 ("ipmi:ssif: Add a timer between request retries") Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index e9775b17dc92..167ca54d186c 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -74,7 +74,7 @@ /* * Timer values */ -#define SSIF_MSG_USEC 20000 /* 20ms between message tries. */ +#define SSIF_MSG_USEC 60000 /* 60ms between message tries. */ #define SSIF_MSG_PART_USEC 5000 /* 5ms for a message part */ /* How many times to we retry sending/receiving the message. */ From c94de7f85d99eef7bcab665da1d5888ad05fa4bc Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 25 Jan 2023 10:11:06 -0600 Subject: [PATCH 0849/1017] ipmi:ssif: resend_msg() cannot fail [ Upstream commit 95767ed78a181d5404202627499f9cde56053b96 ] The resend_msg() function cannot fail, but there was error handling around using it. Rework the handling of the error, and fix the out of retries debug reporting that was wrong around this, too. Cc: stable@vger.kernel.org Signed-off-by: Corey Minyard Stable-dep-of: 00bb7e763ec9 ("ipmi:ssif: Add a timer between request retries") Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 167ca54d186c..cae21632cf07 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -602,7 +602,7 @@ static void ssif_alert(struct i2c_client *client, enum i2c_alert_protocol type, start_get(ssif_info); } -static int start_resend(struct ssif_info *ssif_info); +static void start_resend(struct ssif_info *ssif_info); static void msg_done_handler(struct ssif_info *ssif_info, int result, unsigned char *data, unsigned int len) @@ -909,31 +909,17 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, if (result < 0) { ssif_info->retries_left--; if (ssif_info->retries_left > 0) { - if (!start_resend(ssif_info)) { - ssif_inc_stat(ssif_info, send_retries); - return; - } - /* request failed, just return the error. */ - ssif_inc_stat(ssif_info, send_errors); - - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "%s: Out of retries\n", __func__); - msg_done_handler(ssif_info, -EIO, NULL, 0); + start_resend(ssif_info); return; } ssif_inc_stat(ssif_info, send_errors); - /* - * Got an error on transmit, let the done routine - * handle it. - */ if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) dev_dbg(&ssif_info->client->dev, - "%s: Error %d\n", __func__, result); + "%s: Out of retries\n", __func__); - msg_done_handler(ssif_info, result, NULL, 0); + msg_done_handler(ssif_info, -EIO, NULL, 0); return; } @@ -996,7 +982,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, } } -static int start_resend(struct ssif_info *ssif_info) +static void start_resend(struct ssif_info *ssif_info) { int command; @@ -1021,7 +1007,6 @@ static int start_resend(struct ssif_info *ssif_info) ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); - return 0; } static int start_send(struct ssif_info *ssif_info, @@ -1036,7 +1021,8 @@ static int start_send(struct ssif_info *ssif_info, ssif_info->retries_left = SSIF_SEND_RETRIES; memcpy(ssif_info->data + 1, data, len); ssif_info->data_len = len; - return start_resend(ssif_info); + start_resend(ssif_info); + return 0; } /* Must be called with the message lock held. */ From 8f9ae017dd3571659b3f1f2dde6db6371a248821 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 25 Jan 2023 10:34:47 -0600 Subject: [PATCH 0850/1017] ipmi:ssif: Add a timer between request retries [ Upstream commit 00bb7e763ec9f384cb382455cb6ba5588b5375cf ] The IPMI spec has a time (T6) specified between request retries. Add the handling for that. Reported by: Tony Camuso Cc: stable@vger.kernel.org Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index cae21632cf07..20dc2452815c 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -74,7 +74,8 @@ /* * Timer values */ -#define SSIF_MSG_USEC 60000 /* 60ms between message tries. */ +#define SSIF_MSG_USEC 60000 /* 60ms between message tries (T3). */ +#define SSIF_REQ_RETRY_USEC 60000 /* 60ms between send retries (T6). */ #define SSIF_MSG_PART_USEC 5000 /* 5ms for a message part */ /* How many times to we retry sending/receiving the message. */ @@ -82,7 +83,9 @@ #define SSIF_RECV_RETRIES 250 #define SSIF_MSG_MSEC (SSIF_MSG_USEC / 1000) +#define SSIF_REQ_RETRY_MSEC (SSIF_REQ_RETRY_USEC / 1000) #define SSIF_MSG_JIFFIES ((SSIF_MSG_USEC * 1000) / TICK_NSEC) +#define SSIF_REQ_RETRY_JIFFIES ((SSIF_REQ_RETRY_USEC * 1000) / TICK_NSEC) #define SSIF_MSG_PART_JIFFIES ((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC) /* @@ -229,6 +232,9 @@ struct ssif_info { bool got_alert; bool waiting_alert; + /* Used to inform the timeout that it should do a resend. */ + bool do_resend; + /* * If set to true, this will request events the next time the * state machine is idle. @@ -538,22 +544,28 @@ static void start_get(struct ssif_info *ssif_info) ssif_info->recv, I2C_SMBUS_BLOCK_DATA); } +static void start_resend(struct ssif_info *ssif_info); + static void retry_timeout(struct timer_list *t) { struct ssif_info *ssif_info = from_timer(ssif_info, t, retry_timer); unsigned long oflags, *flags; - bool waiting; + bool waiting, resend; if (ssif_info->stopping) return; flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + resend = ssif_info->do_resend; + ssif_info->do_resend = false; waiting = ssif_info->waiting_alert; ssif_info->waiting_alert = false; ipmi_ssif_unlock_cond(ssif_info, flags); if (waiting) start_get(ssif_info); + if (resend) + start_resend(ssif_info); } static void watch_timeout(struct timer_list *t) @@ -602,8 +614,6 @@ static void ssif_alert(struct i2c_client *client, enum i2c_alert_protocol type, start_get(ssif_info); } -static void start_resend(struct ssif_info *ssif_info); - static void msg_done_handler(struct ssif_info *ssif_info, int result, unsigned char *data, unsigned int len) { @@ -909,7 +919,13 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, if (result < 0) { ssif_info->retries_left--; if (ssif_info->retries_left > 0) { - start_resend(ssif_info); + /* + * Wait the retry timeout time per the spec, + * then redo the send. + */ + ssif_info->do_resend = true; + mod_timer(&ssif_info->retry_timer, + jiffies + SSIF_REQ_RETRY_JIFFIES); return; } @@ -1322,8 +1338,10 @@ static int do_cmd(struct i2c_client *client, int len, unsigned char *msg, ret = i2c_smbus_write_block_data(client, SSIF_IPMI_REQUEST, len, msg); if (ret) { retry_cnt--; - if (retry_cnt > 0) + if (retry_cnt > 0) { + msleep(SSIF_REQ_RETRY_MSEC); goto retry1; + } return -ENODEV; } @@ -1464,8 +1482,10 @@ retry_write: 32, msg); if (ret) { retry_cnt--; - if (retry_cnt > 0) + if (retry_cnt > 0) { + msleep(SSIF_REQ_RETRY_MSEC); goto retry_write; + } dev_err(&client->dev, "Could not write multi-part start, though the BMC said it could handle it. Just limit sends to one part.\n"); return ret; } From 4cc54f6ae5351dd883120751b75405c9e38aeecc Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 27 Aug 2021 11:25:09 +0200 Subject: [PATCH 0851/1017] KVM: Clean up benign vcpu->cpu data races when kicking vCPUs [ Upstream commit 85b640450ddcfa09cf72771b69a9c3daf0ddc772 ] Fix a benign data race reported by syzbot+KCSAN[*] by ensuring vcpu->cpu is read exactly once, and by ensuring the vCPU is booted from guest mode if kvm_arch_vcpu_should_kick() returns true. Fix a similar race in kvm_make_vcpus_request_mask() by ensuring the vCPU is interrupted if kvm_request_needs_ipi() returns true. Reading vcpu->cpu before vcpu->mode (via kvm_arch_vcpu_should_kick() or kvm_request_needs_ipi()) means the target vCPU could get migrated (change vcpu->cpu) and enter !OUTSIDE_GUEST_MODE between reading vcpu->cpud and reading vcpu->mode. If that happens, the kick/IPI will be sent to the old pCPU, not the new pCPU that is now running the vCPU or reading SPTEs. Although failing to kick the vCPU is not exactly ideal, practically speaking it cannot cause a functional issue unless there is also a bug in the caller, and any such bug would exist regardless of kvm_vcpu_kick()'s behavior. The purpose of sending an IPI is purely to get a vCPU into the host (or out of reading SPTEs) so that the vCPU can recognize a change in state, e.g. a KVM_REQ_* request. If vCPU's handling of the state change is required for correctness, KVM must ensure either the vCPU sees the change before entering the guest, or that the sender sees the vCPU as running in guest mode. All architectures handle this by (a) sending the request before calling kvm_vcpu_kick() and (b) checking for requests _after_ setting vcpu->mode. x86's READING_SHADOW_PAGE_TABLES has similar requirements; KVM needs to ensure it kicks and waits for vCPUs that started reading SPTEs _before_ MMU changes were finalized, but any vCPU that starts reading after MMU changes were finalized will see the new state and can continue on uninterrupted. For uses of kvm_vcpu_kick() that are not paired with a KVM_REQ_*, e.g. x86's kvm_arch_sync_dirty_log(), the order of the kick must not be relied upon for functional correctness, e.g. in the dirty log case, userspace cannot assume it has a 100% complete log if vCPUs are still running. All that said, eliminate the benign race since the cost of doing so is an "extra" atomic cmpxchg() in the case where the target vCPU is loaded by the current pCPU or is not loaded at all. I.e. the kick will be skipped due to kvm_vcpu_exiting_guest_mode() seeing a compatible vcpu->mode as opposed to the kick being skipped because of the cpu checks. Keep the "cpu != me" checks even though they appear useless/impossible at first glance. x86 processes guest IPI writes in a fast path that runs in IN_GUEST_MODE, i.e. can call kvm_vcpu_kick() from IN_GUEST_MODE. And calling kvm_vm_bugged()->kvm_make_vcpus_request_mask() from IN_GUEST or READING_SHADOW_PAGE_TABLES is perfectly reasonable. Note, a race with the cpu_online() check in kvm_vcpu_kick() likely persists, e.g. the vCPU could exit guest mode and get offlined between the cpu_online() check and the sending of smp_send_reschedule(). But, the online check appears to exist only to avoid a WARN in x86's native_smp_send_reschedule() that fires if the target CPU is not online. The reschedule WARN exists because CPU offlining takes the CPU out of the scheduling pool, i.e. the WARN is intended to detect the case where the kernel attempts to schedule a task on an offline CPU. The actual sending of the IPI is a non-issue as at worst it will simpy be dropped on the floor. In other words, KVM's usurping of the reschedule IPI could theoretically trigger a WARN if the stars align, but there will be no loss of functionality. [*] https://syzkaller.appspot.com/bug?extid=cd4154e502f43f10808a Cc: Venkatesh Srinivas Cc: Vitaly Kuznetsov Fixes: 97222cc83163 ("KVM: Emulate local APIC in kernel") Signed-off-by: Sean Christopherson Signed-off-by: Vitaly Kuznetsov Message-Id: <20210827092516.1027264-2-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Stable-dep-of: 2b0128127373 ("KVM: Register /dev/kvm as the _very_ last thing during initialization") Signed-off-by: Sasha Levin --- virt/kvm/kvm_main.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 564d5c145fbe..b5134f304648 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -276,14 +276,26 @@ bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, continue; kvm_make_request(req, vcpu); - cpu = vcpu->cpu; if (!(req & KVM_REQUEST_NO_WAKEUP) && kvm_vcpu_wake_up(vcpu)) continue; - if (tmp != NULL && cpu != -1 && cpu != me && - kvm_request_needs_ipi(vcpu, req)) - __cpumask_set_cpu(cpu, tmp); + /* + * Note, the vCPU could get migrated to a different pCPU at any + * point after kvm_request_needs_ipi(), which could result in + * sending an IPI to the previous pCPU. But, that's ok because + * the purpose of the IPI is to ensure the vCPU returns to + * OUTSIDE_GUEST_MODE, which is satisfied if the vCPU migrates. + * Entering READING_SHADOW_PAGE_TABLES after this point is also + * ok, as the requirement is only that KVM wait for vCPUs that + * were reading SPTEs _before_ any changes were finalized. See + * kvm_vcpu_kick() for more details on handling requests. + */ + if (tmp != NULL && kvm_request_needs_ipi(vcpu, req)) { + cpu = READ_ONCE(vcpu->cpu); + if (cpu != -1 && cpu != me) + __cpumask_set_cpu(cpu, tmp); + } } called = kvm_kick_many_cpus(tmp, !!(req & KVM_REQUEST_WAIT)); @@ -2937,16 +2949,24 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_wake_up); */ void kvm_vcpu_kick(struct kvm_vcpu *vcpu) { - int me; - int cpu = vcpu->cpu; + int me, cpu; if (kvm_vcpu_wake_up(vcpu)) return; + /* + * Note, the vCPU could get migrated to a different pCPU at any point + * after kvm_arch_vcpu_should_kick(), which could result in sending an + * IPI to the previous pCPU. But, that's ok because the purpose of the + * IPI is to force the vCPU to leave IN_GUEST_MODE, and migrating the + * vCPU also requires it to leave IN_GUEST_MODE. + */ me = get_cpu(); - if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) - if (kvm_arch_vcpu_should_kick(vcpu)) + if (kvm_arch_vcpu_should_kick(vcpu)) { + cpu = READ_ONCE(vcpu->cpu); + if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) smp_send_reschedule(cpu); + } put_cpu(); } EXPORT_SYMBOL_GPL(kvm_vcpu_kick); From ad120bc8693028ed400bc3b9ec349cfaf7bfef3b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 27 Aug 2021 11:25:10 +0200 Subject: [PATCH 0852/1017] KVM: KVM: Use cpumask_available() to check for NULL cpumask when kicking vCPUs [ Upstream commit 0bbc2ca8515f9cdf11df84ccb63dc7c44bc3d8f4 ] Check for a NULL cpumask_var_t when kicking multiple vCPUs via cpumask_available(), which performs a !NULL check if and only if cpumasks are configured to be allocated off-stack. This is a meaningless optimization, e.g. avoids a TEST+Jcc and TEST+CMOV on x86, but more importantly helps document that the NULL check is necessary even though all callers pass in a local variable. No functional change intended. Cc: Lai Jiangshan Signed-off-by: Sean Christopherson Signed-off-by: Vitaly Kuznetsov Message-Id: <20210827092516.1027264-3-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Stable-dep-of: 2b0128127373 ("KVM: Register /dev/kvm as the _very_ last thing during initialization") Signed-off-by: Sasha Levin --- virt/kvm/kvm_main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b5134f304648..f379398b43d5 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -248,9 +248,13 @@ static void ack_flush(void *_completed) { } -static inline bool kvm_kick_many_cpus(const struct cpumask *cpus, bool wait) +static inline bool kvm_kick_many_cpus(cpumask_var_t tmp, bool wait) { - if (unlikely(!cpus)) + const struct cpumask *cpus; + + if (likely(cpumask_available(tmp))) + cpus = tmp; + else cpus = cpu_online_mask; if (cpumask_empty(cpus)) @@ -280,6 +284,14 @@ bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, if (!(req & KVM_REQUEST_NO_WAKEUP) && kvm_vcpu_wake_up(vcpu)) continue; + /* + * tmp can be "unavailable" if cpumasks are allocated off stack + * as allocation of the mask is deliberately not fatal and is + * handled by falling back to kicking all online CPUs. + */ + if (!cpumask_available(tmp)) + continue; + /* * Note, the vCPU could get migrated to a different pCPU at any * point after kvm_request_needs_ipi(), which could result in @@ -291,7 +303,7 @@ bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, * were reading SPTEs _before_ any changes were finalized. See * kvm_vcpu_kick() for more details on handling requests. */ - if (tmp != NULL && kvm_request_needs_ipi(vcpu, req)) { + if (kvm_request_needs_ipi(vcpu, req)) { cpu = READ_ONCE(vcpu->cpu); if (cpu != -1 && cpu != me) __cpumask_set_cpu(cpu, tmp); From 6100066358ee1bc5f2d329a7d8eb32bf8e3ee74d Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Sep 2021 09:51:37 +0200 Subject: [PATCH 0853/1017] KVM: Optimize kvm_make_vcpus_request_mask() a bit [ Upstream commit ae0946cd3601752dc58f86d84258e5361e9c8cd4 ] Iterating over set bits in 'vcpu_bitmap' should be faster than going through all vCPUs, especially when just a few bits are set. Drop kvm_make_vcpus_request_mask() call from kvm_make_all_cpus_request_except() to avoid handling the special case when 'vcpu_bitmap' is NULL, move the code to kvm_make_all_cpus_request_except() itself. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini Message-Id: <20210903075141.403071-5-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Stable-dep-of: 2b0128127373 ("KVM: Register /dev/kvm as the _very_ last thing during initialization") Signed-off-by: Sasha Levin --- virt/kvm/kvm_main.c | 88 +++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f379398b43d5..34931443dafa 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -264,50 +264,57 @@ static inline bool kvm_kick_many_cpus(cpumask_var_t tmp, bool wait) return true; } +static void kvm_make_vcpu_request(struct kvm *kvm, struct kvm_vcpu *vcpu, + unsigned int req, cpumask_var_t tmp, + int current_cpu) +{ + int cpu; + + kvm_make_request(req, vcpu); + + if (!(req & KVM_REQUEST_NO_WAKEUP) && kvm_vcpu_wake_up(vcpu)) + return; + + /* + * tmp can be "unavailable" if cpumasks are allocated off stack as + * allocation of the mask is deliberately not fatal and is handled by + * falling back to kicking all online CPUs. + */ + if (!cpumask_available(tmp)) + return; + + /* + * Note, the vCPU could get migrated to a different pCPU at any point + * after kvm_request_needs_ipi(), which could result in sending an IPI + * to the previous pCPU. But, that's OK because the purpose of the IPI + * is to ensure the vCPU returns to OUTSIDE_GUEST_MODE, which is + * satisfied if the vCPU migrates. Entering READING_SHADOW_PAGE_TABLES + * after this point is also OK, as the requirement is only that KVM wait + * for vCPUs that were reading SPTEs _before_ any changes were + * finalized. See kvm_vcpu_kick() for more details on handling requests. + */ + if (kvm_request_needs_ipi(vcpu, req)) { + cpu = READ_ONCE(vcpu->cpu); + if (cpu != -1 && cpu != current_cpu) + __cpumask_set_cpu(cpu, tmp); + } +} + bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, struct kvm_vcpu *except, unsigned long *vcpu_bitmap, cpumask_var_t tmp) { - int i, cpu, me; struct kvm_vcpu *vcpu; + int i, me; bool called; me = get_cpu(); - kvm_for_each_vcpu(i, vcpu, kvm) { - if ((vcpu_bitmap && !test_bit(i, vcpu_bitmap)) || - vcpu == except) + for_each_set_bit(i, vcpu_bitmap, KVM_MAX_VCPUS) { + vcpu = kvm_get_vcpu(kvm, i); + if (!vcpu || vcpu == except) continue; - - kvm_make_request(req, vcpu); - - if (!(req & KVM_REQUEST_NO_WAKEUP) && kvm_vcpu_wake_up(vcpu)) - continue; - - /* - * tmp can be "unavailable" if cpumasks are allocated off stack - * as allocation of the mask is deliberately not fatal and is - * handled by falling back to kicking all online CPUs. - */ - if (!cpumask_available(tmp)) - continue; - - /* - * Note, the vCPU could get migrated to a different pCPU at any - * point after kvm_request_needs_ipi(), which could result in - * sending an IPI to the previous pCPU. But, that's ok because - * the purpose of the IPI is to ensure the vCPU returns to - * OUTSIDE_GUEST_MODE, which is satisfied if the vCPU migrates. - * Entering READING_SHADOW_PAGE_TABLES after this point is also - * ok, as the requirement is only that KVM wait for vCPUs that - * were reading SPTEs _before_ any changes were finalized. See - * kvm_vcpu_kick() for more details on handling requests. - */ - if (kvm_request_needs_ipi(vcpu, req)) { - cpu = READ_ONCE(vcpu->cpu); - if (cpu != -1 && cpu != me) - __cpumask_set_cpu(cpu, tmp); - } + kvm_make_vcpu_request(kvm, vcpu, req, tmp, me); } called = kvm_kick_many_cpus(tmp, !!(req & KVM_REQUEST_WAIT)); @@ -319,12 +326,23 @@ bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, struct kvm_vcpu *except) { + struct kvm_vcpu *vcpu; cpumask_var_t cpus; bool called; + int i, me; zalloc_cpumask_var(&cpus, GFP_ATOMIC); - called = kvm_make_vcpus_request_mask(kvm, req, except, NULL, cpus); + me = get_cpu(); + + kvm_for_each_vcpu(i, vcpu, kvm) { + if (vcpu == except) + continue; + kvm_make_vcpu_request(kvm, vcpu, req, cpus, me); + } + + called = kvm_kick_many_cpus(cpus, !!(req & KVM_REQUEST_WAIT)); + put_cpu(); free_cpumask_var(cpus); return called; From 7958663668ef0ffe49c294ee55c83770b532c685 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Fri, 3 Sep 2021 09:51:40 +0200 Subject: [PATCH 0854/1017] KVM: Pre-allocate cpumasks for kvm_make_all_cpus_request_except() [ Upstream commit baff59ccdc657d290be51b95b38ebe5de40036b4 ] Allocating cpumask dynamically in zalloc_cpumask_var() is not ideal. Allocation is somewhat slow and can (in theory and when CPUMASK_OFFSTACK) fail. kvm_make_all_cpus_request_except() already disables preemption so we can use pre-allocated per-cpu cpumasks instead. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini Message-Id: <20210903075141.403071-8-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Stable-dep-of: 2b0128127373 ("KVM: Register /dev/kvm as the _very_ last thing during initialization") Signed-off-by: Sasha Levin --- virt/kvm/kvm_main.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 34931443dafa..d96a076aef0d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -154,6 +154,8 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm); static unsigned long long kvm_createvm_count; static unsigned long long kvm_active_vms; +static DEFINE_PER_CPU(cpumask_var_t, cpu_kick_mask); + __weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, unsigned long start, unsigned long end) { @@ -327,14 +329,15 @@ bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, struct kvm_vcpu *except) { struct kvm_vcpu *vcpu; - cpumask_var_t cpus; + struct cpumask *cpus; bool called; int i, me; - zalloc_cpumask_var(&cpus, GFP_ATOMIC); - me = get_cpu(); + cpus = this_cpu_cpumask_var_ptr(cpu_kick_mask); + cpumask_clear(cpus); + kvm_for_each_vcpu(i, vcpu, kvm) { if (vcpu == except) continue; @@ -344,7 +347,6 @@ bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, called = kvm_kick_many_cpus(cpus, !!(req & KVM_REQUEST_WAIT)); put_cpu(); - free_cpumask_var(cpus); return called; } @@ -5002,9 +5004,17 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, goto out_free_3; } + for_each_possible_cpu(cpu) { + if (!alloc_cpumask_var_node(&per_cpu(cpu_kick_mask, cpu), + GFP_KERNEL, cpu_to_node(cpu))) { + r = -ENOMEM; + goto out_free_4; + } + } + r = kvm_async_pf_init(); if (r) - goto out_free; + goto out_free_5; kvm_chardev_ops.owner = module; kvm_vm_fops.owner = module; @@ -5030,7 +5040,10 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, out_unreg: kvm_async_pf_deinit(); -out_free: +out_free_5: + for_each_possible_cpu(cpu) + free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); +out_free_4: kmem_cache_destroy(kvm_vcpu_cache); out_free_3: unregister_reboot_notifier(&kvm_reboot_notifier); @@ -5050,8 +5063,12 @@ EXPORT_SYMBOL_GPL(kvm_init); void kvm_exit(void) { + int cpu; + debugfs_remove_recursive(kvm_debugfs_dir); misc_deregister(&kvm_dev); + for_each_possible_cpu(cpu) + free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); kmem_cache_destroy(kvm_vcpu_cache); kvm_async_pf_deinit(); unregister_syscore_ops(&kvm_syscore_ops); From a43f7d0628e4f5cdb60c771a74d391c77ce87baf Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 30 Nov 2022 23:08:45 +0000 Subject: [PATCH 0855/1017] KVM: Register /dev/kvm as the _very_ last thing during initialization [ Upstream commit 2b01281273738bf2d6551da48d65db2df3f28998 ] Register /dev/kvm, i.e. expose KVM to userspace, only after all other setup has completed. Once /dev/kvm is exposed, userspace can start invoking KVM ioctls, creating VMs, etc... If userspace creates a VM before KVM is done with its configuration, bad things may happen, e.g. KVM will fail to properly migrate vCPU state if a VM is created before KVM has registered preemption notifiers. Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Message-Id: <20221130230934.1014142-2-seanjc@google.com> Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- virt/kvm/kvm_main.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d96a076aef0d..d2df08102171 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5020,12 +5020,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, kvm_vm_fops.owner = module; kvm_vcpu_fops.owner = module; - r = misc_register(&kvm_dev); - if (r) { - pr_err("kvm: misc device register failed\n"); - goto out_unreg; - } - register_syscore_ops(&kvm_syscore_ops); kvm_preempt_ops.sched_in = kvm_sched_in; @@ -5034,11 +5028,24 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, kvm_init_debug(); r = kvm_vfio_ops_init(); - WARN_ON(r); + if (WARN_ON_ONCE(r)) + goto err_vfio; + + /* + * Registration _must_ be the very last thing done, as this exposes + * /dev/kvm to userspace, i.e. all infrastructure must be setup! + */ + r = misc_register(&kvm_dev); + if (r) { + pr_err("kvm: misc device register failed\n"); + goto err_register; + } return 0; -out_unreg: +err_register: + kvm_vfio_ops_exit(); +err_vfio: kvm_async_pf_deinit(); out_free_5: for_each_possible_cpu(cpu) @@ -5065,8 +5072,14 @@ void kvm_exit(void) { int cpu; - debugfs_remove_recursive(kvm_debugfs_dir); + /* + * Note, unregistering /dev/kvm doesn't strictly need to come first, + * fops_get(), a.k.a. try_module_get(), prevents acquiring references + * to KVM while the module is being stopped. + */ misc_deregister(&kvm_dev); + + debugfs_remove_recursive(kvm_debugfs_dir); for_each_possible_cpu(cpu) free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); kmem_cache_destroy(kvm_vcpu_cache); From ae12308c7d5516891e616bdddfe20a303ac5b2d8 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 3 Aug 2022 18:42:08 +0800 Subject: [PATCH 0856/1017] serial: fsl_lpuart: Fix comment typo [ Upstream commit 374e01fa1304e1eabd2cd16f750da3ecaeab069b ] The double `as' is duplicated in the comment, remove one. Signed-off-by: Jason Wang Link: https://lore.kernel.org/r/20220803104208.4127-1-wangborong@cdjrlc.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 1be6f2b15f90 ("tty: serial: fsl_lpuart: fix race on RX DMA shutdown") Signed-off-by: Sasha Levin --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 32cce52800a7..bab296c5a021 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2766,7 +2766,7 @@ static int __maybe_unused lpuart_suspend(struct device *dev) * EDMA driver during suspend will forcefully release any * non-idle DMA channels. If port wakeup is enabled or if port * is console port or 'no_console_suspend' is set the Rx DMA - * cannot resume as as expected, hence gracefully release the + * cannot resume as expected, hence gracefully release the * Rx DMA path before suspend and start Rx DMA path on resume. */ if (irq_wake) { From 19a98d56dfedafb25652bdb9cd48a4e73ceba702 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Thu, 9 Mar 2023 14:43:02 +0100 Subject: [PATCH 0857/1017] tty: serial: fsl_lpuart: fix race on RX DMA shutdown [ Upstream commit 1be6f2b15f902c02e055ae0b419ca789200473c9 ] From time to time DMA completion can come in the middle of DMA shutdown: : : lpuart32_shutdown() lpuart_dma_shutdown() del_timer_sync() lpuart_dma_rx_complete() lpuart_copy_rx_to_tty() mod_timer() lpuart_dma_rx_free() When the timer fires a bit later, sport->dma_rx_desc is NULL: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000004 pc : lpuart_copy_rx_to_tty+0xcc/0x5bc lr : lpuart_timer_func+0x1c/0x2c Call trace: lpuart_copy_rx_to_tty lpuart_timer_func call_timer_fn __run_timers.part.0 run_timer_softirq __do_softirq __irq_exit_rcu irq_exit handle_domain_irq gic_handle_irq call_on_irq_stack do_interrupt_handler ... To fix this fold del_timer_sync() into lpuart_dma_rx_free() after dmaengine_terminate_sync() to make sure timer will not be re-started in lpuart_copy_rx_to_tty() <= lpuart_dma_rx_complete(). Fixes: 4a8588a1cf86 ("serial: fsl_lpuart: delete timer on shutdown") Cc: stable Signed-off-by: Alexander Sverdlin Link: https://lore.kernel.org/r/20230309134302.74940-2-alexander.sverdlin@siemens.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/fsl_lpuart.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index bab296c5a021..99f29bd930bd 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1278,6 +1278,7 @@ static void lpuart_dma_rx_free(struct uart_port *port) struct dma_chan *chan = sport->dma_rx_chan; dmaengine_terminate_all(chan); + del_timer_sync(&sport->lpuart_timer); dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE); kfree(sport->rx_ring.buf); sport->rx_ring.tail = 0; @@ -1743,7 +1744,6 @@ static int lpuart32_startup(struct uart_port *port) static void lpuart_dma_shutdown(struct lpuart_port *sport) { if (sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); sport->lpuart_dma_rx_use = false; } @@ -1894,10 +1894,8 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, * Since timer function acqures sport->port.lock, need to stop before * acquring same lock because otherwise del_timer_sync() can deadlock. */ - if (old && sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); + if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - } spin_lock_irqsave(&sport->port.lock, flags); @@ -2129,10 +2127,8 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, * Since timer function acqures sport->port.lock, need to stop before * acquring same lock because otherwise del_timer_sync() can deadlock. */ - if (old && sport->lpuart_dma_rx_use) { - del_timer_sync(&sport->lpuart_timer); + if (old && sport->lpuart_dma_rx_use) lpuart_dma_rx_free(&sport->port); - } spin_lock_irqsave(&sport->port.lock, flags); @@ -2770,7 +2766,6 @@ static int __maybe_unused lpuart_suspend(struct device *dev) * Rx DMA path before suspend and start Rx DMA path on resume. */ if (irq_wake) { - del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); } From 5fcb12f00a05241089449d7d7bdb22b66803e4ce Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 11 Jul 2022 10:42:52 +0200 Subject: [PATCH 0858/1017] serial: 8250: SERIAL_8250_ASPEED_VUART should depend on ARCH_ASPEED [ Upstream commit 806a449725cbd679a7f52c394d3c87b451d66bd5 ] The Aspeed Virtual UART is only present on Aspeed BMC platforms. Hence add a dependency on ARCH_ASPEED, to prevent asking the user about this driver when configuring a kernel without Aspeed BMC support. Reviewed-by: Jeremy Kerr Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/259138c372d433005b4871789ef9ee8d15320307.1657528861.git.geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman Stable-dep-of: f8086d1a65ac ("serial: 8250: ASPEED_VUART: select REGMAP instead of depending on it") Signed-off-by: Sasha Levin --- drivers/tty/serial/8250/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 136f2b1460f9..dcf89db183df 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -255,6 +255,7 @@ config SERIAL_8250_ASPEED_VUART depends on SERIAL_8250 depends on OF depends on REGMAP && MFD_SYSCON + depends on ARCH_ASPEED || COMPILE_TEST help If you want to use the virtual UART (VUART) device on Aspeed BMC platforms, enable this option. This enables the 16550A- From b5131ed83c8309d3005ce4a4c5dbbb98362dc696 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 25 Feb 2023 21:39:53 -0800 Subject: [PATCH 0859/1017] serial: 8250: ASPEED_VUART: select REGMAP instead of depending on it [ Upstream commit f8086d1a65ac693e3fd863128352b4b11ee7324d ] REGMAP is a hidden (not user visible) symbol. Users cannot set it directly thru "make *config", so drivers should select it instead of depending on it if they need it. Consistently using "select" or "depends on" can also help reduce Kconfig circular dependency issues. Therefore, change the use of "depends on REGMAP" to "select REGMAP". Fixes: 8d310c9107a2 ("drivers/tty/serial/8250: Make Aspeed VUART SIRQ polarity configurable") Cc: stable Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Oskar Senft Cc: linux-serial@vger.kernel.org Link: https://lore.kernel.org/r/20230226053953.4681-9-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/8250/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index dcf89db183df..b7922c8da1e6 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -254,8 +254,9 @@ config SERIAL_8250_ASPEED_VUART tristate "Aspeed Virtual UART" depends on SERIAL_8250 depends on OF - depends on REGMAP && MFD_SYSCON + depends on MFD_SYSCON depends on ARCH_ASPEED || COMPILE_TEST + select REGMAP help If you want to use the virtual UART (VUART) device on Aspeed BMC platforms, enable this option. This enables the 16550A- From cfeda9432c1dd0b33d006fc3cca21d69ff47c49b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 6 Mar 2023 11:32:42 +0100 Subject: [PATCH 0860/1017] drm/sun4i: fix missing component unbind on bind errors [ Upstream commit c22f2ff8724b49dce2ae797e9fbf4bc0fa91112f ] Make sure to unbind all subcomponents when binding the aggregate device fails. Fixes: 9026e0d122ac ("drm: Add Allwinner A10 Display Engine support") Cc: stable@vger.kernel.org # 4.7 Cc: Maxime Ripard Signed-off-by: Johan Hovold Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20230306103242.4775-1-johan+linaro@kernel.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/sun4i/sun4i_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index c5912fd53772..9c6ae8cfa0b2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -93,7 +93,7 @@ static int sun4i_drv_bind(struct device *dev) /* drm_vblank_init calls kcalloc, which can fail */ ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret) - goto cleanup_mode_config; + goto unbind_all; drm->irq_enabled = true; @@ -117,6 +117,8 @@ static int sun4i_drv_bind(struct device *dev) finish_poll: drm_kms_helper_poll_fini(drm); +unbind_all: + component_unbind_all(dev, NULL); cleanup_mode_config: drm_mode_config_cleanup(drm); of_reserved_mem_device_release(dev); From 1fde5782f187daa05919d2bebd872df8ebcc00d1 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Thu, 23 Mar 2023 05:03:22 +0000 Subject: [PATCH 0861/1017] net: tls: fix possible race condition between do_tls_getsockopt_conf() and do_tls_setsockopt_conf() commit 49c47cc21b5b7a3d8deb18fc57b0aa2ab1286962 upstream. ctx->crypto_send.info is not protected by lock_sock in do_tls_getsockopt_conf(). A race condition between do_tls_getsockopt_conf() and error paths of do_tls_setsockopt_conf() may lead to a use-after-free or null-deref. More discussion: https://lore.kernel.org/all/Y/ht6gQL+u6fj3dG@hog/ Fixes: 3c4d7559159b ("tls: kernel TLS support") Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20230228023344.9623-1-hbh25y@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Meena Shanmugam Signed-off-by: Sasha Levin --- net/tls/tls_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index e537085b184f..54863e68f304 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -386,13 +386,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval, rc = -EINVAL; goto out; } - lock_sock(sk); memcpy(crypto_info_aes_gcm_128->iv, cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, TLS_CIPHER_AES_GCM_128_IV_SIZE); memcpy(crypto_info_aes_gcm_128->rec_seq, cctx->rec_seq, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - release_sock(sk); if (copy_to_user(optval, crypto_info_aes_gcm_128, sizeof(*crypto_info_aes_gcm_128))) @@ -410,13 +408,11 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval, rc = -EINVAL; goto out; } - lock_sock(sk); memcpy(crypto_info_aes_gcm_256->iv, cctx->iv + TLS_CIPHER_AES_GCM_256_SALT_SIZE, TLS_CIPHER_AES_GCM_256_IV_SIZE); memcpy(crypto_info_aes_gcm_256->rec_seq, cctx->rec_seq, TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); - release_sock(sk); if (copy_to_user(optval, crypto_info_aes_gcm_256, sizeof(*crypto_info_aes_gcm_256))) @@ -436,6 +432,8 @@ static int do_tls_getsockopt(struct sock *sk, int optname, { int rc = 0; + lock_sock(sk); + switch (optname) { case TLS_TX: case TLS_RX: @@ -446,6 +444,9 @@ static int do_tls_getsockopt(struct sock *sk, int optname, rc = -ENOPROTOOPT; break; } + + release_sock(sk); + return rc; } From 18359b8e30c4f190398ae2bf41c9f07c78e4367a Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Tue, 12 Apr 2022 08:30:44 +0000 Subject: [PATCH 0862/1017] power: supply: bq24190_charger: using pm_runtime_resume_and_get instead of pm_runtime_get_sync [ Upstream commit d96a89407e5f682d1cb22569d91784506c784863 ] Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Sebastian Reichel Stable-dep-of: 47c29d692129 ("power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition") Signed-off-by: Sasha Levin --- drivers/power/supply/bq24190_charger.c | 63 +++++++++----------------- 1 file changed, 21 insertions(+), 42 deletions(-) diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 8c3c378dce0d..81389fcc73e1 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -448,11 +448,9 @@ static ssize_t bq24190_sysfs_show(struct device *dev, if (!info) return -EINVAL; - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v); if (ret) @@ -483,11 +481,9 @@ static ssize_t bq24190_sysfs_store(struct device *dev, if (ret < 0) return ret; - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v); if (ret) @@ -506,10 +502,9 @@ static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val) struct bq24190_dev_info *bdi = rdev_get_drvdata(dev); int ret; - ret = pm_runtime_get_sync(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); if (ret < 0) { dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); - pm_runtime_put_noidle(bdi->dev); return ret; } @@ -539,10 +534,9 @@ static int bq24190_vbus_is_enabled(struct regulator_dev *dev) int ret; u8 val; - ret = pm_runtime_get_sync(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); if (ret < 0) { dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); - pm_runtime_put_noidle(bdi->dev); return ret; } @@ -1083,11 +1077,9 @@ static int bq24190_charger_get_property(struct power_supply *psy, dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_CHARGE_TYPE: @@ -1157,11 +1149,9 @@ static int bq24190_charger_set_property(struct power_supply *psy, dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_ONLINE: @@ -1420,11 +1410,9 @@ static int bq24190_battery_get_property(struct power_supply *psy, dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_STATUS: @@ -1468,11 +1456,9 @@ static int bq24190_battery_set_property(struct power_supply *psy, dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_ONLINE: @@ -1626,10 +1612,9 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) int error; bdi->irq_event = true; - error = pm_runtime_get_sync(bdi->dev); + error = pm_runtime_resume_and_get(bdi->dev); if (error < 0) { dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); return IRQ_NONE; } bq24190_check_status(bdi); @@ -1849,11 +1834,9 @@ static int bq24190_remove(struct i2c_client *client) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); - } bq24190_register_reset(bdi); if (bdi->battery) @@ -1902,11 +1885,9 @@ static __maybe_unused int bq24190_pm_suspend(struct device *dev) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); - } bq24190_register_reset(bdi); @@ -1927,11 +1908,9 @@ static __maybe_unused int bq24190_pm_resume(struct device *dev) bdi->f_reg = 0; bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); - } bq24190_register_reset(bdi); bq24190_set_config(bdi); From 2b346876b93168541a45551d5f9abd1d26102e89 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Fri, 10 Mar 2023 01:47:28 +0800 Subject: [PATCH 0863/1017] power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition [ Upstream commit 47c29d69212911f50bdcdd0564b5999a559010d4 ] In bq24190_probe, &bdi->input_current_limit_work is bound with bq24190_input_current_limit_work. When external power changed, it will call bq24190_charger_external_power_changed to start the work. If we remove the module which will call bq24190_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows: CPU0 CPUc1 |bq24190_input_current_limit_work bq24190_remove | power_supply_unregister | device_unregister | power_supply_dev_release| kfree(psy) | | | power_supply_get_property_from_supplier | //use Fix it by finishing the work before cleanup in the bq24190_remove Fixes: 97774672573a ("power_supply: Initialize changed_work before calling device_add") Signed-off-by: Zheng Wang Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/bq24190_charger.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 81389fcc73e1..338dd82007e4 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -1834,6 +1834,7 @@ static int bq24190_remove(struct i2c_client *client) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; + cancel_delayed_work_sync(&bdi->input_current_limit_work); error = pm_runtime_resume_and_get(bdi->dev); if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); From 75e2144291e847009fbc0350e10ec588ff96e05a Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Sun, 12 Mar 2023 01:46:50 +0800 Subject: [PATCH 0864/1017] power: supply: da9150: Fix use after free bug in da9150_charger_remove due to race condition [ Upstream commit 06615d11cc78162dfd5116efb71f29eb29502d37 ] In da9150_charger_probe, &charger->otg_work is bound with da9150_charger_otg_work. da9150_charger_otg_ncb may be called to start the work. If we remove the module which will call da9150_charger_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows: Fix it by canceling the work before cleanup in the da9150_charger_remove CPU0 CPUc1 |da9150_charger_otg_work da9150_charger_remove | power_supply_unregister | device_unregister | power_supply_dev_release| kfree(psy) | | | power_supply_changed(charger->usb); | //use Fixes: c1a281e34dae ("power: Add support for DA9150 Charger") Signed-off-by: Zheng Wang Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/da9150-charger.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/supply/da9150-charger.c b/drivers/power/supply/da9150-charger.c index f9314cc0cd75..6b987da58655 100644 --- a/drivers/power/supply/da9150-charger.c +++ b/drivers/power/supply/da9150-charger.c @@ -662,6 +662,7 @@ static int da9150_charger_remove(struct platform_device *pdev) if (!IS_ERR_OR_NULL(charger->usb_phy)) usb_unregister_notifier(charger->usb_phy, &charger->otg_nb); + cancel_work_sync(&charger->otg_work); power_supply_unregister(charger->battery); power_supply_unregister(charger->usb); From 35a49d27585ccafb8d449c666f9620a739538a0f Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 26 Feb 2023 21:12:13 +0800 Subject: [PATCH 0865/1017] ARM: dts: imx6sll: e60k02: fix usbotg1 pinctrl [ Upstream commit 957c04e9784c7c757e8cc293d7fb2a60cdf461b6 ] usb@2184000: 'pinctrl-0' is a dependency of 'pinctrl-names' Signed-off-by: Peng Fan Fixes: c100ea86e6ab ("ARM: dts: add Netronix E60K02 board common file") Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/e60k02.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/e60k02.dtsi b/arch/arm/boot/dts/e60k02.dtsi index 3af1ab4458ef..bd1f58ae2374 100644 --- a/arch/arm/boot/dts/e60k02.dtsi +++ b/arch/arm/boot/dts/e60k02.dtsi @@ -296,6 +296,7 @@ &usbotg1 { pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1>; disable-over-current; srp-disable; hnp-disable; From 7b5dffe048f925a528c83e12331ebe635c12562d Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 26 Feb 2023 21:12:14 +0800 Subject: [PATCH 0866/1017] ARM: dts: imx6sl: tolino-shine2hd: fix usbotg1 pinctrl [ Upstream commit 1cd489e1ada1cffa56bd06fd4609f5a60a985d43 ] usb@2184000: 'pinctrl-0' is a dependency of 'pinctrl-names' Signed-off-by: Peng Fan Fixes: 9c7016f1ca6d ("ARM: dts: imx: add devicetree for Tolino Shine 2 HD") Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts b/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts index caa279608803..0fd126db4e5d 100644 --- a/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts +++ b/arch/arm/boot/dts/imx6sl-tolino-shine2hd.dts @@ -580,6 +580,7 @@ &usbotg1 { pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1>; disable-over-current; srp-disable; hnp-disable; From 580634b03a55f04a3c1968bcbd97736c079c6601 Mon Sep 17 00:00:00 2001 From: Kal Conley Date: Wed, 8 Mar 2023 18:40:13 +0100 Subject: [PATCH 0867/1017] xsk: Add missing overflow check in xdp_umem_reg [ Upstream commit c7df4813b149362248d6ef7be41a311e27bf75fe ] The number of chunks can overflow u32. Make sure to return -EINVAL on overflow. Also remove a redundant u32 cast assigning umem->npgs. Fixes: bbff2f321a86 ("xsk: new descriptor addressing scheme") Signed-off-by: Kal Conley Signed-off-by: Daniel Borkmann Acked-by: Magnus Karlsson Link: https://lore.kernel.org/bpf/20230308174013.1114745-1-kal.conley@dectris.com Signed-off-by: Sasha Levin --- net/xdp/xdp_umem.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c index 56a28a686988..42b19feb2b6e 100644 --- a/net/xdp/xdp_umem.c +++ b/net/xdp/xdp_umem.c @@ -153,10 +153,11 @@ static int xdp_umem_account_pages(struct xdp_umem *umem) static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) { - u32 npgs_rem, chunk_size = mr->chunk_size, headroom = mr->headroom; bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG; - u64 npgs, addr = mr->addr, size = mr->len; - unsigned int chunks, chunks_rem; + u32 chunk_size = mr->chunk_size, headroom = mr->headroom; + u64 addr = mr->addr, size = mr->len; + u32 chunks_rem, npgs_rem; + u64 chunks, npgs; int err; if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) { @@ -191,8 +192,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) if (npgs > U32_MAX) return -EINVAL; - chunks = (unsigned int)div_u64_rem(size, chunk_size, &chunks_rem); - if (chunks == 0) + chunks = div_u64_rem(size, chunk_size, &chunks_rem); + if (!chunks || chunks > U32_MAX) return -EINVAL; if (!unaligned_chunks && chunks_rem) @@ -205,7 +206,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr) umem->headroom = headroom; umem->chunk_size = chunk_size; umem->chunks = chunks; - umem->npgs = (u32)npgs; + umem->npgs = npgs; umem->pgs = NULL; umem->user = NULL; umem->flags = mr->flags; From 15dcb57eba09ca3f84033af1e961dde24e2dcb14 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Wed, 1 Mar 2023 12:59:07 +0100 Subject: [PATCH 0868/1017] iavf: fix inverted Rx hash condition leading to disabled hash [ Upstream commit 32d57f667f871bc5a8babbe27ea4c5e668ee0ea8 ] Condition, which checks whether the netdev has hashing enabled is inverted. Basically, the tagged commit effectively disabled passing flow hash from descriptor to skb, unless user *disables* it via Ethtool. Commit a876c3ba59a6 ("i40e/i40evf: properly report Rx packet hash") fixed this problem, but only for i40e. Invert the condition now in iavf and unblock passing hash to skbs again. Fixes: 857942fd1aa1 ("i40e: Fix Rx hash reported to the stack by our driver") Reviewed-by: Larysa Zaremba Reviewed-by: Michal Kubiak Signed-off-by: Alexander Lobakin Tested-by: Rafal Romanowski Reviewed-by: Leon Romanovsky Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/iavf/iavf_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c index d481a922f018..f411e683eb15 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c +++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c @@ -1061,7 +1061,7 @@ static inline void iavf_rx_hash(struct iavf_ring *ring, cpu_to_le64((u64)IAVF_RX_DESC_FLTSTAT_RSS_HASH << IAVF_RX_DESC_STATUS_FLTSTAT_SHIFT); - if (ring->netdev->features & NETIF_F_RXHASH) + if (!(ring->netdev->features & NETIF_F_RXHASH)) return; if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) { From 155d6d434f86bcbae985171c1c398c11f393950d Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Wed, 1 Mar 2023 12:59:08 +0100 Subject: [PATCH 0869/1017] iavf: fix non-tunneled IPv6 UDP packet type and hashing [ Upstream commit de58647b4301fe181f9c38e8b46f7021584ae427 ] Currently, IAVF's decode_rx_desc_ptype() correctly reports payload type of L4 for IPv4 UDP packets and IPv{4,6} TCP, but only L3 for IPv6 UDP. Originally, i40e, ice and iavf were affected. Commit 73df8c9e3e3d ("i40e: Correct UDP packet header for non_tunnel-ipv6") fixed that in i40e, then commit 638a0c8c8861 ("ice: fix incorrect payload indicator on PTYPE") fixed that for ice. IPv6 UDP is L4 obviously. Fix it and make iavf report correct L4 hash type for such packets, so that the stack won't calculate it on CPU when needs it. Fixes: 206812b5fccb ("i40e/i40evf: i40e implementation for skb_set_hash") Reviewed-by: Larysa Zaremba Reviewed-by: Michal Kubiak Signed-off-by: Alexander Lobakin Tested-by: Rafal Romanowski Reviewed-by: Leon Romanovsky Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/iavf/iavf_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/iavf/iavf_common.c b/drivers/net/ethernet/intel/iavf/iavf_common.c index 8547fc8fdfd6..78423ca401b2 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_common.c +++ b/drivers/net/ethernet/intel/iavf/iavf_common.c @@ -662,7 +662,7 @@ struct iavf_rx_ptype_decoded iavf_ptype_lookup[] = { /* Non Tunneled IPv6 */ IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), - IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY3), + IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4), IAVF_PTT_UNUSED_ENTRY(91), IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), From fe3850c72a722e9efe18b4ec384b0fa0c09ac053 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Tue, 22 Nov 2022 10:28:52 +0800 Subject: [PATCH 0870/1017] intel/igbvf: free irq on the error path in igbvf_request_msix() [ Upstream commit 85eb39bb39cbb5c086df1e19ba67cc1366693a77 ] In igbvf_request_msix(), irqs have not been freed on the err path, we need to free it. Fix it. Fixes: d4e0fe01a38a ("igbvf: add new driver to support 82576 virtual functions") Signed-off-by: Gaosheng Cui Reviewed-by: Maciej Fijalkowski Tested-by: Marek Szlosek Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/igbvf/netdev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index fe8c0a26b720..037ec90ed56c 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -1074,7 +1074,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) igbvf_intr_msix_rx, 0, adapter->rx_ring->name, netdev); if (err) - goto out; + goto free_irq_tx; adapter->rx_ring->itr_register = E1000_EITR(vector); adapter->rx_ring->itr_val = adapter->current_itr; @@ -1083,10 +1083,14 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) err = request_irq(adapter->msix_entries[vector].vector, igbvf_msix_other, 0, netdev->name, netdev); if (err) - goto out; + goto free_irq_rx; igbvf_configure_msix(adapter); return 0; +free_irq_rx: + free_irq(adapter->msix_entries[--vector].vector, netdev); +free_irq_tx: + free_irq(adapter->msix_entries[--vector].vector, netdev); out: return err; } From d3e4844c1829646a0945318bf342f18b64715509 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 1 Dec 2022 19:20:03 +0900 Subject: [PATCH 0871/1017] igbvf: Regard vf reset nack as success [ Upstream commit 02c83791ef969c6a8a150b4927193d0d0e50fb23 ] vf reset nack actually represents the reset operation itself is performed but no address is assigned. Therefore, e1000_reset_hw_vf should fill the "perm_addr" with the zero address and return success on such an occasion. This prevents its callers in netdev.c from saying PF still resetting, and instead allows them to correctly report that no address is assigned. Fixes: 6ddbc4cf1f4d ("igb: Indicate failure on vf reset for empty mac address") Signed-off-by: Akihiko Odaki Reviewed-by: Leon Romanovsky Tested-by: Marek Szlosek Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/igbvf/vf.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/igbvf/vf.c b/drivers/net/ethernet/intel/igbvf/vf.c index b8ba3f94c363..a47a2e3e548c 100644 --- a/drivers/net/ethernet/intel/igbvf/vf.c +++ b/drivers/net/ethernet/intel/igbvf/vf.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2009 - 2018 Intel Corporation. */ +#include + #include "vf.h" static s32 e1000_check_for_link_vf(struct e1000_hw *hw); @@ -131,11 +133,16 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw) /* set our "perm_addr" based on info provided by PF */ ret_val = mbx->ops.read_posted(hw, msgbuf, 3); if (!ret_val) { - if (msgbuf[0] == (E1000_VF_RESET | - E1000_VT_MSGTYPE_ACK)) + switch (msgbuf[0]) { + case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK: memcpy(hw->mac.perm_addr, addr, ETH_ALEN); - else + break; + case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK: + eth_zero_addr(hw->mac.perm_addr); + break; + default: ret_val = -E1000_ERR_MAC_INIT; + } } } From bde2e73d5232cb52003197a5c5e05b61f720d000 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 7 Mar 2023 15:45:31 +0900 Subject: [PATCH 0872/1017] igc: fix the validation logic for taprio's gate list [ Upstream commit 2b4cc3d3f4d8ec42961e98568a0afeee96a943ab ] The check introduced in the commit a5fd39464a40 ("igc: Lift TAPRIO schedule restriction") can detect a false positive error in some corner case. For instance, tc qdisc replace ... taprio num_tc 4 ... sched-entry S 0x01 100000 # slot#1 sched-entry S 0x03 100000 # slot#2 sched-entry S 0x04 100000 # slot#3 sched-entry S 0x08 200000 # slot#4 flags 0x02 # hardware offload Here the queue#0 (the first queue) is on at the slot#1 and #2, and off at the slot#3 and #4. Under the current logic, when the slot#4 is examined, validate_schedule() returns *false* since the enablement count for the queue#0 is two and it is already off at the previous slot (i.e. #3). But this definition is truely correct. Let's fix the logic to enforce a strict validation for consecutively-opened slots. Fixes: a5fd39464a40 ("igc: Lift TAPRIO schedule restriction") Signed-off-by: AKASHI Takahiro Reviewed-by: Kurt Kanzenbach Acked-by: Vinicius Costa Gomes Tested-by: Naama Meir Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/igc/igc_main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 1a0aae7b128d..3aa0efb542aa 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4874,18 +4874,18 @@ static bool validate_schedule(struct igc_adapter *adapter, if (e->command != TC_TAPRIO_CMD_SET_GATES) return false; - for (i = 0; i < adapter->num_tx_queues; i++) { - if (e->gate_mask & BIT(i)) + for (i = 0; i < adapter->num_tx_queues; i++) + if (e->gate_mask & BIT(i)) { queue_uses[i]++; - /* There are limitations: A single queue cannot be - * opened and closed multiple times per cycle unless the - * gate stays open. Check for it. - */ - if (queue_uses[i] > 1 && - !(prev->gate_mask & BIT(i))) - return false; - } + /* There are limitations: A single queue cannot + * be opened and closed multiple times per cycle + * unless the gate stays open. Check for it. + */ + if (queue_uses[i] > 1 && + !(prev->gate_mask & BIT(i))) + return false; + } } return true; From a3ada13f20fd018fce7b5867e9805ee69ee01b83 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Mon, 30 Jan 2023 16:32:47 +0100 Subject: [PATCH 0873/1017] i2c: imx-lpi2c: check only for enabled interrupt flags [ Upstream commit 1c7885004567e8951d65a983be095f254dd20bef ] When reading from I2C, the Tx watermark is set to 0. Unfortunately the TDF (transmit data flag) is enabled when Tx FIFO entries is equal or less than watermark. So it is set in every case, hence the reset default of 1. This results in the MSR_RDF _and_ MSR_TDF flags to be set thus trying to send Tx data on a read message. Mask the IRQ status to filter for wanted flags only. Fixes: a55fa9d0e42e ("i2c: imx-lpi2c: add low power i2c bus driver") Signed-off-by: Alexander Stein Tested-by: Emanuele Ghidoli Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-imx-lpi2c.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 8b9ba055c418..2018dbcf241e 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -502,10 +502,14 @@ disable: static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id) { struct lpi2c_imx_struct *lpi2c_imx = dev_id; + unsigned int enabled; unsigned int temp; + enabled = readl(lpi2c_imx->base + LPI2C_MIER); + lpi2c_imx_intctrl(lpi2c_imx, 0); temp = readl(lpi2c_imx->base + LPI2C_MSR); + temp &= enabled; if (temp & MSR_RDF) lpi2c_imx_read_rxfifo(lpi2c_imx); From c09cdf6eb815ee35e55d6c50ac7f63db58bd20b8 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Wed, 15 Mar 2023 14:21:54 +0800 Subject: [PATCH 0874/1017] scsi: scsi_dh_alua: Fix memleak for 'qdata' in alua_activate() [ Upstream commit a13faca032acbf2699293587085293bdfaafc8ae ] If alua_rtpg_queue() failed from alua_activate(), then 'qdata' is not freed, which will cause following memleak: unreferenced object 0xffff88810b2c6980 (size 32): comm "kworker/u16:2", pid 635322, jiffies 4355801099 (age 1216426.076s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 40 39 24 c1 ff ff ff ff 00 f8 ea 0a 81 88 ff ff @9$............. backtrace: [<0000000098f3a26d>] alua_activate+0xb0/0x320 [<000000003b529641>] scsi_dh_activate+0xb2/0x140 [<000000007b296db3>] activate_path_work+0xc6/0xe0 [dm_multipath] [<000000007adc9ace>] process_one_work+0x3c5/0x730 [<00000000c457a985>] worker_thread+0x93/0x650 [<00000000cb80e628>] kthread+0x1ba/0x210 [<00000000a1e61077>] ret_from_fork+0x22/0x30 Fix the problem by freeing 'qdata' in error path. Fixes: 625fe857e4fa ("scsi: scsi_dh_alua: Check scsi_device_get() return value") Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20230315062154.668812-1-yukuai1@huaweicloud.com Reviewed-by: Benjamin Block Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index fe8a5e5c0df8..bf0b3178f84d 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -1036,10 +1036,12 @@ static int alua_activate(struct scsi_device *sdev, rcu_read_unlock(); mutex_unlock(&h->init_mutex); - if (alua_rtpg_queue(pg, sdev, qdata, true)) + if (alua_rtpg_queue(pg, sdev, qdata, true)) { fn = NULL; - else + } else { + kfree(qdata); err = SCSI_DH_DEV_OFFLINED; + } kref_put(&pg->kref, release_port_group); out: if (fn) From 33d1603a38e05886c538129ddfe00bd52d347e7b Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Thu, 16 Mar 2023 11:19:54 +0100 Subject: [PATCH 0875/1017] net: usb: smsc95xx: Limit packet length to skb->len [ Upstream commit ff821092cf02a70c2bccd2d19269f01e29aa52cf ] Packet length retrieved from descriptor may be larger than the actual socket buffer length. In such case the cloned skb passed up the network stack will leak kernel memory contents. Fixes: 2f7ca802bdae ("net: Add SMSC LAN9500 USB2.0 10/100 ethernet adapter driver") Signed-off-by: Szymon Heidrich Reviewed-by: Jakub Kicinski Link: https://lore.kernel.org/r/20230316101954.75836-1-szymon.heidrich@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/usb/smsc95xx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index e1cd4c2de2d3..975f52605867 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1824,6 +1824,12 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) size = (u16)((header & RX_STS_FL_) >> 16); align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; + if (unlikely(size > skb->len)) { + netif_dbg(dev, rx_err, dev->net, + "size err header=0x%08x\n", header); + return 0; + } + if (unlikely(header & RX_STS_ES_)) { netif_dbg(dev, rx_err, dev->net, "Error header=0x%08x\n", header); From 39c3b9dd481c3afce9439b29bafe00444cb4406b Mon Sep 17 00:00:00 2001 From: Daniil Tatianin Date: Thu, 16 Mar 2023 13:29:21 +0300 Subject: [PATCH 0876/1017] qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info [ Upstream commit 25143b6a01d0cc5319edd3de22ffa2578b045550 ] We have to make sure that the info returned by the helper is valid before using it. Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Fixes: f990c82c385b ("qed*: Add support for ndo_set_vf_trust") Fixes: 733def6a04bf ("qed*: IOV link control") Signed-off-by: Daniil Tatianin Reviewed-by: Michal Swiatkowski Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/qlogic/qed/qed_sriov.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c index 3541bc95493f..b2a2beb84e54 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -4378,6 +4378,9 @@ qed_iov_configure_min_tx_rate(struct qed_dev *cdev, int vfid, u32 rate) } vf = qed_iov_get_vf_info(QED_LEADING_HWFN(cdev), (u16)vfid, true); + if (!vf) + return -EINVAL; + vport_id = vf->vport_id; return qed_configure_vport_wfq(cdev, vport_id, rate); @@ -5123,7 +5126,7 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn) /* Validate that the VF has a configured vport */ vf = qed_iov_get_vf_info(hwfn, i, true); - if (!vf->vport_instance) + if (!vf || !vf->vport_instance) continue; memset(¶ms, 0, sizeof(params)); From bfeeb3aaad4ee8eaaefe5d9edd9b2ccb5d9b7505 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Fri, 17 Mar 2023 00:15:26 +0800 Subject: [PATCH 0877/1017] xirc2ps_cs: Fix use after free bug in xirc2ps_detach [ Upstream commit e8d20c3ded59a092532513c9bd030d1ea66f5f44 ] In xirc2ps_probe, the local->tx_timeout_task was bounded with xirc2ps_tx_timeout_task. When timeout occurs, it will call xirc_tx_timeout->schedule_work to start the work. When we call xirc2ps_detach to remove the driver, there may be a sequence as follows: Stop responding to timeout tasks and complete scheduled tasks before cleanup in xirc2ps_detach, which will fix the problem. CPU0 CPU1 |xirc2ps_tx_timeout_task xirc2ps_detach | free_netdev | kfree(dev); | | | do_reset | //use dev Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Zheng Wang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/xircom/xirc2ps_cs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c index 3e337142b516..56cef59c1c87 100644 --- a/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -503,6 +503,11 @@ static void xirc2ps_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; + struct local_info *local = netdev_priv(dev); + + netif_carrier_off(dev); + netif_tx_disable(dev); + cancel_work_sync(&local->tx_timeout_task); dev_dbg(&link->dev, "detach\n"); From 1b333766ea7a65ee779dd7b91ad3325d1526db7e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 16 Mar 2023 13:33:24 -0700 Subject: [PATCH 0878/1017] net: phy: Ensure state transitions are processed from phy_stop() [ Upstream commit 4203d84032e28f893594a453bd8bc9c3b15c7334 ] In the phy_disconnect() -> phy_stop() path, we will be forcibly setting the PHY state machine to PHY_HALTED. This invalidates the old_state != phydev->state condition in phy_state_machine() such that we will neither display the state change for debugging, nor will we invoke the link_change_notify() callback. Factor the code by introducing phy_process_state_change(), and ensure that we process the state change from phy_stop() as well. Fixes: 5c5f626bcace ("net: phy: improve handling link_change_notify callback") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/phy/phy.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 18e67eb6d8b4..f3e606b6617e 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -56,6 +56,18 @@ static const char *phy_state_to_str(enum phy_state st) return NULL; } +static void phy_process_state_change(struct phy_device *phydev, + enum phy_state old_state) +{ + if (old_state != phydev->state) { + phydev_dbg(phydev, "PHY state change %s -> %s\n", + phy_state_to_str(old_state), + phy_state_to_str(phydev->state)); + if (phydev->drv && phydev->drv->link_change_notify) + phydev->drv->link_change_notify(phydev); + } +} + static void phy_link_up(struct phy_device *phydev) { phydev->phy_link_change(phydev, true); @@ -1110,6 +1122,7 @@ EXPORT_SYMBOL(phy_free_interrupt); void phy_stop(struct phy_device *phydev) { struct net_device *dev = phydev->attached_dev; + enum phy_state old_state; if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) { WARN(1, "called from state %s\n", @@ -1118,6 +1131,7 @@ void phy_stop(struct phy_device *phydev) } mutex_lock(&phydev->lock); + old_state = phydev->state; if (phydev->state == PHY_CABLETEST) { phy_abort_cable_test(phydev); @@ -1128,6 +1142,7 @@ void phy_stop(struct phy_device *phydev) sfp_upstream_stop(phydev->sfp_bus); phydev->state = PHY_HALTED; + phy_process_state_change(phydev, old_state); mutex_unlock(&phydev->lock); @@ -1242,13 +1257,7 @@ void phy_state_machine(struct work_struct *work) if (err < 0) phy_error(phydev); - if (old_state != phydev->state) { - phydev_dbg(phydev, "PHY state change %s -> %s\n", - phy_state_to_str(old_state), - phy_state_to_str(phydev->state)); - if (phydev->drv && phydev->drv->link_change_notify) - phydev->drv->link_change_notify(phydev); - } + phy_process_state_change(phydev, old_state); /* Only re-schedule a PHY state machine change if we are polling the * PHY, if PHY_IGNORE_INTERRUPT is set, then we will be moving From d04dac7fae7580dce0cd9b55db6e1ad4e8d26157 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Thu, 16 Mar 2023 16:33:16 -0700 Subject: [PATCH 0879/1017] net: mdio: fix owner field for mdio buses registered using device-tree [ Upstream commit 99669259f3361d759219811e670b7e0742668556 ] Bus ownership is wrong when using of_mdiobus_register() to register an mdio bus. That function is not inline, so when it calls mdiobus_register() the wrong THIS_MODULE value is captured. Signed-off-by: Maxime Bizon Fixes: 90eff9096c01 ("net: phy: Allow splitting MDIO bus/device support from PHYs") [florian: fix kdoc, added Fixes tag] Signed-off-by: Florian Fainelli Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/mdio/of_mdio.c | 12 +++++++----- drivers/net/phy/mdio_devres.c | 11 ++++++----- include/linux/of_mdio.h | 22 +++++++++++++++++++--- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index 5bae47f3da40..b254127cea50 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -238,21 +238,23 @@ bool of_mdiobus_child_is_phy(struct device_node *child) EXPORT_SYMBOL(of_mdiobus_child_is_phy); /** - * of_mdiobus_register - Register mii_bus and create PHYs from the device tree + * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure * @np: pointer to device_node of MDIO bus. + * @owner: module owning the @mdio object. * * This function registers the mii_bus structure and registers a phy_device * for each child node of @np. */ -int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) +int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, + struct module *owner) { struct device_node *child; bool scanphys = false; int addr, rc; if (!np) - return mdiobus_register(mdio); + return __mdiobus_register(mdio, owner); /* Do not continue if the node is disabled */ if (!of_device_is_available(np)) @@ -272,7 +274,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us); /* Register the MDIO bus */ - rc = mdiobus_register(mdio); + rc = __mdiobus_register(mdio, owner); if (rc) return rc; @@ -336,7 +338,7 @@ unregister: mdiobus_unregister(mdio); return rc; } -EXPORT_SYMBOL(of_mdiobus_register); +EXPORT_SYMBOL(__of_mdiobus_register); /** * of_mdio_find_device - Given a device tree node, find the mdio_device diff --git a/drivers/net/phy/mdio_devres.c b/drivers/net/phy/mdio_devres.c index b560e99695df..69b829e6ab35 100644 --- a/drivers/net/phy/mdio_devres.c +++ b/drivers/net/phy/mdio_devres.c @@ -98,13 +98,14 @@ EXPORT_SYMBOL(__devm_mdiobus_register); #if IS_ENABLED(CONFIG_OF_MDIO) /** - * devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register() + * __devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register() * @dev: Device to register mii_bus for * @mdio: MII bus structure to register * @np: Device node to parse + * @owner: Owning module */ -int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, - struct device_node *np) +int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, + struct device_node *np, struct module *owner) { struct mdiobus_devres *dr; int ret; @@ -117,7 +118,7 @@ int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, if (!dr) return -ENOMEM; - ret = of_mdiobus_register(mdio, np); + ret = __of_mdiobus_register(mdio, np, owner); if (ret) { devres_free(dr); return ret; @@ -127,7 +128,7 @@ int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, devres_add(dev, dr); return 0; } -EXPORT_SYMBOL(devm_of_mdiobus_register); +EXPORT_SYMBOL(__devm_of_mdiobus_register); #endif /* CONFIG_OF_MDIO */ MODULE_LICENSE("GPL"); diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index f56c6a9230ac..8cc6522ee43a 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -14,9 +14,25 @@ #if IS_ENABLED(CONFIG_OF_MDIO) bool of_mdiobus_child_is_phy(struct device_node *child); -int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np); -int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, - struct device_node *np); +int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, + struct module *owner); + +static inline int of_mdiobus_register(struct mii_bus *mdio, + struct device_node *np) +{ + return __of_mdiobus_register(mdio, np, THIS_MODULE); +} + +int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, + struct device_node *np, struct module *owner); + +static inline int devm_of_mdiobus_register(struct device *dev, + struct mii_bus *mdio, + struct device_node *np) +{ + return __devm_of_mdiobus_register(dev, mdio, np, THIS_MODULE); +} + struct mdio_device *of_mdio_find_device(struct device_node *np); struct phy_device *of_phy_find_device(struct device_node *phy_np); struct phy_device * From cb5879efde4f9b4de4248b835890df7b6c49ffbc Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Sat, 18 Mar 2023 16:05:26 +0800 Subject: [PATCH 0880/1017] net: qcom/emac: Fix use after free bug in emac_remove due to race condition [ Upstream commit 6b6bc5b8bd2d4ca9e1efa9ae0f98a0b0687ace75 ] In emac_probe, &adpt->work_thread is bound with emac_work_thread. Then it will be started by timeout handler emac_tx_timeout or a IRQ handler emac_isr. If we remove the driver which will call emac_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows: Fix it by finishing the work before cleanup in the emac_remove and disable timeout response. CPU0 CPU1 |emac_work_thread emac_remove | free_netdev | kfree(netdev); | |emac_reinit_locked |emac_mac_down |//use netdev Fixes: b9b17debc69d ("net: emac: emac gigabit ethernet controller driver") Signed-off-by: Zheng Wang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/qualcomm/emac/emac.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index ad655f0a4965..e1aa56be9cc0 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -728,9 +728,15 @@ static int emac_remove(struct platform_device *pdev) struct net_device *netdev = dev_get_drvdata(&pdev->dev); struct emac_adapter *adpt = netdev_priv(netdev); + netif_carrier_off(netdev); + netif_tx_disable(netdev); + unregister_netdev(netdev); netif_napi_del(&adpt->rx_q.napi); + free_irq(adpt->irq.irq, &adpt->irq); + cancel_work_sync(&adpt->work_thread); + emac_clks_teardown(adpt); put_device(&adpt->phydev->mdio.dev); From 3d5a97283e2aa00687399afef2a19e310081e202 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 18 Mar 2023 17:39:16 +0000 Subject: [PATCH 0881/1017] net/ps3_gelic_net: Fix RX sk_buff length [ Upstream commit 19b3bb51c3bc288b3f2c6f8c4450b0f548320625 ] The Gelic Ethernet device needs to have the RX sk_buffs aligned to GELIC_NET_RXBUF_ALIGN, and also the length of the RX sk_buffs must be a multiple of GELIC_NET_RXBUF_ALIGN. The current Gelic Ethernet driver was not allocating sk_buffs large enough to allow for this alignment. Also, correct the maximum and minimum MTU sizes, and add a new preprocessor macro for the maximum frame size, GELIC_NET_MAX_FRAME. Fixes various randomly occurring runtime network errors. Fixes: 02c1889166b4 ("ps3: gigabit ethernet driver for PS3, take3") Signed-off-by: Geoff Levand Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 19 ++++++++++--------- drivers/net/ethernet/toshiba/ps3_gelic_net.h | 5 +++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c index d9a5722f561b..013011285dd0 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -365,26 +365,27 @@ iommu_error: * * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. * Activate the descriptor state-wise + * + * Gelic RX sk_buffs must be aligned to GELIC_NET_RXBUF_ALIGN and the length + * must be a multiple of GELIC_NET_RXBUF_ALIGN. */ static int gelic_descr_prepare_rx(struct gelic_card *card, struct gelic_descr *descr) { + static const unsigned int rx_skb_size = + ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) + + GELIC_NET_RXBUF_ALIGN - 1; int offset; - unsigned int bufsize; if (gelic_descr_get_status(descr) != GELIC_DESCR_DMA_NOT_IN_USE) dev_info(ctodev(card), "%s: ERROR status\n", __func__); - /* we need to round up the buffer size to a multiple of 128 */ - bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN); - /* and we need to have it 128 byte aligned, therefore we allocate a - * bit more */ - descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1); + descr->skb = netdev_alloc_skb(*card->netdev, rx_skb_size); if (!descr->skb) { descr->buf_addr = 0; /* tell DMAC don't touch memory */ return -ENOMEM; } - descr->buf_size = cpu_to_be32(bufsize); + descr->buf_size = cpu_to_be32(rx_skb_size); descr->dmac_cmd_status = 0; descr->result_size = 0; descr->valid_size = 0; @@ -397,7 +398,7 @@ static int gelic_descr_prepare_rx(struct gelic_card *card, /* io-mmu-map the skb */ descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card), descr->skb->data, - GELIC_NET_MAX_MTU, + GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE)); if (!descr->buf_addr) { dev_kfree_skb_any(descr->skb); @@ -915,7 +916,7 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, data_error = be32_to_cpu(descr->data_error); /* unmap skb buffer */ dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), - GELIC_NET_MAX_MTU, + GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE); skb_put(skb, be32_to_cpu(descr->valid_size)? diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.h b/drivers/net/ethernet/toshiba/ps3_gelic_net.h index 68f324ed4eaf..0d98defb011e 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.h +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.h @@ -19,8 +19,9 @@ #define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */ #define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */ -#define GELIC_NET_MAX_MTU VLAN_ETH_FRAME_LEN -#define GELIC_NET_MIN_MTU VLAN_ETH_ZLEN +#define GELIC_NET_MAX_FRAME 2312 +#define GELIC_NET_MAX_MTU 2294 +#define GELIC_NET_MIN_MTU 64 #define GELIC_NET_RXBUF_ALIGN 128 #define GELIC_CARD_RX_CSUM_DEFAULT 1 /* hw chksum */ #define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ From 56e0bc4a72a09761ce438c0b38f5263a51582660 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 18 Mar 2023 17:39:16 +0000 Subject: [PATCH 0882/1017] net/ps3_gelic_net: Use dma_mapping_error [ Upstream commit bebe933d35a63d4f042fbf4dce4f22e689ba0fcd ] The current Gelic Etherenet driver was checking the return value of its dma_map_single call, and not using the dma_mapping_error() routine. Fixes runtime problems like these: DMA-API: ps3_gelic_driver sb_05: device driver failed to check map error WARNING: CPU: 0 PID: 0 at kernel/dma/debug.c:1027 .check_unmap+0x888/0x8dc Fixes: 02c1889166b4 ("ps3: gigabit ethernet driver for PS3, take3") Reviewed-by: Alexander Duyck Signed-off-by: Geoff Levand Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/toshiba/ps3_gelic_net.c | 26 +++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c index 013011285dd0..524098a7b658 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -317,15 +317,17 @@ static int gelic_card_init_chain(struct gelic_card *card, /* set up the hardware pointers in each descriptor */ for (i = 0; i < no; i++, descr++) { - gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); - descr->bus_addr = - dma_map_single(ctodev(card), descr, - GELIC_DESCR_SIZE, - DMA_BIDIRECTIONAL); + dma_addr_t cpu_addr; - if (!descr->bus_addr) + gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); + + cpu_addr = dma_map_single(ctodev(card), descr, + GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL); + + if (dma_mapping_error(ctodev(card), cpu_addr)) goto iommu_error; + descr->bus_addr = cpu_to_be32(cpu_addr); descr->next = descr + 1; descr->prev = descr - 1; } @@ -375,6 +377,7 @@ static int gelic_descr_prepare_rx(struct gelic_card *card, static const unsigned int rx_skb_size = ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) + GELIC_NET_RXBUF_ALIGN - 1; + dma_addr_t cpu_addr; int offset; if (gelic_descr_get_status(descr) != GELIC_DESCR_DMA_NOT_IN_USE) @@ -396,11 +399,10 @@ static int gelic_descr_prepare_rx(struct gelic_card *card, if (offset) skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset); /* io-mmu-map the skb */ - descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card), - descr->skb->data, - GELIC_NET_MAX_FRAME, - DMA_FROM_DEVICE)); - if (!descr->buf_addr) { + cpu_addr = dma_map_single(ctodev(card), descr->skb->data, + GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE); + descr->buf_addr = cpu_to_be32(cpu_addr); + if (dma_mapping_error(ctodev(card), cpu_addr)) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; dev_info(ctodev(card), @@ -780,7 +782,7 @@ static int gelic_descr_prepare_tx(struct gelic_card *card, buf = dma_map_single(ctodev(card), skb->data, skb->len, DMA_TO_DEVICE); - if (!buf) { + if (dma_mapping_error(ctodev(card), buf)) { dev_err(ctodev(card), "dma map 2 failed (%p, %i). Dropping packet\n", skb->data, skb->len); From ec23a669decaef2d9531b8c5e1f5d2ea5b85c55e Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Wed, 15 Mar 2023 22:54:08 +0900 Subject: [PATCH 0883/1017] bootconfig: Fix testcase to increase max node [ Upstream commit b69245126a48e50882021180fa5d264dc7149ccc ] Since commit 6c40624930c5 ("bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC support") increased the max number of bootconfig node to 8192, the bootconfig testcase of the max number of nodes fails. To fix this issue, we can not simply increase the number in the test script because the test bootconfig file becomes too big (>32KB). To fix that, we can use a combination of three alphabets (26^3 = 17576). But with that, we can not express the 8193 (just one exceed from the limitation) because it also exceeds the max size of bootconfig. So, the first 26 nodes will just use one alphabet. With this fix, test-bootconfig.sh passes all tests. Link: https://lore.kernel.org/all/167888844790.791176.670805252426835131.stgit@devnote2/ Reported-by: Heinz Wiesinger Link: https://lore.kernel.org/all/2463802.XAFRqVoOGU@amaterasu.liwjatan.org Fixes: 6c40624930c5 ("bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC support") Signed-off-by: Masami Hiramatsu (Google) Reviewed-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- tools/bootconfig/test-bootconfig.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/bootconfig/test-bootconfig.sh b/tools/bootconfig/test-bootconfig.sh index baed891d0ba4..e36f178f7dcb 100755 --- a/tools/bootconfig/test-bootconfig.sh +++ b/tools/bootconfig/test-bootconfig.sh @@ -87,10 +87,14 @@ xfail grep -i "error" $OUTFILE echo "Max node number check" -echo -n > $TEMPCONF -for i in `seq 1 1024` ; do - echo "node$i" >> $TEMPCONF -done +awk ' +BEGIN { + for (i = 0; i < 26; i += 1) + printf("%c\n", 65 + i % 26) + for (i = 26; i < 8192; i += 1) + printf("%c%c%c\n", 65 + i % 26, 65 + (i / 26) % 26, 65 + (i / 26 / 26)) +} +' > $TEMPCONF xpass $BOOTCONF -a $TEMPCONF $INITRD echo "badnode" >> $TEMPCONF From a44e98abcca49e3d6af4f0c9b6fcfc0e98039d99 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 14 Mar 2023 15:15:18 +0000 Subject: [PATCH 0884/1017] keys: Do not cache key in task struct if key is requested from kernel thread [ Upstream commit 47f9e4c924025c5be87959d3335e66fcbb7f6b5c ] The key which gets cached in task structure from a kernel thread does not get invalidated even after expiry. Due to which, a new key request from kernel thread will be served with the cached key if it's present in task struct irrespective of the key validity. The change is to not cache key in task_struct when key requested from kernel thread so that kernel thread gets a valid key on every key request. The problem has been seen with the cifs module doing DNS lookups from a kernel thread and the results getting pinned by being attached to that kernel thread's cache - and thus not something that can be easily got rid of. The cache would ordinarily be cleared by notify-resume, but kernel threads don't do that. This isn't seen with AFS because AFS is doing request_key() within the kernel half of a user thread - which will do notify-resume. Fixes: 7743c48e54ee ("keys: Cache result of request_key*() temporarily in task_struct") Signed-off-by: Bharath SM Signed-off-by: David Howells Reviewed-by: Jarkko Sakkinen cc: Shyam Prasad N cc: Steve French cc: keyrings@vger.kernel.org cc: linux-cifs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/CAGypqWw951d=zYRbdgNR4snUDvJhWL=q3=WOyh7HhSJupjz2vA@mail.gmail.com/ Signed-off-by: Sasha Levin --- security/keys/request_key.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 2da4404276f0..07a0ef2baacd 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -38,9 +38,12 @@ static void cache_requested_key(struct key *key) #ifdef CONFIG_KEYS_REQUEST_CACHE struct task_struct *t = current; - key_put(t->cached_requested_key); - t->cached_requested_key = key_get(key); - set_tsk_thread_flag(t, TIF_NOTIFY_RESUME); + /* Do not cache key if it is a kernel thread */ + if (!(t->flags & PF_KTHREAD)) { + key_put(t->cached_requested_key); + t->cached_requested_key = key_get(key); + set_tsk_thread_flag(t, TIF_NOTIFY_RESUME); + } #endif } From a4bbab27c4bf69486f5846d44134eb31c37e9b22 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 20 Mar 2023 15:37:25 +0100 Subject: [PATCH 0885/1017] bpf: Adjust insufficient default bpf_jit_limit [ Upstream commit 10ec8ca8ec1a2f04c4ed90897225231c58c124a7 ] We've seen recent AWS EKS (Kubernetes) user reports like the following: After upgrading EKS nodes from v20230203 to v20230217 on our 1.24 EKS clusters after a few days a number of the nodes have containers stuck in ContainerCreating state or liveness/readiness probes reporting the following error: Readiness probe errored: rpc error: code = Unknown desc = failed to exec in container: failed to start exec "4a11039f730203ffc003b7[...]": OCI runtime exec failed: exec failed: unable to start container process: unable to init seccomp: error loading seccomp filter into kernel: error loading seccomp filter: errno 524: unknown However, we had not been seeing this issue on previous AMIs and it only started to occur on v20230217 (following the upgrade from kernel 5.4 to 5.10) with no other changes to the underlying cluster or workloads. We tried the suggestions from that issue (sysctl net.core.bpf_jit_limit=452534528) which helped to immediately allow containers to be created and probes to execute but after approximately a day the issue returned and the value returned by cat /proc/vmallocinfo | grep bpf_jit | awk '{s+=$2} END {print s}' was steadily increasing. I tested bpf tree to observe bpf_jit_charge_modmem, bpf_jit_uncharge_modmem their sizes passed in as well as bpf_jit_current under tcpdump BPF filter, seccomp BPF and native (e)BPF programs, and the behavior all looks sane and expected, that is nothing "leaking" from an upstream perspective. The bpf_jit_limit knob was originally added in order to avoid a situation where unprivileged applications loading BPF programs (e.g. seccomp BPF policies) consuming all the module memory space via BPF JIT such that loading of kernel modules would be prevented. The default limit was defined back in 2018 and while good enough back then, we are generally seeing far more BPF consumers today. Adjust the limit for the BPF JIT pool from originally 1/4 to now 1/2 of the module memory space to better reflect today's needs and avoid more users running into potentially hard to debug issues. Fixes: fdadd04931c2 ("bpf: fix bpf_jit_limit knob for PAGE_SIZE >= 64K") Reported-by: Stephen Haynes Reported-by: Lefteris Alexakis Signed-off-by: Daniel Borkmann Link: https://github.com/awslabs/amazon-eks-ami/issues/1179 Link: https://github.com/awslabs/amazon-eks-ami/issues/1219 Reviewed-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20230320143725.8394-1-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- kernel/bpf/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 73d4b1e32fbd..d3f6a070875c 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -826,7 +826,7 @@ static int __init bpf_jit_charge_init(void) { /* Only used as heuristic here to derive limit. */ bpf_jit_limit_max = bpf_jit_alloc_exec_limit(); - bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 2, + bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 1, PAGE_SIZE), LONG_MAX); return 0; } From 18cead61e437f4c7898acca0a5f3df12f801d97f Mon Sep 17 00:00:00 2001 From: Lama Kayal Date: Tue, 31 Jan 2023 14:07:03 +0200 Subject: [PATCH 0886/1017] net/mlx5: Fix steering rules cleanup [ Upstream commit 922f56e9a795d6f3dd72d3428ebdd7ee040fa855 ] vport's mc, uc and multicast rules are not deleted in teardown path when EEH happens. Since the vport's promisc settings(uc, mc and all) in firmware are reset after EEH, mlx5 driver will try to delete the above rules in the initialization path. This cause kernel crash because these software rules are no longer valid. Fix by nullifying these rules right after delete to avoid accessing any dangling pointers. Call Trace: __list_del_entry_valid+0xcc/0x100 (unreliable) tree_put_node+0xf4/0x1b0 [mlx5_core] tree_remove_node+0x30/0x70 [mlx5_core] mlx5_del_flow_rules+0x14c/0x1f0 [mlx5_core] esw_apply_vport_rx_mode+0x10c/0x200 [mlx5_core] esw_update_vport_rx_mode+0xb4/0x180 [mlx5_core] esw_vport_change_handle_locked+0x1ec/0x230 [mlx5_core] esw_enable_vport+0x130/0x260 [mlx5_core] mlx5_eswitch_enable_sriov+0x2a0/0x2f0 [mlx5_core] mlx5_device_enable_sriov+0x74/0x440 [mlx5_core] mlx5_load_one+0x114c/0x1550 [mlx5_core] mlx5_pci_resume+0x68/0xf0 [mlx5_core] eeh_report_resume+0x1a4/0x230 eeh_pe_dev_traverse+0x98/0x170 eeh_handle_normal_event+0x3e4/0x640 eeh_handle_event+0x4c/0x370 eeh_event_handler+0x14c/0x210 kthread+0x168/0x1b0 ret_from_kernel_thread+0x5c/0x84 Fixes: a35f71f27a61 ("net/mlx5: E-Switch, Implement promiscuous rx modes vf request handling") Signed-off-by: Huy Nguyen Signed-off-by: Lama Kayal Reviewed-by: Tariq Toukan Reviewed-by: Maor Dickman Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 78cc6f0bbc72..3ae082c72a2b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1339,6 +1339,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, u16 vport_num) */ esw_vport_change_handle_locked(vport); vport->enabled_events = 0; + esw_apply_vport_rx_mode(esw, vport, false, false); esw_vport_cleanup(esw, vport); esw->enabled_vports--; From 265101aea4c0939f4f916412d0c5469a088f2b7c Mon Sep 17 00:00:00 2001 From: Maher Sanalla Date: Wed, 15 Mar 2023 11:04:38 +0200 Subject: [PATCH 0887/1017] net/mlx5: Read the TC mapping of all priorities on ETS query [ Upstream commit 44d553188c38ac74b799dfdcebafef2f7bb70942 ] When ETS configurations are queried by the user to get the mapping assignment between packet priority and traffic class, only priorities up to maximum TCs are queried from QTCT register in FW to retrieve their assigned TC, leaving the rest of the priorities mapped to the default TC #0 which might be misleading. Fix by querying the TC mapping of all priorities on each ETS query, regardless of the maximum number of TCs configured in FW. Fixes: 820c2c5e773d ("net/mlx5e: Read ETS settings directly from firmware") Signed-off-by: Maher Sanalla Reviewed-by: Moshe Shemesh Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index 7c0ae7c38eef..c25fb0cbde27 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -117,12 +117,14 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev, if (!MLX5_CAP_GEN(priv->mdev, ets)) return -EOPNOTSUPP; - ets->ets_cap = mlx5_max_tc(priv->mdev) + 1; - for (i = 0; i < ets->ets_cap; i++) { + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]); if (err) return err; + } + ets->ets_cap = mlx5_max_tc(priv->mdev) + 1; + for (i = 0; i < ets->ets_cap; i++) { err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]); if (err) return err; From 5eadc80328298ef7beaaf0cd96791667d3b485ca Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 27 Feb 2023 14:16:10 +0300 Subject: [PATCH 0888/1017] net/mlx5: E-Switch, Fix an Oops in error handling code [ Upstream commit 640fcdbcf27fc62de9223f958ceb4e897a00e791 ] The error handling dereferences "vport". There is nothing we can do if it is an error pointer except returning the error code. Fixes: 133dcfc577ea ("net/mlx5: E-Switch, Alloc and free unique metadata for match") Signed-off-by: Dan Carpenter Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed Signed-off-by: Sasha Levin --- drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c index 548c005ea633..90a10230bf0c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c @@ -301,8 +301,7 @@ int mlx5_esw_acl_ingress_vport_bond_update(struct mlx5_eswitch *esw, u16 vport_n if (WARN_ON_ONCE(IS_ERR(vport))) { esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num); - err = PTR_ERR(vport); - goto out; + return PTR_ERR(vport); } esw_acl_ingress_ofld_rules_destroy(esw, vport); From 19aa85b9df487801bfb2d14281797d72d1830e6f Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Mon, 20 Mar 2023 14:33:18 +0000 Subject: [PATCH 0889/1017] atm: idt77252: fix kmemleak when rmmod idt77252 [ Upstream commit 4fe3c88552a3fbe1944426a4506a18cdeb457b5a ] There are memory leaks reported by kmemleak: unreferenced object 0xffff888106500800 (size 128): comm "modprobe", pid 1017, jiffies 4297787785 (age 67.152s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000970ce626>] __kmem_cache_alloc_node+0x20c/0x380 [<00000000fb5f78d9>] kmalloc_trace+0x2f/0xb0 [<000000000e947e2a>] idt77252_init_one+0x2847/0x3c90 [idt77252] [<000000006efb048e>] local_pci_probe+0xeb/0x1a0 ... unreferenced object 0xffff888106500b00 (size 128): comm "modprobe", pid 1017, jiffies 4297787785 (age 67.152s) hex dump (first 32 bytes): 00 20 3d 01 80 88 ff ff 00 20 3d 01 80 88 ff ff . =...... =..... f0 23 3d 01 80 88 ff ff 00 20 3d 01 00 00 00 00 .#=...... =..... backtrace: [<00000000970ce626>] __kmem_cache_alloc_node+0x20c/0x380 [<00000000fb5f78d9>] kmalloc_trace+0x2f/0xb0 [<00000000f451c5be>] alloc_scq.constprop.0+0x4a/0x400 [idt77252] [<00000000e6313849>] idt77252_init_one+0x28cf/0x3c90 [idt77252] The root cause is traced to the vc_maps which alloced in open_card_oam() are not freed in close_card_oam(). The vc_maps are used to record open connections, so when close a vc_map in close_card_oam(), the memory should be freed. Moreover, the ubr0 is not closed when close a idt77252 device, leading to the memory leak of vc_map and scq_info. Fix them by adding kfree in close_card_oam() and implementing new close_card_ubr0() to close ubr0. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Li Zetao Reviewed-by: Francois Romieu Link: https://lore.kernel.org/r/20230320143318.2644630-1-lizetao1@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/atm/idt77252.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 82f6f1fbe9e7..a217b50439e7 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -2915,6 +2915,7 @@ close_card_oam(struct idt77252_dev *card) recycle_rx_pool_skb(card, &vc->rcv.rx_pool); } + kfree(vc); } } } @@ -2958,6 +2959,15 @@ open_card_ubr0(struct idt77252_dev *card) return 0; } +static void +close_card_ubr0(struct idt77252_dev *card) +{ + struct vc_map *vc = card->vcs[0]; + + free_scq(card, vc->scq); + kfree(vc); +} + static int idt77252_dev_open(struct idt77252_dev *card) { @@ -3007,6 +3017,7 @@ static void idt77252_dev_close(struct atm_dev *dev) struct idt77252_dev *card = dev->dev_data; u32 conf; + close_card_ubr0(card); close_card_oam(card); conf = SAR_CFG_RXPTH | /* enable receive path */ From f8cec30541f5c5cc218e9a32138d45d227727f2f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 20 Mar 2023 16:34:27 +0000 Subject: [PATCH 0890/1017] erspan: do not use skb_mac_header() in ndo_start_xmit() [ Upstream commit 8e50ed774554f93d55426039b27b1e38d7fa64d8 ] Drivers should not assume skb_mac_header(skb) == skb->data in their ndo_start_xmit(). Use skb_network_offset() and skb_transport_offset() which better describe what is needed in erspan_fb_xmit() and ip6erspan_tunnel_xmit() syzbot reported: WARNING: CPU: 0 PID: 5083 at include/linux/skbuff.h:2873 skb_mac_header include/linux/skbuff.h:2873 [inline] WARNING: CPU: 0 PID: 5083 at include/linux/skbuff.h:2873 ip6erspan_tunnel_xmit+0x1d9c/0x2d90 net/ipv6/ip6_gre.c:962 Modules linked in: CPU: 0 PID: 5083 Comm: syz-executor406 Not tainted 6.3.0-rc2-syzkaller-00866-gd4671cb96fa3 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/02/2023 RIP: 0010:skb_mac_header include/linux/skbuff.h:2873 [inline] RIP: 0010:ip6erspan_tunnel_xmit+0x1d9c/0x2d90 net/ipv6/ip6_gre.c:962 Code: 04 02 41 01 de 84 c0 74 08 3c 03 0f 8e 1c 0a 00 00 45 89 b4 24 c8 00 00 00 c6 85 77 fe ff ff 01 e9 33 e7 ff ff e8 b4 27 a1 f8 <0f> 0b e9 b6 e7 ff ff e8 a8 27 a1 f8 49 8d bf f0 0c 00 00 48 b8 00 RSP: 0018:ffffc90003b2f830 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 000000000000ffff RCX: 0000000000000000 RDX: ffff888021273a80 RSI: ffffffff88e1bd4c RDI: 0000000000000003 RBP: ffffc90003b2f9d8 R08: 0000000000000003 R09: 000000000000ffff R10: 000000000000ffff R11: 0000000000000000 R12: ffff88802b28da00 R13: 00000000000000d0 R14: ffff88807e25b6d0 R15: ffff888023408000 FS: 0000555556a61300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055e5b11eb6e8 CR3: 0000000027c1b000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: __netdev_start_xmit include/linux/netdevice.h:4900 [inline] netdev_start_xmit include/linux/netdevice.h:4914 [inline] __dev_direct_xmit+0x504/0x730 net/core/dev.c:4300 dev_direct_xmit include/linux/netdevice.h:3088 [inline] packet_xmit+0x20a/0x390 net/packet/af_packet.c:285 packet_snd net/packet/af_packet.c:3075 [inline] packet_sendmsg+0x31a0/0x5150 net/packet/af_packet.c:3107 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0xde/0x190 net/socket.c:747 __sys_sendto+0x23a/0x340 net/socket.c:2142 __do_sys_sendto net/socket.c:2154 [inline] __se_sys_sendto net/socket.c:2150 [inline] __x64_sys_sendto+0xe1/0x1b0 net/socket.c:2150 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f123aaa1039 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 b1 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc15d12058 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f123aaa1039 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 0000000000000000 R08: 0000000020000040 R09: 0000000000000014 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f123aa648c0 R13: 431bde82d7b634db R14: 0000000000000000 R15: 0000000000000000 Fixes: 1baf5ebf8954 ("erspan: auto detect truncated packets.") Reported-by: syzbot Signed-off-by: Eric Dumazet Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230320163427.8096-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/ip_gre.c | 4 ++-- net/ipv6/ip6_gre.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 65ead8a74933..9d1a50657104 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -547,7 +547,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) truncate = true; } - nhoff = skb_network_header(skb) - skb_mac_header(skb); + nhoff = skb_network_offset(skb); if (skb->protocol == htons(ETH_P_IP) && (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff)) truncate = true; @@ -556,7 +556,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) int thoff; if (skb_transport_header_was_set(skb)) - thoff = skb_transport_header(skb) - skb_mac_header(skb); + thoff = skb_transport_offset(skb); else thoff = nhoff + sizeof(struct ipv6hdr); if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 0010f9e54f13..2332b5b81c55 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -959,7 +959,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, truncate = true; } - nhoff = skb_network_header(skb) - skb_mac_header(skb); + nhoff = skb_network_offset(skb); if (skb->protocol == htons(ETH_P_IP) && (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff)) truncate = true; @@ -968,7 +968,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, int thoff; if (skb_transport_header_was_set(skb)) - thoff = skb_transport_header(skb) - skb_mac_header(skb); + thoff = skb_transport_offset(skb); else thoff = nhoff + sizeof(struct ipv6hdr); if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff) From 73db80dcdc20aceda0c6251f6b1289d7ae297b0d Mon Sep 17 00:00:00 2001 From: Zhang Changzhong Date: Tue, 21 Mar 2023 14:45:43 +1100 Subject: [PATCH 0891/1017] net/sonic: use dma_mapping_error() for error check [ Upstream commit 4107b8746d93ace135b8c4da4f19bbae81db785f ] The DMA address returned by dma_map_single() should be checked with dma_mapping_error(). Fix it accordingly. Fixes: efcce839360f ("[PATCH] macsonic/jazzsonic network drivers update") Signed-off-by: Zhang Changzhong Tested-by: Stan Johnson Signed-off-by: Finn Thain Reviewed-by: Leon Romanovsky Link: https://lore.kernel.org/r/6645a4b5c1e364312103f48b7b36783b94e197a2.1679370343.git.fthain@linux-m68k.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/natsemi/sonic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c index d17d1b4f2585..825356ee3492 100644 --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -292,7 +292,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) */ laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE); - if (!laddr) { + if (dma_mapping_error(lp->device, laddr)) { pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name); dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -509,7 +509,7 @@ static bool sonic_alloc_rb(struct net_device *dev, struct sonic_local *lp, *new_addr = dma_map_single(lp->device, skb_put(*new_skb, SONIC_RBSIZE), SONIC_RBSIZE, DMA_FROM_DEVICE); - if (!*new_addr) { + if (dma_mapping_error(lp->device, *new_addr)) { dev_kfree_skb(*new_skb); *new_skb = NULL; return false; From 3c72445dadc33fd5ab44b3987a8c59b62da6f3b1 Mon Sep 17 00:00:00 2001 From: Caleb Sander Date: Mon, 20 Mar 2023 09:57:36 -0600 Subject: [PATCH 0892/1017] nvme-tcp: fix nvme_tcp_term_pdu to match spec [ Upstream commit aa01c67de5926fdb276793180564f172c55fb0d7 ] The FEI field of C2HTermReq/H2CTermReq is 4 bytes but not 4-byte-aligned in the NVMe/TCP specification (it is located at offset 10 in the PDU). Split it into two 16-bit integers in struct nvme_tcp_term_pdu so no padding is inserted. There should also be 10 reserved bytes after. There are currently no users of this type. Fixes: fc221d05447aa6db ("nvme-tcp: Add protocol header") Reported-by: Geert Uytterhoeven Signed-off-by: Caleb Sander Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- include/linux/nvme-tcp.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/nvme-tcp.h b/include/linux/nvme-tcp.h index 959e0bd9a913..73364ae91689 100644 --- a/include/linux/nvme-tcp.h +++ b/include/linux/nvme-tcp.h @@ -114,8 +114,9 @@ struct nvme_tcp_icresp_pdu { struct nvme_tcp_term_pdu { struct nvme_tcp_hdr hdr; __le16 fes; - __le32 fei; - __u8 rsvd[8]; + __le16 feil; + __le16 feiu; + __u8 rsvd[10]; }; /** From 94ef1715d263ba3b19c55effc22e890af6bd262b Mon Sep 17 00:00:00 2001 From: Joshua Washington Date: Tue, 21 Mar 2023 10:23:32 -0700 Subject: [PATCH 0893/1017] gve: Cache link_speed value from device [ Upstream commit 68c3e4fc8628b1487c965aabb29207249657eb5f ] The link speed is never changed for the uptime of a VM, and the current implementation sends an admin queue command for each call. Admin queue command invocations have nontrivial overhead (e.g., VM exits), which can be disruptive to users if triggered frequently. Our telemetry data shows that there are VMs that make frequent calls to this admin queue command. Caching the result of the original admin queue command would eliminate the need to send multiple admin queue commands on subsequent calls to retrieve link speed. Fixes: 7e074d5a76ca ("gve: Enable Link Speed Reporting in the driver.") Signed-off-by: Joshua Washington Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230321172332.91678-1-joshwash@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/google/gve/gve_ethtool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c index c53a04313944..e0449cc24fbd 100644 --- a/drivers/net/ethernet/google/gve/gve_ethtool.c +++ b/drivers/net/ethernet/google/gve/gve_ethtool.c @@ -510,7 +510,10 @@ static int gve_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd) { struct gve_priv *priv = netdev_priv(netdev); - int err = gve_adminq_report_link_speed(priv); + int err = 0; + + if (priv->link_speed == 0) + err = gve_adminq_report_link_speed(priv); cmd->base.speed = priv->link_speed; return err; From 7aa3d03e1b308b4e8d640d11f516741bc4e81c99 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 22 Mar 2023 14:20:57 +0800 Subject: [PATCH 0894/1017] net: mdio: thunder: Add missing fwnode_handle_put() [ Upstream commit b1de5c78ebe9858ccec9d49af2f76724f1d47e3e ] In device_for_each_child_node(), we should add fwnode_handle_put() when break out of the iteration device_for_each_child_node() as it will automatically increase and decrease the refcounter. Fixes: 379d7ac7ca31 ("phy: mdio-thunder: Add driver for Cavium Thunder SoC MDIO buses.") Signed-off-by: Liang He Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/mdio/mdio-thunder.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/mdio/mdio-thunder.c b/drivers/net/mdio/mdio-thunder.c index 822d2cdd2f35..394b864aaa37 100644 --- a/drivers/net/mdio/mdio-thunder.c +++ b/drivers/net/mdio/mdio-thunder.c @@ -104,6 +104,7 @@ static int thunder_mdiobus_pci_probe(struct pci_dev *pdev, if (i >= ARRAY_SIZE(nexus->buses)) break; } + fwnode_handle_put(fwn); return 0; err_release_regions: From 65ceb170749b65292bb70406c74cd6dd6afcc013 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 8 Mar 2023 14:31:55 +0100 Subject: [PATCH 0895/1017] Bluetooth: btqcomsmd: Fix command timeout after setting BD address [ Upstream commit 5d44ab9e204200a78ad55cdf185aa2bb109b5950 ] On most devices using the btqcomsmd driver (e.g. the DragonBoard 410c and other devices based on the Qualcomm MSM8916/MSM8909/... SoCs) the Bluetooth firmware seems to become unresponsive for a while after setting the BD address. On recent kernel versions (at least 5.17+) this often causes timeouts for subsequent commands, e.g. the HCI reset sent by the Bluetooth core during initialization: Bluetooth: hci0: Opcode 0x c03 failed: -110 Unfortunately this behavior does not seem to be documented anywhere. Experimentation suggests that the minimum necessary delay to avoid the problem is ~150us. However, to be sure add a sleep for > 1ms in case it is a bit longer on other firmware versions. Older kernel versions are likely also affected, although perhaps with slightly different errors or less probability. Side effects can easily hide the issue in most cases, e.g. unrelated incoming interrupts that cause the necessary delay. Fixes: 1511cc750c3d ("Bluetooth: Introduce Qualcomm WCNSS SMD based HCI driver") Signed-off-by: Stephan Gerhold Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/btqcomsmd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btqcomsmd.c b/drivers/bluetooth/btqcomsmd.c index 2acb719e596f..11c7e04bf394 100644 --- a/drivers/bluetooth/btqcomsmd.c +++ b/drivers/bluetooth/btqcomsmd.c @@ -122,6 +122,21 @@ static int btqcomsmd_setup(struct hci_dev *hdev) return 0; } +static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) +{ + int ret; + + ret = qca_set_bdaddr_rome(hdev, bdaddr); + if (ret) + return ret; + + /* The firmware stops responding for a while after setting the bdaddr, + * causing timeouts for subsequent commands. Sleep a bit to avoid this. + */ + usleep_range(1000, 10000); + return 0; +} + static int btqcomsmd_probe(struct platform_device *pdev) { struct btqcomsmd *btq; @@ -162,7 +177,7 @@ static int btqcomsmd_probe(struct platform_device *pdev) hdev->close = btqcomsmd_close; hdev->send = btqcomsmd_send; hdev->setup = btqcomsmd_setup; - hdev->set_bdaddr = qca_set_bdaddr_rome; + hdev->set_bdaddr = btqcomsmd_set_bdaddr; ret = hci_register_dev(hdev); if (ret < 0) From 77a61df0a0e6cf9495b5524e65ffb32e06000871 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 15 Mar 2021 13:04:37 -0700 Subject: [PATCH 0896/1017] Bluetooth: L2CAP: Fix not checking for maximum number of DCID [ Upstream commit 7cf3b1dd6aa603fd80969e9e7160becf1455a0eb ] When receiving L2CAP_CREDIT_BASED_CONNECTION_REQ the remote may request more channels than allowed by the spec (10 octecs = 5 CIDs) so this checks if the number of channels is bigger than the maximum allowed and respond with an error. Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Marcel Holtmann Stable-dep-of: 9aa9d9473f15 ("Bluetooth: L2CAP: Fix responding with wrong PDU type") Signed-off-by: Sasha Levin --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9b8000869b07..7f9d0ab76b14 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -493,6 +493,7 @@ struct l2cap_le_credits { #define L2CAP_ECRED_MIN_MTU 64 #define L2CAP_ECRED_MIN_MPS 64 +#define L2CAP_ECRED_MAX_CID 5 struct l2cap_ecred_conn_req { __le16 psm; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index bde90df6b497..b01677882e38 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -5952,7 +5952,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, struct l2cap_ecred_conn_req *req = (void *) data; struct { struct l2cap_ecred_conn_rsp rsp; - __le16 dcid[5]; + __le16 dcid[L2CAP_ECRED_MAX_CID]; } __packed pdu; struct l2cap_chan *chan, *pchan; u16 mtu, mps; @@ -5969,6 +5969,14 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, goto response; } + cmd_len -= sizeof(*req); + num_scid = cmd_len / sizeof(u16); + + if (num_scid > ARRAY_SIZE(pdu.dcid)) { + result = L2CAP_CR_LE_INVALID_PARAMS; + goto response; + } + mtu = __le16_to_cpu(req->mtu); mps = __le16_to_cpu(req->mps); @@ -6013,8 +6021,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, } result = L2CAP_CR_LE_SUCCESS; - cmd_len -= sizeof(*req); - num_scid = cmd_len / sizeof(u16); for (i = 0; i < num_scid; i++) { u16 scid = __le16_to_cpu(req->scid[i]); From fce0e47e9ec5afa6123ca403bf2112dae59a9b84 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 8 Mar 2023 14:20:34 -0800 Subject: [PATCH 0897/1017] Bluetooth: L2CAP: Fix responding with wrong PDU type [ Upstream commit 9aa9d9473f1550d1936c31259720b3f1f4690576 ] L2CAP_ECRED_CONN_REQ shall be responded with L2CAP_ECRED_CONN_RSP not L2CAP_LE_CONN_RSP: L2CAP LE EATT Server - Reject - run Listening for connections New client connection with handle 0x002a Sending L2CAP Request from client Client received response code 0x15 Unexpected L2CAP response code (expected 0x18) L2CAP LE EATT Server - Reject - test failed > ACL Data RX: Handle 42 flags 0x02 dlen 26 LE L2CAP: Enhanced Credit Connection Request (0x17) ident 1 len 18 PSM: 39 (0x0027) MTU: 64 MPS: 64 Credits: 5 Source CID: 65 Source CID: 66 Source CID: 67 Source CID: 68 Source CID: 69 < ACL Data TX: Handle 42 flags 0x00 dlen 16 LE L2CAP: LE Connection Response (0x15) ident 1 len 8 invalid size 00 00 00 00 00 00 06 00 L2CAP LE EATT Server - Reject - run Listening for connections New client connection with handle 0x002a Sending L2CAP Request from client Client received response code 0x18 L2CAP LE EATT Server - Reject - test passed Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_core.c | 133 ++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 46 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b01677882e38..367b1dec2e75 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -710,6 +710,17 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) } EXPORT_SYMBOL_GPL(l2cap_chan_del); +static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id, + l2cap_chan_func_t func, void *data) +{ + struct l2cap_chan *chan, *l; + + list_for_each_entry_safe(chan, l, &conn->chan_l, list) { + if (chan->ident == id) + func(chan, data); + } +} + static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func, void *data) { @@ -777,23 +788,9 @@ static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan) { - struct l2cap_conn *conn = chan->conn; - struct l2cap_ecred_conn_rsp rsp; - u16 result; - - if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) - result = L2CAP_CR_LE_AUTHORIZATION; - else - result = L2CAP_CR_LE_BAD_PSM; - l2cap_state_change(chan, BT_DISCONN); - memset(&rsp, 0, sizeof(rsp)); - - rsp.result = cpu_to_le16(result); - - l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), - &rsp); + __l2cap_ecred_conn_rsp_defer(chan); } static void l2cap_chan_connect_reject(struct l2cap_chan *chan) @@ -848,7 +845,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) break; case L2CAP_MODE_EXT_FLOWCTL: l2cap_chan_ecred_connect_reject(chan); - break; + return; } } } @@ -3934,43 +3931,86 @@ void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan) &rsp); } -void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan) +static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data) { - struct { - struct l2cap_ecred_conn_rsp rsp; - __le16 dcid[5]; - } __packed pdu; - struct l2cap_conn *conn = chan->conn; - u16 ident = chan->ident; - int i = 0; + int *result = data; - if (!ident) + if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) return; - BT_DBG("chan %p ident %d", chan, ident); - - pdu.rsp.mtu = cpu_to_le16(chan->imtu); - pdu.rsp.mps = cpu_to_le16(chan->mps); - pdu.rsp.credits = cpu_to_le16(chan->rx_credits); - pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS); - - mutex_lock(&conn->chan_lock); - - list_for_each_entry(chan, &conn->chan_l, list) { - if (chan->ident != ident) - continue; - - /* Reset ident so only one response is sent */ - chan->ident = 0; - - /* Include all channels pending with the same ident */ - pdu.dcid[i++] = cpu_to_le16(chan->scid); + switch (chan->state) { + case BT_CONNECT2: + /* If channel still pending accept add to result */ + (*result)++; + return; + case BT_CONNECTED: + return; + default: + /* If not connected or pending accept it has been refused */ + *result = -ECONNREFUSED; + return; } +} - mutex_unlock(&conn->chan_lock); +struct l2cap_ecred_rsp_data { + struct { + struct l2cap_ecred_conn_rsp rsp; + __le16 scid[L2CAP_ECRED_MAX_CID]; + } __packed pdu; + int count; +}; - l2cap_send_cmd(conn, ident, L2CAP_ECRED_CONN_RSP, - sizeof(pdu.rsp) + i * sizeof(__le16), &pdu); +static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data) +{ + struct l2cap_ecred_rsp_data *rsp = data; + + if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) + return; + + /* Reset ident so only one response is sent */ + chan->ident = 0; + + /* Include all channels pending with the same ident */ + if (!rsp->pdu.rsp.result) + rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid); + else + l2cap_chan_del(chan, ECONNRESET); +} + +void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan) +{ + struct l2cap_conn *conn = chan->conn; + struct l2cap_ecred_rsp_data data; + u16 id = chan->ident; + int result = 0; + + if (!id) + return; + + BT_DBG("chan %p id %d", chan, id); + + memset(&data, 0, sizeof(data)); + + data.pdu.rsp.mtu = cpu_to_le16(chan->imtu); + data.pdu.rsp.mps = cpu_to_le16(chan->mps); + data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits); + data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_SUCCESS); + + /* Verify that all channels are ready */ + __l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result); + + if (result > 0) + return; + + if (result < 0) + data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION); + + /* Build response */ + __l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data); + + l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP, + sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)), + &data.pdu); } void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) @@ -6073,6 +6113,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, __set_chan_timer(chan, chan->ops->get_sndtimeo(chan)); chan->ident = cmd->ident; + chan->mode = L2CAP_MODE_EXT_FLOWCTL; if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { l2cap_state_change(chan, BT_CONNECT2); From da3d3fdfb4d523c5da30e35a8dd90e04f0fd8962 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Thu, 9 Mar 2023 16:07:39 +0800 Subject: [PATCH 0898/1017] Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work [ Upstream commit 1e9ac114c4428fdb7ff4635b45d4f46017e8916f ] In btsdio_probe, &data->work was bound with btsdio_work.In btsdio_send_frame, it was started by schedule_work. If we call btsdio_remove with an unfinished job, there may be a race condition and cause UAF bug on hdev. Fixes: ddbaf13e3609 ("[Bluetooth] Add generic driver for Bluetooth SDIO devices") Signed-off-by: Zheng Wang Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/btsdio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 199e8f7d426d..7050a16e7efe 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -352,6 +352,7 @@ static void btsdio_remove(struct sdio_func *func) BT_DBG("func %p", func); + cancel_work_sync(&data->work); if (!data) return; From f86ff88a1548ccf5a13960c0e7625ca787ea0993 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Fri, 24 Mar 2023 09:06:58 +0800 Subject: [PATCH 0899/1017] platform/chrome: cros_ec_chardev: fix kernel data leak from ioctl [ Upstream commit b20cf3f89c56b5f6a38b7f76a8128bf9f291bbd3 ] It is possible to peep kernel page's data by providing larger `insize` in struct cros_ec_command[1] when invoking EC host commands. Fix it by using zeroed memory. [1]: https://elixir.bootlin.com/linux/v6.2/source/include/linux/platform_data/cros_ec_proto.h#L74 Fixes: eda2e30c6684 ("mfd / platform: cros_ec: Miscellaneous character device to talk with the EC") Signed-off-by: Tzung-Bi Shih Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230324010658.1082361-1-tzungbi@kernel.org Signed-off-by: Sasha Levin --- drivers/platform/chrome/cros_ec_chardev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c index 0de7c255254e..d6de5a294128 100644 --- a/drivers/platform/chrome/cros_ec_chardev.c +++ b/drivers/platform/chrome/cros_ec_chardev.c @@ -284,7 +284,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) u_cmd.insize > EC_MAX_MSG_BYTES) return -EINVAL; - s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), + s_cmd = kzalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), GFP_KERNEL); if (!s_cmd) return -ENOMEM; From 33c2fa39fb9e7b3346e53fba055d5cacf9af6dce Mon Sep 17 00:00:00 2001 From: Phinex Hung Date: Tue, 21 Mar 2023 14:02:23 +0800 Subject: [PATCH 0900/1017] hwmon: fix potential sensor registration fail if of_node is missing [ Upstream commit 2315332efcbe7124252f080e03b57d3d2f1f4771 ] It is not sufficient to check of_node in current device. In some cases, this would cause the sensor registration to fail. This patch looks for device's ancestors to find a valid of_node if any. Fixes: d560168b5d0f ("hwmon: (core) New hwmon registration API") Signed-off-by: Phinex Hung Link: https://lore.kernel.org/r/20230321060224.3819-1-phinex@realtek.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/hwmon.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index d649fea82999..045dc3fd7953 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -700,6 +700,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, { struct hwmon_device *hwdev; struct device *hdev; + struct device *tdev = dev; int i, err, id; /* Complain about invalid characters in hwmon name attribute */ @@ -757,7 +758,9 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, hwdev->name = name; hdev->class = &hwmon_class; hdev->parent = dev; - hdev->of_node = dev ? dev->of_node : NULL; + while (tdev && !tdev->of_node) + tdev = tdev->parent; + hdev->of_node = tdev ? tdev->of_node : NULL; hwdev->chip = chip; dev_set_drvdata(hdev, drvdata); dev_set_name(hdev, HWMON_ID_FORMAT, id); @@ -769,7 +772,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, INIT_LIST_HEAD(&hwdev->tzdata); - if (dev && dev->of_node && chip && chip->ops->read && + if (hdev->of_node && chip && chip->ops->read && chip->info[0]->type == hwmon_chip && (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) { err = hwmon_thermal_register_sensors(hdev); From f73a88df19b7997829fd05ae9bbc62f86541d789 Mon Sep 17 00:00:00 2001 From: Frank Crawford Date: Sat, 18 Mar 2023 19:05:42 +1100 Subject: [PATCH 0901/1017] hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs [ Upstream commit 968b66ffeb7956acc72836a7797aeb7b2444ec51 ] Fix voltage scaling for chips that have 10.9mV ADCs, where scaling was not performed. Fixes: ead8080351c9 ("hwmon: (it87) Add support for IT8732F") Signed-off-by: Frank Crawford Link: https://lore.kernel.org/r/20230318080543.1226700-2-frank@crawford.emu.id.au [groeck: Update subject and description to focus on bug fix] Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/it87.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index fac9b5c68a6a..85413d3dc394 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -486,6 +486,8 @@ static const struct it87_devices it87_devices[] = { #define has_pwm_freq2(data) ((data)->features & FEAT_PWM_FREQ2) #define has_six_temp(data) ((data)->features & FEAT_SIX_TEMP) #define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V) +#define has_scaling(data) ((data)->features & (FEAT_12MV_ADC | \ + FEAT_10_9MV_ADC)) struct it87_sio_data { int sioaddr; @@ -3098,7 +3100,7 @@ static int it87_probe(struct platform_device *pdev) "Detected broken BIOS defaults, disabling PWM interface\n"); /* Starting with IT8721F, we handle scaling of internal voltages */ - if (has_12mv_adc(data)) { + if (has_scaling(data)) { if (sio_data->internal & BIT(0)) data->in_scaled |= BIT(3); /* in3 is AVCC */ if (sio_data->internal & BIT(1)) From 231cfa78ec5badd84a1a2b09465bfad1a926aba1 Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Sun, 12 Mar 2023 21:37:10 -0700 Subject: [PATCH 0902/1017] scsi: qla2xxx: Perform lockless command completion in abort path commit 0367076b0817d5c75dfb83001ce7ce5c64d803a9 upstream. While adding and removing the controller, the following call trace was observed: WARNING: CPU: 3 PID: 623596 at kernel/dma/mapping.c:532 dma_free_attrs+0x33/0x50 CPU: 3 PID: 623596 Comm: sh Kdump: loaded Not tainted 5.14.0-96.el9.x86_64 #1 RIP: 0010:dma_free_attrs+0x33/0x50 Call Trace: qla2x00_async_sns_sp_done+0x107/0x1b0 [qla2xxx] qla2x00_abort_srb+0x8e/0x250 [qla2xxx] ? ql_dbg+0x70/0x100 [qla2xxx] __qla2x00_abort_all_cmds+0x108/0x190 [qla2xxx] qla2x00_abort_all_cmds+0x24/0x70 [qla2xxx] qla2x00_abort_isp_cleanup+0x305/0x3e0 [qla2xxx] qla2x00_remove_one+0x364/0x400 [qla2xxx] pci_device_remove+0x36/0xa0 __device_release_driver+0x17a/0x230 device_release_driver+0x24/0x30 pci_stop_bus_device+0x68/0x90 pci_stop_and_remove_bus_device_locked+0x16/0x30 remove_store+0x75/0x90 kernfs_fop_write_iter+0x11c/0x1b0 new_sync_write+0x11f/0x1b0 vfs_write+0x1eb/0x280 ksys_write+0x5f/0xe0 do_syscall_64+0x5c/0x80 ? do_user_addr_fault+0x1d8/0x680 ? do_syscall_64+0x69/0x80 ? exc_page_fault+0x62/0x140 ? asm_exc_page_fault+0x8/0x30 entry_SYSCALL_64_after_hwframe+0x44/0xae The command was completed in the abort path during driver unload with a lock held, causing the warning in abort path. Hence complete the command without any lock held. Reported-by: Lin Li Tested-by: Lin Li Cc: stable@vger.kernel.org Signed-off-by: Nilesh Javali Link: https://lore.kernel.org/r/20230313043711.13500-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Reviewed-by: John Meneghini Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_os.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e1132970f189..38b8ff87ec0a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1762,6 +1762,17 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { + /* + * perform lockless completion during driver unload + */ + if (qla2x00_chip_is_down(vha)) { + req->outstanding_cmds[cnt] = NULL; + spin_unlock_irqrestore(qp->qp_lock_ptr, flags); + sp->done(sp, res); + spin_lock_irqsave(qp->qp_lock_ptr, flags); + continue; + } + switch (sp->cmd_type) { case TYPE_SRB: qla2x00_abort_srb(qp, sp, res, &flags); From 32fa53c27ea36b62e4444e7e859a5d03f6189d9e Mon Sep 17 00:00:00 2001 From: Yaroslav Furman Date: Sun, 12 Mar 2023 11:07:45 +0200 Subject: [PATCH 0903/1017] uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2 commit a37eb61b6ec064ac794b8a1e89fd33eb582fe51d upstream. Just like other JMicron JMS5xx enclosures, it chokes on report-opcodes, let's avoid them. Signed-off-by: Yaroslav Furman Cc: stable Link: https://lore.kernel.org/r/20230312090745.47962-1-yaro330@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_uas.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index c7b763d6d102..1f8c9b16a0fb 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -111,6 +111,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_BROKEN_FUA), +/* Reported by: Yaroslav Furman */ +UNUSUAL_DEV(0x152d, 0x0583, 0x0000, 0x9999, + "JMicron", + "JMS583Gen 2", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + /* Reported-by: Thinh Nguyen */ UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, "PNY", From 06e04b450bb49f34d859f49c50d6609dd2008f2f Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 27 Dec 2022 11:55:26 +0200 Subject: [PATCH 0904/1017] thunderbolt: Use scale field when allocating USB3 bandwidth commit c82510b1d87bdebfe916048857d2ef46f1778aa5 upstream. When tunneling aggregated USB3 (20 Gb/s) the bandwidth values that are programmed to the ADP_USB3_CS_2 go higher than 4096 and that does not fit anymore to the 12-bit field. Fix this by scaling the value using the scale field accordingly. Fixes: 3b1d8d577ca8 ("thunderbolt: Implement USB3 bandwidth negotiation routines") Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg Signed-off-by: Greg Kroah-Hartman --- drivers/thunderbolt/usb4.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index 0b3a77ade04d..5b45c45e7c5b 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1636,18 +1636,30 @@ static int usb4_usb3_port_write_allocated_bandwidth(struct tb_port *port, int downstream_bw) { u32 val, ubw, dbw, scale; - int ret; + int ret, max_bw; - /* Read the used scale, hardware default is 0 */ - ret = tb_port_read(port, &scale, TB_CFG_PORT, - port->cap_adap + ADP_USB3_CS_3, 1); + /* Figure out suitable scale */ + scale = 0; + max_bw = max(upstream_bw, downstream_bw); + while (scale < 64) { + if (mbps_to_usb3_bw(max_bw, scale) < 4096) + break; + scale++; + } + + if (WARN_ON(scale >= 64)) + return -EINVAL; + + ret = tb_port_write(port, &scale, TB_CFG_PORT, + port->cap_adap + ADP_USB3_CS_3, 1); if (ret) return ret; - scale &= ADP_USB3_CS_3_SCALE_MASK; ubw = mbps_to_usb3_bw(upstream_bw, scale); dbw = mbps_to_usb3_bw(downstream_bw, scale); + tb_port_dbg(port, "scaled bandwidth %u/%u, scale %u\n", ubw, dbw, scale); + ret = tb_port_read(port, &val, TB_CFG_PORT, port->cap_adap + ADP_USB3_CS_2, 1); if (ret) From 2d6c2dee59a396b22fff6d708db4b167281e78c2 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 10 Mar 2023 11:20:49 -0600 Subject: [PATCH 0905/1017] thunderbolt: Use const qualifier for `ring_interrupt_index` commit 1716efdb07938bd6510e1127d02012799112c433 upstream. `ring_interrupt_index` doesn't change the data for `ring` so mark it as const. This is needed by the following patch that disables interrupt auto clear for rings. Cc: Sanju Mehta Cc: stable@vger.kernel.org Signed-off-by: Mario Limonciello Signed-off-by: Mika Westerberg Signed-off-by: Greg Kroah-Hartman --- drivers/thunderbolt/nhi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index db80dc5dfeba..fd1b59397c70 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -36,7 +36,7 @@ #define NHI_MAILBOX_TIMEOUT 500 /* ms */ -static int ring_interrupt_index(struct tb_ring *ring) +static int ring_interrupt_index(const struct tb_ring *ring) { int bit = ring->hop; if (!ring->is_tx) From 082b8240a66af84dd837e48751689e9176feb146 Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Tue, 16 Mar 2021 15:34:20 -0400 Subject: [PATCH 0906/1017] riscv: Bump COMMAND_LINE_SIZE value to 1024 [ Upstream commit 61fc1ee8be26bc192d691932b0a67eabee45d12f ] Increase COMMAND_LINE_SIZE as the current default value is too low for syzbot kernel command line. There has been considerable discussion on this patch that has led to a larger patch set removing COMMAND_LINE_SIZE from the uapi headers on all ports. That's not quite done yet, but it's gotten far enough we're confident this is not a uABI change so this is safe. Reported-by: Dmitry Vyukov Signed-off-by: Alexandre Ghiti Link: https://lore.kernel.org/r/20210316193420.904-1-alex@ghiti.fr [Palmer: it's not uabi] Link: https://lore.kernel.org/linux-riscv/874b8076-b0d1-4aaa-bcd8-05d523060152@app.fastmail.com/#t Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- arch/riscv/include/uapi/asm/setup.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 arch/riscv/include/uapi/asm/setup.h diff --git a/arch/riscv/include/uapi/asm/setup.h b/arch/riscv/include/uapi/asm/setup.h new file mode 100644 index 000000000000..66b13a522880 --- /dev/null +++ b/arch/riscv/include/uapi/asm/setup.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ + +#ifndef _UAPI_ASM_RISCV_SETUP_H +#define _UAPI_ASM_RISCV_SETUP_H + +#define COMMAND_LINE_SIZE 1024 + +#endif /* _UAPI_ASM_RISCV_SETUP_H */ From 3d8fafc5308f7657f93b9514556960936c79917c Mon Sep 17 00:00:00 2001 From: Danny Kaehn Date: Fri, 10 Feb 2023 11:00:44 -0600 Subject: [PATCH 0907/1017] HID: cp2112: Fix driver not registering GPIO IRQ chip as threaded [ Upstream commit 37f5b858a66543b2b67c0288280af623985abc29 ] The CP2112 generates interrupts from a polling routine on a thread, and can only support threaded interrupts. This patch configures the gpiochip irq chip with this flag, disallowing consumers to request a hard IRQ from this driver, which resulted in a segfault previously. Signed-off-by: Danny Kaehn Link: https://lore.kernel.org/r/20230210170044.11835-1-kaehndan@gmail.com Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin --- drivers/hid/hid-cp2112.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index 172f20e88c6c..d902fe43cb81 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c @@ -1352,6 +1352,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id) girq->parents = NULL; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_simple_irq; + girq->threaded = true; ret = gpiochip_add_data(&dev->gc, dev); if (ret < 0) { From 7df72bedbdd1d02bb216e1f6eca0a16900238c4e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Thu, 16 Feb 2023 23:25:04 -0500 Subject: [PATCH 0908/1017] ca8210: fix mac_len negative array access [ Upstream commit 6c993779ea1d0cccdb3a5d7d45446dd229e610a3 ] This patch fixes a buffer overflow access of skb->data if ieee802154_hdr_peek_addrs() fails. Reported-by: lianhui tang Signed-off-by: Alexander Aring Link: https://lore.kernel.org/r/20230217042504.3303396-1-aahringo@redhat.com Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin --- drivers/net/ieee802154/ca8210.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index 95ef3b6f98dd..5beb447529f9 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -1956,6 +1956,8 @@ static int ca8210_skb_tx( * packet */ mac_len = ieee802154_hdr_peek_addrs(skb, &header); + if (mac_len < 0) + return mac_len; secspec.security_level = header.sec.level; secspec.key_id_mode = header.sec.key_id_mode; From df1da53a7e98f0b2a0eb2241c154f148f2f2c1d8 Mon Sep 17 00:00:00 2001 From: Michael Schmitz Date: Wed, 1 Mar 2023 15:11:07 +1300 Subject: [PATCH 0909/1017] m68k: Only force 030 bus error if PC not in exception table [ Upstream commit e36a82bebbf7da814530d5a179bef9df5934b717 ] __get_kernel_nofault() does copy data in supervisor mode when forcing a task backtrace log through /proc/sysrq_trigger. This is expected cause a bus error exception on e.g. NULL pointer dereferencing when logging a kernel task has no workqueue associated. This bus error ought to be ignored. Our 030 bus error handler is ill equipped to deal with this: Whenever ssw indicates a kernel mode access on a data fault, we don't even attempt to handle the fault and instead always send a SEGV signal (or panic). As a result, the check for exception handling at the fault PC (buried in send_sig_fault() which gets called from do_page_fault() eventually) is never used. In contrast, both 040 and 060 access error handlers do not care whether a fault happened on supervisor mode access, and will call do_page_fault() on those, ultimately honoring the exception table. Add a check in bus_error030 to call do_page_fault() in case we do have an entry for the fault PC in our exception table. I had attempted a fix for this earlier in 2019 that did rely on testing pagefault_disabled() (see link below) to achieve the same thing, but this patch should be more generic. Tested on 030 Atari Falcon. Reported-by: Eero Tamminen Link: https://lore.kernel.org/r/alpine.LNX.2.21.1904091023540.25@nippy.intranet Link: https://lore.kernel.org/r/63130691-1984-c423-c1f2-73bfd8d3dcd3@gmail.com Signed-off-by: Michael Schmitz Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230301021107.26307-1-schmitzmic@gmail.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/kernel/traps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index b2a31afb998c..7d42c84649ac 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -549,7 +550,8 @@ static inline void bus_error030 (struct frame *fp) errorcode |= 2; if (mmusr & (MMU_I | MMU_WP)) { - if (ssw & 4) { + /* We might have an exception table for this PC */ + if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) { pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n", ssw & RW ? "read" : "write", fp->un.fmtb.daddr, From 8c42442887db59ac4b67aeaf8825d1192bc783d6 Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Mon, 6 Mar 2023 11:21:38 +0000 Subject: [PATCH 0910/1017] selftests/bpf: check that modifier resolves after pointer [ Upstream commit dfdd608c3b365f0fd49d7e13911ebcde06b9865b ] Add a regression test that ensures that a VAR pointing at a modifier which follows a PTR (or STRUCT or ARRAY) is resolved correctly by the datasec validator. Signed-off-by: Lorenz Bauer Link: https://lore.kernel.org/r/20230306112138.155352-3-lmb@isovalent.com Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- tools/testing/selftests/bpf/prog_tests/btf.c | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c index 48b01150e703..28d22265b825 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf.c +++ b/tools/testing/selftests/bpf/prog_tests/btf.c @@ -882,6 +882,34 @@ static struct btf_raw_test raw_tests[] = { .btf_load_err = true, .err_str = "Invalid elem", }, +{ + .descr = "var after datasec, ptr followed by modifier", + .raw_types = { + /* .bss section */ /* [1] */ + BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), + sizeof(void*)+4), + BTF_VAR_SECINFO_ENC(4, 0, sizeof(void*)), + BTF_VAR_SECINFO_ENC(6, sizeof(void*), 4), + /* int */ /* [2] */ + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), + /* int* */ /* [3] */ + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), + BTF_VAR_ENC(NAME_TBD, 3, 0), /* [4] */ + /* const int */ /* [5] */ + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2), + BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ + BTF_END_RAW, + }, + .str_sec = "\0a\0b\0c\0", + .str_sec_size = sizeof("\0a\0b\0c\0"), + .map_type = BPF_MAP_TYPE_ARRAY, + .map_name = ".bss", + .key_size = sizeof(int), + .value_size = sizeof(void*)+4, + .key_type_id = 0, + .value_type_id = 1, + .max_entries = 1, +}, /* Test member exceeds the size of struct. * * struct A { From 799d29a447dc2461a537fc8edeb44f9cfd630936 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 14 Feb 2023 15:15:56 +0100 Subject: [PATCH 0911/1017] scsi: target: iscsi: Fix an error message in iscsi_check_key() [ Upstream commit 6cc55c969b7ce8d85e09a636693d4126c3676c11 ] The first half of the error message is printed by pr_err(), the second half is printed by pr_debug(). The user will therefore see only the first part of the message and will miss some useful information. Link: https://lore.kernel.org/r/20230214141556.762047-1-mlombard@redhat.com Signed-off-by: Maurizio Lombardi Reviewed-by: Mike Christie Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/target/iscsi/iscsi_target_parameters.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 7a461fbb1566..31cd3c02e517 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -1262,18 +1262,20 @@ static struct iscsi_param *iscsi_check_key( return param; if (!(param->phase & phase)) { - pr_err("Key \"%s\" may not be negotiated during ", - param->name); + char *phase_name; + switch (phase) { case PHASE_SECURITY: - pr_debug("Security phase.\n"); + phase_name = "Security"; break; case PHASE_OPERATIONAL: - pr_debug("Operational phase.\n"); + phase_name = "Operational"; break; default: - pr_debug("Unknown phase.\n"); + phase_name = "Unknown"; } + pr_err("Key \"%s\" may not be negotiated during %s phase.\n", + param->name, phase_name); return NULL; } From 522314863f7820f49ea80a8fb9d9e5526a578d9a Mon Sep 17 00:00:00 2001 From: Kang Chen Date: Mon, 27 Feb 2023 11:10:30 +0800 Subject: [PATCH 0912/1017] scsi: hisi_sas: Check devm_add_action() return value [ Upstream commit 06d1a90de60208054cca15ef200138cfdbb642a9 ] In case devm_add_action() fails, check it in the caller of interrupt_preinit_v3_hw(). Link: https://lore.kernel.org/r/20230227031030.893324-1-void0red@gmail.com Signed-off-by: Kang Chen Acked-by: Xiang Chen Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index cd41dc061d87..65971bd80186 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2402,8 +2402,7 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba) hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW; shost->nr_hw_queues = hisi_hba->cq_nvecs; - devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); - return 0; + return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); } static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) From f9a937f75ba2faf41b5acb1603f5ccf3c64b1e82 Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Mon, 20 Feb 2023 09:07:40 -0500 Subject: [PATCH 0913/1017] scsi: ufs: core: Add soft dependency on governor_simpleondemand [ Upstream commit 2ebe16155dc8bd4e602cad5b5f65458d2eaa1a75 ] The ufshcd driver uses simpleondemand governor for devfreq. Add it to the list of ufshcd softdeps to allow userspace initramfs tools like dracut to automatically pull the governor module into the initramfs together with UFS drivers. Link: https://lore.kernel.org/r/20230220140740.14379-1-athierry@redhat.com Signed-off-by: Adrien Thierry Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufshcd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ea6ceab1a1b2..f3389e913179 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -9311,5 +9311,6 @@ EXPORT_SYMBOL_GPL(ufshcd_init); MODULE_AUTHOR("Santosh Yaragnavi "); MODULE_AUTHOR("Vinayak Holikatti "); MODULE_DESCRIPTION("Generic UFS host controller driver Core"); +MODULE_SOFTDEP("pre: governor_simpleondemand"); MODULE_LICENSE("GPL"); MODULE_VERSION(UFSHCD_DRIVER_VERSION); From 3e0a423a55a75a27537084ab9b2edae32b3df2b8 Mon Sep 17 00:00:00 2001 From: Jakob Koschel Date: Wed, 1 Mar 2023 18:19:14 +0100 Subject: [PATCH 0914/1017] scsi: lpfc: Avoid usage of list iterator variable after loop [ Upstream commit 2850b23e9f9ae3696e472d2883ea1b43aafa884e ] If the &epd_pool->list is empty when executing lpfc_get_io_buf_from_expedite_pool() the function would return an invalid pointer. Even in the case if the list is guaranteed to be populated, the iterator variable should not be used after the loop to be more robust for future changes. Linus proposed to avoid any use of the list iterator variable after the loop, in the attempt to move the list iterator variable declaration into the macro to avoid any potential misuse after the loop [1]. Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ [1] Signed-off-by: Jakob Koschel Link: https://lore.kernel.org/r/20230301-scsi-lpfc-avoid-list-iterator-after-loop-v1-1-325578ae7561@gmail.com Reviewed-by: Justin Tee Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/lpfc/lpfc_sli.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 755d68b98160..923ceaba0bf3 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -20816,20 +20816,20 @@ lpfc_get_io_buf_from_private_pool(struct lpfc_hba *phba, static struct lpfc_io_buf * lpfc_get_io_buf_from_expedite_pool(struct lpfc_hba *phba) { - struct lpfc_io_buf *lpfc_ncmd; + struct lpfc_io_buf *lpfc_ncmd = NULL, *iter; struct lpfc_io_buf *lpfc_ncmd_next; unsigned long iflag; struct lpfc_epd_pool *epd_pool; epd_pool = &phba->epd_pool; - lpfc_ncmd = NULL; spin_lock_irqsave(&epd_pool->lock, iflag); if (epd_pool->count > 0) { - list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next, + list_for_each_entry_safe(iter, lpfc_ncmd_next, &epd_pool->list, list) { - list_del(&lpfc_ncmd->list); + list_del(&iter->list); epd_pool->count--; + lpfc_ncmd = iter; break; } } From ddfc061793385d7342997c6868a5c9638f1550c8 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Mon, 27 Feb 2023 08:48:34 -0800 Subject: [PATCH 0915/1017] scsi: storvsc: Handle BlockSize change in Hyper-V VHD/VHDX file [ Upstream commit 11d9874c4204a785f43d899a1ab12f9dc8d9de3e ] Hyper-V uses a VHD or VHDX file on the host as the underlying storage for a virtual disk. The VHD/VHDX file format is a sparse format where real disk space on the host is assigned in chunks that the VHD/VHDX file format calls the BlockSize. This BlockSize is not to be confused with the 512-byte (or 4096-byte) sector size of the underlying storage device. The default block size for a new VHD/VHDX file is 32 Mbytes. When a guest VM touches any disk space within a 32 Mbyte chunk of the VHD/VHDX file, Hyper-V allocates 32 Mbytes of real disk space for that section of the VHD/VHDX. Similarly, if a discard operation is done that covers an entire 32 Mbyte chunk, Hyper-V will free the real disk space for that portion of the VHD/VHDX. This BlockSize is surfaced in Linux as the "discard_granularity" in /sys/block/sd/queue, which makes sense. Hyper-V also has differencing disks that can overlay a VHD/VHDX file to capture changes to the VHD/VHDX while preserving the original VHD/VHDX. One example of this differencing functionality is for VM snapshots. When a snapshot is created, a differencing disk is created. If the snapshot is rolled back, Hyper-V can just delete the differencing disk, and the VM will see the original disk contents at the time the snapshot was taken. Differencing disks are used in other scenarios as well. The BlockSize for a differencing disk defaults to 2 Mbytes, not 32 Mbytes. The smaller default is used because changes to differencing disks are typically scattered all over, and Hyper-V doesn't want to allocate 32 Mbytes of real disk space for a stray write here or there. The smaller BlockSize provides more efficient use of real disk space. When a differencing disk is added to a VHD/VHDX, Hyper-V reports UNIT_ATTENTION with a sense code indicating "Operating parameters have changed", because the value of discard_granularity should be changed to 2 Mbytes. When the differencing disk is removed, discard_granularity should be changed back to 32 Mbytes. However, current code simply reports a message from scsi_report_sense() and the value of /sys/block/sd/queue/discard_granularity is not updated. The message isn't very actionable by a sysadmin. Fix this by having the storvsc driver check for the sense code indicating that the underly VHD/VHDX block size has changed, and do a rescan of the device to pick up the new discard_granularity. With this change the entire transition to/from differencing disks is handled automatically and transparently, with no confusing messages being output. Link: https://lore.kernel.org/r/1677516514-86060-1-git-send-email-mikelley@microsoft.com Signed-off-by: Michael Kelley Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/storvsc_drv.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 3fa8a0c94bdc..e38aebcabb26 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1013,6 +1013,22 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, goto do_work; } + /* + * Check for "Operating parameters have changed" + * due to Hyper-V changing the VHD/VHDX BlockSize + * when adding/removing a differencing disk. This + * causes discard_granularity to change, so do a + * rescan to pick up the new granularity. We don't + * want scsi_report_sense() to output a message + * that a sysadmin wouldn't know what to do with. + */ + if ((asc == 0x3f) && (ascq != 0x03) && + (ascq != 0x0e)) { + process_err_fn = storvsc_device_scan; + set_host_byte(scmnd, DID_REQUEUE); + goto do_work; + } + /* * Otherwise, let upper layer deal with the * error when sense message is present From 27d4ce4aa3bbf02e839f812843d0c183ac20061d Mon Sep 17 00:00:00 2001 From: Enrico Sau Date: Mon, 6 Mar 2023 12:59:33 +0100 Subject: [PATCH 0916/1017] net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990 [ Upstream commit 418383e6ed6b4624a54ec05c535f13d184fbf33b ] Add quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE for Telit FE990 0x1081 composition in order to avoid bind error. Signed-off-by: Enrico Sau Link: https://lore.kernel.org/r/20230306115933.198259-1-enrico.sau@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/usb/cdc_mbim.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 414341c9cf5a..6ad1fb00a35c 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -663,6 +663,11 @@ static const struct usb_device_id mbim_devs[] = { .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, }, + /* Telit FE990 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1081, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, + }, + /* default entry */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&cdc_mbim_info_zlp, From 87e800e3dc77e3a2b48f105e97bb75f864c65b71 Mon Sep 17 00:00:00 2001 From: Enrico Sau Date: Mon, 6 Mar 2023 13:05:28 +0100 Subject: [PATCH 0917/1017] net: usb: qmi_wwan: add Telit 0x1080 composition [ Upstream commit 382e363d5bed0cec5807b35761d14e55955eee63 ] Add the following Telit FE990 composition: 0x1080: tty, adb, rmnet, tty, tty, tty, tty Signed-off-by: Enrico Sau Link: https://lore.kernel.org/r/20230306120528.198842-1-enrico.sau@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index bce151e3706a..070910567c44 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1297,6 +1297,7 @@ static const struct usb_device_id products[] = { {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ From 8beb18c25beff12f27ffeb78f4e1de31a0e7cad0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 6 Mar 2023 01:20:30 +0000 Subject: [PATCH 0918/1017] sh: sanitize the flags on sigreturn [ Upstream commit 573b22ccb7ce9ab7f0539a2e11a9d3609a8783f5 ] We fetch %SR value from sigframe; it might have been modified by signal handler, so we can't trust it with any bits that are not modifiable in user mode. Signed-off-by: Al Viro Cc: Rich Felker Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- arch/sh/include/asm/processor_32.h | 1 + arch/sh/kernel/signal_32.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index aa92cc933889..6c7966e62775 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -50,6 +50,7 @@ #define SR_FD 0x00008000 #define SR_MD 0x40000000 +#define SR_USER_MASK 0x00000303 // M, Q, S, T bits /* * DSP structure and data */ diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index dd3092911efa..dc13702003f0 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -115,6 +115,7 @@ static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p) { unsigned int err = 0; + unsigned int sr = regs->sr & ~SR_USER_MASK; #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) COPY(regs[1]); @@ -130,6 +131,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p COPY(sr); COPY(pc); #undef COPY + regs->sr = (regs->sr & SR_USER_MASK) | sr; + #ifdef CONFIG_SH_FPU if (boot_cpu_data.flags & CPU_HAS_FPU) { int owned_fp; From f7a4ce3514262777f1a43b793d5a7daf24d517bc Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Thu, 9 Mar 2023 13:23:29 +0000 Subject: [PATCH 0919/1017] cifs: empty interface list when server doesn't support query interfaces commit 896cd316b841053f6df95ab77b5f1322c16a8e18 upstream. When querying server interfaces returns -EOPNOTSUPP, clear the list of interfaces. Assumption is that multichannel would be disabled too. Signed-off-by: Shyam Prasad N Reviewed-by: Paulo Alcantara (SUSE) Cc: stable@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 8fdd34ff20ef..120c7cb11b02 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -593,7 +593,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) if (rc == -EOPNOTSUPP) { cifs_dbg(FYI, "server does not support query network interfaces\n"); - goto out; + ret_data_len = 0; } else if (rc != 0) { cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc); goto out; From dce128421554c7ad7c1f25a972b49c355ac2199e Mon Sep 17 00:00:00 2001 From: Joel Selvaraj Date: Sun, 12 Mar 2023 23:14:02 -0500 Subject: [PATCH 0920/1017] scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR commit a204b490595de71016b2360a1886ec8c12d0afac upstream. Xiaomi Poco F1 (qcom/sdm845-xiaomi-beryllium*.dts) comes with a SKhynix H28U74301AMR UFS. The sd_read_cpr() operation leads to a 120 second timeout, making the device bootup very slow: [ 121.457736] sd 0:0:0:1: [sdb] tag#23 timing out command, waited 120s Setting the BLIST_SKIP_VPD_PAGES allows the device to skip the failing sd_read_cpr operation and boot normally. Signed-off-by: Joel Selvaraj Link: https://lore.kernel.org/r/20230313041402.39330-1-joelselvaraj.oss@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 9a8f9f902f3b..f5e121f0ee52 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -232,6 +232,7 @@ static struct { {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"SKhynix", "H28U74301AMR", NULL, BLIST_SKIP_VPD_PAGES}, {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, From 1f01027c51eb16145e8e07fafea3ca07ef102d06 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Thu, 16 Mar 2023 09:41:27 +0100 Subject: [PATCH 0921/1017] usb: dwc2: fix a devres leak in hw_enable upon suspend resume commit f747313249b74f323ddf841a9c8db14d989f296a upstream. Each time the platform goes to low power, PM suspend / resume routines call: __dwc2_lowlevel_hw_enable -> devm_add_action_or_reset(). This adds a new devres each time. This may also happen at runtime, as dwc2_lowlevel_hw_enable() can be called from udc_start(). This can be seen with tracing: - echo 1 > /sys/kernel/debug/tracing/events/dev/devres_log/enable - go to low power - cat /sys/kernel/debug/tracing/trace A new "ADD" entry is found upon each low power cycle: ... devres_log: 49000000.usb-otg ADD 82a13bba devm_action_release (8 bytes) ... devres_log: 49000000.usb-otg ADD 49889daf devm_action_release (8 bytes) ... A second issue is addressed here: - regulator_bulk_enable() is called upon each PM cycle (suspend/resume). - regulator_bulk_disable() never gets called. So the reference count for these regulators constantly increase, by one upon each low power cycle, due to missing regulator_bulk_disable() call in __dwc2_lowlevel_hw_disable(). The original fix that introduced the devm_add_action_or_reset() call, fixed an issue during probe, that happens due to other errors in dwc2_driver_probe() -> dwc2_core_reset(). Then the probe fails without disabling regulators, when dr_mode == USB_DR_MODE_PERIPHERAL. Rather fix the error path: disable all the low level hardware in the error path, by using the "hsotg->ll_hw_enabled" flag. Checking dr_mode has been introduced to avoid a dual call to dwc2_lowlevel_hw_disable(). "ll_hw_enabled" should achieve the same (and is used currently in the remove() routine). Fixes: 54c196060510 ("usb: dwc2: Always disable regulators on driver teardown") Fixes: 33a06f1300a7 ("usb: dwc2: Fix error path in gadget registration") Cc: stable Signed-off-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20230316084127.126084-1-fabrice.gasnier@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc2/platform.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 8851db646ef5..9d0dd09a2015 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -121,13 +121,6 @@ static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg) return 0; } -static void __dwc2_disable_regulators(void *data) -{ - struct dwc2_hsotg *hsotg = data; - - regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); -} - static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); @@ -138,11 +131,6 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) if (ret) return ret; - ret = devm_add_action_or_reset(&pdev->dev, - __dwc2_disable_regulators, hsotg); - if (ret) - return ret; - if (hsotg->clk) { ret = clk_prepare_enable(hsotg->clk); if (ret) @@ -198,7 +186,7 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) if (hsotg->clk) clk_disable_unprepare(hsotg->clk); - return 0; + return regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); } /** @@ -625,7 +613,7 @@ error_init: if (hsotg->params.activate_stm_id_vb_detection) regulator_disable(hsotg->usb33d); error: - if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) + if (hsotg->ll_hw_enabled) dwc2_lowlevel_hw_disable(hsotg); return retval; } From 33f341c1fc60e172a3515c51bdabee11e83d1ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Thu, 2 Mar 2023 17:36:47 +0100 Subject: [PATCH 0922/1017] usb: gadget: u_audio: don't let userspace block driver unbind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6c67ed9ad9b83e453e808f9b31a931a20a25629b upstream. In the unbind callback for f_uac1 and f_uac2, a call to snd_card_free() via g_audio_cleanup() will disconnect the card and then wait for all resources to be released, which happens when the refcount falls to zero. Since userspace can keep the refcount incremented by not closing the relevant file descriptor, the call to unbind may block indefinitely. This can cause a deadlock during reboot, as evidenced by the following blocked task observed on my machine: task:reboot state:D stack:0 pid:2827 ppid:569 flags:0x0000000c Call trace: __switch_to+0xc8/0x140 __schedule+0x2f0/0x7c0 schedule+0x60/0xd0 schedule_timeout+0x180/0x1d4 wait_for_completion+0x78/0x180 snd_card_free+0x90/0xa0 g_audio_cleanup+0x2c/0x64 afunc_unbind+0x28/0x60 ... kernel_restart+0x4c/0xac __do_sys_reboot+0xcc/0x1ec __arm64_sys_reboot+0x28/0x30 invoke_syscall+0x4c/0x110 ... The issue can also be observed by opening the card with arecord and then stopping the process through the shell before unbinding: # arecord -D hw:UAC2Gadget -f S32_LE -c 2 -r 48000 /dev/null Recording WAVE '/dev/null' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo ^Z[1]+ Stopped arecord -D hw:UAC2Gadget -f S32_LE -c 2 -r 48000 /dev/null # echo gadget.0 > /sys/bus/gadget/drivers/configfs-gadget/unbind (observe that the unbind command never finishes) Fix the problem by using snd_card_free_when_closed() instead, which will still disconnect the card as desired, but defer the task of freeing the resources to the core once userspace closes its file descriptor. Fixes: 132fcb460839 ("usb: gadget: Add Audio Class 2.0 Driver") Cc: stable@vger.kernel.org Signed-off-by: Alvin Šipraga Reviewed-by: Ruslan Bilovol Reviewed-by: John Keeping Link: https://lore.kernel.org/r/20230302163648.3349669-1-alvin@pqrs.dk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/u_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 95605b1ef4eb..6c8b8f5b7e0f 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -613,7 +613,7 @@ void g_audio_cleanup(struct g_audio *g_audio) uac = g_audio->uac; card = uac->card; if (card) - snd_card_free(card); + snd_card_free_when_closed(card); kfree(uac->p_prm.ureq); kfree(uac->c_prm.ureq); From e66f3039c7922cc76ec555363f3e2a4cd224397d Mon Sep 17 00:00:00 2001 From: Nathan Huckleberry Date: Fri, 10 Mar 2023 11:33:25 -0800 Subject: [PATCH 0923/1017] fsverity: Remove WQ_UNBOUND from fsverity read workqueue commit f959325e6ac3f499450088b8d9c626d1177be160 upstream. WQ_UNBOUND causes significant scheduler latency on ARM64/Android. This is problematic for latency sensitive workloads, like I/O post-processing. Removing WQ_UNBOUND gives a 96% reduction in fsverity workqueue related scheduler latency and improves app cold startup times by ~30ms. WQ_UNBOUND was also removed from the dm-verity workqueue for the same reason [1]. This code was tested by running Android app startup benchmarks and measuring how long the fsverity workqueue spent in the runnable state. Before Total workqueue scheduler latency: 553800us After Total workqueue scheduler latency: 18962us [1]: https://lore.kernel.org/all/20230202012348.885402-1-nhuck@google.com/ Signed-off-by: Nathan Huckleberry Fixes: 8a1d0f9cacc9 ("fs-verity: add data verification hooks for ->readpages()") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230310193325.620493-1-nhuck@google.com Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman --- fs/verity/verify.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/verity/verify.c b/fs/verity/verify.c index a8b68c6f663d..d3a3a359d815 100644 --- a/fs/verity/verify.c +++ b/fs/verity/verify.c @@ -279,15 +279,15 @@ EXPORT_SYMBOL_GPL(fsverity_enqueue_verify_work); int __init fsverity_init_workqueue(void) { /* - * Use an unbound workqueue to allow bios to be verified in parallel - * even when they happen to complete on the same CPU. This sacrifices - * locality, but it's worthwhile since hashing is CPU-intensive. + * Use a high-priority workqueue to prioritize verification work, which + * blocks reads from completing, over regular application tasks. * - * Also use a high-priority workqueue to prioritize verification work, - * which blocks reads from completing, over regular application tasks. + * For performance reasons, don't use an unbound workqueue. Using an + * unbound workqueue for crypto operations causes excessive scheduler + * latency on ARM64. */ fsverity_read_workqueue = alloc_workqueue("fsverity_read_queue", - WQ_UNBOUND | WQ_HIGHPRI, + WQ_HIGHPRI, num_online_cpus()); if (!fsverity_read_workqueue) return -ENOMEM; From 4d2626e10709ff8474ffd1a9db3cf4647569e89c Mon Sep 17 00:00:00 2001 From: Lin Ma Date: Tue, 7 Mar 2023 23:29:17 +0800 Subject: [PATCH 0924/1017] igb: revert rtnl_lock() that causes deadlock commit 65f69851e44d71248b952a687e44759a7abb5016 upstream. The commit 6faee3d4ee8b ("igb: Add lock to avoid data race") adds rtnl_lock to eliminate a false data race shown below (FREE from device detaching) | (USE from netdev core) igb_remove | igb_ndo_get_vf_config igb_disable_sriov | vf >= adapter->vfs_allocated_count? kfree(adapter->vf_data) | adapter->vfs_allocated_count = 0 | | memcpy(... adapter->vf_data[vf] The above race will never happen and the extra rtnl_lock causes deadlock below [ 141.420169] [ 141.420672] __schedule+0x2dd/0x840 [ 141.421427] schedule+0x50/0xc0 [ 141.422041] schedule_preempt_disabled+0x11/0x20 [ 141.422678] __mutex_lock.isra.13+0x431/0x6b0 [ 141.423324] unregister_netdev+0xe/0x20 [ 141.423578] igbvf_remove+0x45/0xe0 [igbvf] [ 141.423791] pci_device_remove+0x36/0xb0 [ 141.423990] device_release_driver_internal+0xc1/0x160 [ 141.424270] pci_stop_bus_device+0x6d/0x90 [ 141.424507] pci_stop_and_remove_bus_device+0xe/0x20 [ 141.424789] pci_iov_remove_virtfn+0xba/0x120 [ 141.425452] sriov_disable+0x2f/0xf0 [ 141.425679] igb_disable_sriov+0x4e/0x100 [igb] [ 141.426353] igb_remove+0xa0/0x130 [igb] [ 141.426599] pci_device_remove+0x36/0xb0 [ 141.426796] device_release_driver_internal+0xc1/0x160 [ 141.427060] driver_detach+0x44/0x90 [ 141.427253] bus_remove_driver+0x55/0xe0 [ 141.427477] pci_unregister_driver+0x2a/0xa0 [ 141.428296] __x64_sys_delete_module+0x141/0x2b0 [ 141.429126] ? mntput_no_expire+0x4a/0x240 [ 141.429363] ? syscall_trace_enter.isra.19+0x126/0x1a0 [ 141.429653] do_syscall_64+0x5b/0x80 [ 141.429847] ? exit_to_user_mode_prepare+0x14d/0x1c0 [ 141.430109] ? syscall_exit_to_user_mode+0x12/0x30 [ 141.430849] ? do_syscall_64+0x67/0x80 [ 141.431083] ? syscall_exit_to_user_mode_prepare+0x183/0x1b0 [ 141.431770] ? syscall_exit_to_user_mode+0x12/0x30 [ 141.432482] ? do_syscall_64+0x67/0x80 [ 141.432714] ? exc_page_fault+0x64/0x140 [ 141.432911] entry_SYSCALL_64_after_hwframe+0x72/0xdc Since the igb_disable_sriov() will call pci_disable_sriov() before releasing any resources, the netdev core will synchronize the cleanup to avoid any races. This patch removes the useless rtnl_(un)lock to guarantee correctness. CC: stable@vger.kernel.org Fixes: 6faee3d4ee8b ("igb: Add lock to avoid data race") Reported-by: Corinna Vinschen Link: https://lore.kernel.org/intel-wired-lan/ZAcJvkEPqWeJHO2r@calimero.vinschen.de/ Signed-off-by: Lin Ma Tested-by: Corinna Vinschen Reviewed-by: Jacob Keller Reviewed-by: Simon Horman Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/igb/igb_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 0ea8e4024d63..c5f465814dec 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3821,9 +3821,7 @@ static void igb_remove(struct pci_dev *pdev) igb_release_hw_control(adapter); #ifdef CONFIG_PCI_IOV - rtnl_lock(); igb_disable_sriov(pdev); - rtnl_unlock(); #endif unregister_netdev(netdev); From aae6d1bf4d8e66d566b77a44b5bef2cad11ec02c Mon Sep 17 00:00:00 2001 From: Coly Li Date: Mon, 27 Feb 2023 23:23:17 +0800 Subject: [PATCH 0925/1017] dm thin: fix deadlock when swapping to thin device commit 9bbf5feecc7eab2c370496c1c161bbfe62084028 upstream. This is an already known issue that dm-thin volume cannot be used as swap, otherwise a deadlock may happen when dm-thin internal memory demand triggers swap I/O on the dm-thin volume itself. But thanks to commit a666e5c05e7c ("dm: fix deadlock when swapping to encrypted device"), the limit_swap_bios target flag can also be used for dm-thin to avoid the recursive I/O when it is used as swap. Fix is to simply set ti->limit_swap_bios to true in both pool_ctr() and thin_ctr(). In my test, I create a dm-thin volume /dev/vg/swap and use it as swap device. Then I run fio on another dm-thin volume /dev/vg/main and use large --blocksize to trigger swap I/O onto /dev/vg/swap. The following fio command line is used in my test, fio --name recursive-swap-io --lockmem 1 --iodepth 128 \ --ioengine libaio --filename /dev/vg/main --rw randrw \ --blocksize 1M --numjobs 32 --time_based --runtime=12h Without this fix, the whole system can be locked up within 15 seconds. With this fix, there is no any deadlock or hung task observed after 2 hours of running fio. Furthermore, if blocksize is changed from 1M to 128M, after around 30 seconds fio has no visible I/O, and the out-of-memory killer message shows up in kernel message. After around 20 minutes all fio processes are killed and the whole system is back to being alive. This is exactly what is expected when recursive I/O happens on dm-thin volume when it is used as swap. Depends-on: a666e5c05e7c ("dm: fix deadlock when swapping to encrypted device") Cc: stable@vger.kernel.org Signed-off-by: Coly Li Acked-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-thin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index c890bb3e5185..93140743a999 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3383,6 +3383,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) pt->low_water_blocks = low_water_blocks; pt->adjusted_pf = pt->requested_pf = pf; ti->num_flush_bios = 1; + ti->limit_swap_bios = true; /* * Only need to enable discards if the pool should pass @@ -4259,6 +4260,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) goto bad; ti->num_flush_bios = 1; + ti->limit_swap_bios = true; ti->flush_supported = true; ti->per_io_data_size = sizeof(struct dm_thin_endio_hook); From 5a36b601aff3f22e9504763c6d9779f099d3f1bd Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Wed, 8 Mar 2023 07:44:27 -0500 Subject: [PATCH 0926/1017] usb: cdns3: Fix issue with using incorrect PCI device function commit 1272fd652a226ccb34e9f47371b6121948048438 upstream. PCI based platform can have more than two PCI functions. USBSS PCI Glue driver during initialization should consider only DRD/HOST/DEVICE PCI functions and all other should be ignored. This patch adds additional condition which causes that only DRD and HOST/DEVICE function will be accepted. cc: Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Signed-off-by: Pawel Laszczak Link: https://lore.kernel.org/r/20230308124427.311245-1-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdns3-pci-wrap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns3-pci-wrap.c index deeea618ba33..1f6320d98a76 100644 --- a/drivers/usb/cdns3/cdns3-pci-wrap.c +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c @@ -60,6 +60,11 @@ static struct pci_dev *cdns3_get_second_fun(struct pci_dev *pdev) return NULL; } + if (func->devfn != PCI_DEV_FN_HOST_DEVICE && + func->devfn != PCI_DEV_FN_OTG) { + return NULL; + } + return func; } From 073ce98aa3a6be039a7e17b87945dfea3b4d2b66 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Fri, 17 Mar 2023 14:15:15 +0800 Subject: [PATCH 0927/1017] usb: chipdea: core: fix return -EINVAL if request role is the same with current role commit 3670de80678961eda7fa2220883fc77c16868951 upstream. It should not return -EINVAL if the request role is the same with current role, return non-error and without do anything instead. Fixes: a932a8041ff9 ("usb: chipidea: core: add sysfs group") cc: Acked-by: Peter Chen Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20230317061516.2451728-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 127b1a62b1bf..0b7e5ab23457 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -966,9 +966,12 @@ static ssize_t role_store(struct device *dev, strlen(ci->roles[role]->name))) break; - if (role == CI_ROLE_END || role == ci->role) + if (role == CI_ROLE_END) return -EINVAL; + if (role == ci->role) + return n; + pm_runtime_get_sync(dev); disable_irq(ci->irq); ci_role_stop(ci); From 09671cfc2b22fa1a4cec29464205d9ac62f821e5 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Fri, 17 Mar 2023 14:15:16 +0800 Subject: [PATCH 0928/1017] usb: chipidea: core: fix possible concurrent when switch role commit 451b15ed138ec15bffbebb58a00ebdd884c3e659 upstream. The user may call role_store() when driver is handling ci_handle_id_switch() which is triggerred by otg event or power lost event. Unfortunately, the controller may go into chaos in this case. Fix this by protecting it with mutex lock. Fixes: a932a8041ff9 ("usb: chipidea: core: add sysfs group") cc: Acked-by: Peter Chen Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20230317061516.2451728-2-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci.h | 2 ++ drivers/usb/chipidea/core.c | 8 +++++++- drivers/usb/chipidea/otg.c | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 0697eb980e5f..7b00b93dad9b 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -204,6 +204,7 @@ struct hw_bank { * @in_lpm: if the core in low power mode * @wakeup_int: if wakeup interrupt occur * @rev: The revision number for controller + * @mutex: protect code from concorrent running when doing role switch */ struct ci_hdrc { struct device *dev; @@ -257,6 +258,7 @@ struct ci_hdrc { bool in_lpm; bool wakeup_int; enum ci_revision rev; + struct mutex mutex; }; static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 0b7e5ab23457..f26dd1f054f2 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -969,8 +969,12 @@ static ssize_t role_store(struct device *dev, if (role == CI_ROLE_END) return -EINVAL; - if (role == ci->role) + mutex_lock(&ci->mutex); + + if (role == ci->role) { + mutex_unlock(&ci->mutex); return n; + } pm_runtime_get_sync(dev); disable_irq(ci->irq); @@ -980,6 +984,7 @@ static ssize_t role_store(struct device *dev, ci_handle_vbus_change(ci); enable_irq(ci->irq); pm_runtime_put_sync(dev); + mutex_unlock(&ci->mutex); return (ret == 0) ? n : ret; } @@ -1015,6 +1020,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENOMEM; spin_lock_init(&ci->lock); + mutex_init(&ci->mutex); ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index d3aada3ce7ec..9a12868ea9b6 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -166,8 +166,10 @@ static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci) static void ci_handle_id_switch(struct ci_hdrc *ci) { - enum ci_role role = ci_otg_role(ci); + enum ci_role role; + mutex_lock(&ci->mutex); + role = ci_otg_role(ci); if (role != ci->role) { dev_dbg(ci->dev, "switching from %s to %s\n", ci_role(ci)->name, ci->roles[role]->name); @@ -197,6 +199,7 @@ static void ci_handle_id_switch(struct ci_hdrc *ci) if (role == CI_ROLE_GADGET) ci_handle_vbus_change(ci); } + mutex_unlock(&ci->mutex); } /** * ci_otg_work - perform otg (vbus/id) event handle From a6adfe9bbd6ac11e398b54ccd99a0f8eea09f3c0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 8 Mar 2023 16:42:42 +0100 Subject: [PATCH 0929/1017] usb: ucsi: Fix NULL pointer deref in ucsi_connector_change() commit f87fb985452ab2083967103ac00bfd68fb182764 upstream. When ucsi_init() fails, ucsi->connector is NULL, yet in case of ucsi_acpi we may still get events which cause the ucs_acpi code to call ucsi_connector_change(), which then derefs the NULL ucsi->connector pointer. Fix this by not setting ucsi->ntfy inside ucsi_init() until ucsi_init() has succeeded, so that ucsi_connector_change() ignores the events because UCSI_ENABLE_NTFY_CONNECTOR_CHANGE is not set in the ntfy mask. Fixes: bdc62f2bae8f ("usb: typec: ucsi: Simplified registration and I/O API") Link: https://bugzilla.kernel.org/show_bug.cgi?id=217106 Cc: stable@vger.kernel.org Reviewed-by: Heikki Krogerus Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20230308154244.722337-2-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 4cd5c291cdf3..cd3689005c31 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1152,7 +1152,7 @@ out_unlock: static int ucsi_init(struct ucsi *ucsi) { struct ucsi_connector *con; - u64 command; + u64 command, ntfy; int ret; int i; @@ -1164,8 +1164,8 @@ static int ucsi_init(struct ucsi *ucsi) } /* Enable basic notifications */ - ucsi->ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR; - command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; + ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR; + command = UCSI_SET_NOTIFICATION_ENABLE | ntfy; ret = ucsi_send_command(ucsi, command, NULL, 0); if (ret < 0) goto err_reset; @@ -1197,12 +1197,13 @@ static int ucsi_init(struct ucsi *ucsi) } /* Enable all notifications */ - ucsi->ntfy = UCSI_ENABLE_NTFY_ALL; - command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; + ntfy = UCSI_ENABLE_NTFY_ALL; + command = UCSI_SET_NOTIFICATION_ENABLE | ntfy; ret = ucsi_send_command(ucsi, command, NULL, 0); if (ret < 0) goto err_unregister; + ucsi->ntfy = ntfy; return 0; err_unregister: From 560437bba14d0546de72e3e9d0a2f78d88e8cd91 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 14 Mar 2023 10:59:50 +0100 Subject: [PATCH 0930/1017] wifi: mac80211: fix qos on mesh interfaces commit 4e348c6c6e23491ae6eb5e077848a42d0562339c upstream. When ieee80211_select_queue is called for mesh, the sta pointer is usually NULL, since the nexthop is looked up much later in the tx path. Explicitly check for unicast address in that case in order to make qos work again. Cc: stable@vger.kernel.org Fixes: 50e2ab392919 ("wifi: mac80211: fix queue selection for mesh/OCB interfaces") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230314095956.62085-1-nbd@nbd.name Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/wme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index b9404b056087..eb79f6844466 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -141,12 +141,14 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct sk_buff *skb) { + const struct ethhdr *eth = (void *)skb->data; struct mac80211_qos_map *qos_map; bool qos; /* all mesh/ocb stations are required to support WME */ - if (sta && (sdata->vif.type == NL80211_IFTYPE_MESH_POINT || - sdata->vif.type == NL80211_IFTYPE_OCB)) + if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT && + !is_multicast_ether_addr(eth->h_dest)) || + (sdata->vif.type == NL80211_IFTYPE_OCB && sta)) qos = true; else if (sta) qos = sta->sta.wme; From d18db946cc6a394291539e030df32324285648f7 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Tue, 7 Mar 2023 17:55:48 +0900 Subject: [PATCH 0931/1017] nilfs2: fix kernel-infoleak in nilfs_ioctl_wrap_copy() commit 003587000276f81d0114b5ce773d80c119d8cb30 upstream. The ioctl helper function nilfs_ioctl_wrap_copy(), which exchanges a metadata array to/from user space, may copy uninitialized buffer regions to user space memory for read-only ioctl commands NILFS_IOCTL_GET_SUINFO and NILFS_IOCTL_GET_CPINFO. This can occur when the element size of the user space metadata given by the v_size member of the argument nilfs_argv structure is larger than the size of the metadata element (nilfs_suinfo structure or nilfs_cpinfo structure) on the file system side. KMSAN-enabled kernels detect this issue as follows: BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:121 [inline] BUG: KMSAN: kernel-infoleak in _copy_to_user+0xc0/0x100 lib/usercopy.c:33 instrument_copy_to_user include/linux/instrumented.h:121 [inline] _copy_to_user+0xc0/0x100 lib/usercopy.c:33 copy_to_user include/linux/uaccess.h:169 [inline] nilfs_ioctl_wrap_copy+0x6fa/0xc10 fs/nilfs2/ioctl.c:99 nilfs_ioctl_get_info fs/nilfs2/ioctl.c:1173 [inline] nilfs_ioctl+0x2402/0x4450 fs/nilfs2/ioctl.c:1290 nilfs_compat_ioctl+0x1b8/0x200 fs/nilfs2/ioctl.c:1343 __do_compat_sys_ioctl fs/ioctl.c:968 [inline] __se_compat_sys_ioctl+0x7dd/0x1000 fs/ioctl.c:910 __ia32_compat_sys_ioctl+0x93/0xd0 fs/ioctl.c:910 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0xa2/0x100 arch/x86/entry/common.c:178 do_fast_syscall_32+0x37/0x80 arch/x86/entry/common.c:203 do_SYSENTER_32+0x1f/0x30 arch/x86/entry/common.c:246 entry_SYSENTER_compat_after_hwframe+0x70/0x82 Uninit was created at: __alloc_pages+0x9f6/0xe90 mm/page_alloc.c:5572 alloc_pages+0xab0/0xd80 mm/mempolicy.c:2287 __get_free_pages+0x34/0xc0 mm/page_alloc.c:5599 nilfs_ioctl_wrap_copy+0x223/0xc10 fs/nilfs2/ioctl.c:74 nilfs_ioctl_get_info fs/nilfs2/ioctl.c:1173 [inline] nilfs_ioctl+0x2402/0x4450 fs/nilfs2/ioctl.c:1290 nilfs_compat_ioctl+0x1b8/0x200 fs/nilfs2/ioctl.c:1343 __do_compat_sys_ioctl fs/ioctl.c:968 [inline] __se_compat_sys_ioctl+0x7dd/0x1000 fs/ioctl.c:910 __ia32_compat_sys_ioctl+0x93/0xd0 fs/ioctl.c:910 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0xa2/0x100 arch/x86/entry/common.c:178 do_fast_syscall_32+0x37/0x80 arch/x86/entry/common.c:203 do_SYSENTER_32+0x1f/0x30 arch/x86/entry/common.c:246 entry_SYSENTER_compat_after_hwframe+0x70/0x82 Bytes 16-127 of 3968 are uninitialized ... This eliminates the leak issue by initializing the page allocated as buffer using get_zeroed_page(). Link: https://lkml.kernel.org/r/20230307085548.6290-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi Reported-by: syzbot+132fdd2f1e1805fdc591@syzkaller.appspotmail.com Link: https://lkml.kernel.org/r/000000000000a5bd2d05f63f04ae@google.com Tested-by: Ryusuke Konishi Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/nilfs2/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 3a1dea5d1448..01235fac5971 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -70,7 +70,7 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs, if (argv->v_index > ~(__u64)0 - argv->v_nmembs) return -EINVAL; - buf = (void *)__get_free_pages(GFP_NOFS, 0); + buf = (void *)get_zeroed_page(GFP_NOFS); if (unlikely(!buf)) return -ENOMEM; maxmembs = PAGE_SIZE / argv->v_size; From d5329a06b4cb8bb79117c5ccb0bd3f1463881d21 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 14 Mar 2023 15:29:14 +0100 Subject: [PATCH 0932/1017] drm/i915/active: Fix missing debug object activation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e92eb246feb9019b0b137706c934b8891cdfe3c2 upstream. debug_active_activate() expected ref->count to be zero which is not true anymore as __i915_active_activate() calls debug_active_activate() after incrementing the count. v2: No need to check for "ref->count == 1" as __i915_active_activate() already make sure of that(Janusz). References: https://gitlab.freedesktop.org/drm/intel/-/issues/6733 Fixes: 04240e30ed06 ("drm/i915: Skip taking acquire mutex for no ref->active callback") Cc: Chris Wilson Cc: Tvrtko Ursulin Cc: Thomas Hellström Cc: Andi Shyti Cc: intel-gfx@lists.freedesktop.org Cc: Janusz Krzysztofik Cc: # v5.10+ Signed-off-by: Nirmoy Das Reviewed-by: Janusz Krzysztofik Reviewed-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20230313114613.9874-1-nirmoy.das@intel.com (cherry picked from commit bfad380c542438a9b642f8190b7fd37bc77e2723) Signed-off-by: Jani Nikula Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_active.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index 0532a5069c04..cae9ac6379a5 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -96,8 +96,7 @@ static void debug_active_init(struct i915_active *ref) static void debug_active_activate(struct i915_active *ref) { lockdep_assert_held(&ref->tree_lock); - if (!atomic_read(&ref->count)) /* before the first inc */ - debug_object_activate(ref, &active_debug_desc); + debug_object_activate(ref, &active_debug_desc); } static void debug_active_deactivate(struct i915_active *ref) From 4ede0da36c2fcd1f315c93719d9f3b7c7a807512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 23 Feb 2023 17:20:48 +0200 Subject: [PATCH 0933/1017] drm/i915: Preserve crtc_state->inherited during state clearing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 3a84f2c6c9558c554a90ec26ad25df92fc5e05b7 upstream. intel_crtc_prepare_cleared_state() is unintentionally losing the "inherited" flag. This will happen if intel_initial_commit() is forced to go through the full modeset calculations for whatever reason. Afterwards the first real commit from userspace will not get forced to the full modeset path, and thus eg. audio state may not get recomputed properly. So if the monitor was already enabled during boot audio will not work until userspace itself does an explicit full modeset. Cc: stable@vger.kernel.org Tested-by: Lee Shawn C Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230223152048.20878-1-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar (cherry picked from commit 2553bacaf953b48c59357f5a622282bc0c45adae) Signed-off-by: Jani Nikula Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 45c2556d6395..d46011f7a838 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -13335,6 +13335,7 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state) * only fields that are know to not cause problems are preserved. */ saved_state->uapi = crtc_state->uapi; + saved_state->inherited = crtc_state->inherited; saved_state->scaler_state = crtc_state->scaler_state; saved_state->shared_dpll = crtc_state->shared_dpll; saved_state->dpll_hw_state = crtc_state->dpll_hw_state; From f632a90f8e39db39b322107b9a8d438b826a7f4f Mon Sep 17 00:00:00 2001 From: Rijo Thomas Date: Tue, 28 Feb 2023 15:11:20 +0530 Subject: [PATCH 0934/1017] tee: amdtee: fix race condition in amdtee_open_session commit f8502fba45bd30e1a6a354d9d898bc99d1a11e6d upstream. There is a potential race condition in amdtee_open_session that may lead to use-after-free. For instance, in amdtee_open_session() after sess->sess_mask is set, and before setting: sess->session_info[i] = session_info; if amdtee_close_session() closes this same session, then 'sess' data structure will be released, causing kernel panic when 'sess' is accessed within amdtee_open_session(). The solution is to set the bit sess->sess_mask as the last step in amdtee_open_session(). Fixes: 757cc3e9ff1d ("tee: add AMD-TEE driver") Cc: stable@vger.kernel.org Signed-off-by: Rijo Thomas Acked-by: Sumit Garg Signed-off-by: Jens Wiklander Signed-off-by: Greg Kroah-Hartman --- drivers/tee/amdtee/core.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c index 297dc62bca29..372d64756ed6 100644 --- a/drivers/tee/amdtee/core.c +++ b/drivers/tee/amdtee/core.c @@ -267,35 +267,34 @@ int amdtee_open_session(struct tee_context *ctx, goto out; } + /* Open session with loaded TA */ + handle_open_session(arg, &session_info, param); + if (arg->ret != TEEC_SUCCESS) { + pr_err("open_session failed %d\n", arg->ret); + handle_unload_ta(ta_handle); + kref_put(&sess->refcount, destroy_session); + goto out; + } + /* Find an empty session index for the given TA */ spin_lock(&sess->lock); i = find_first_zero_bit(sess->sess_mask, TEE_NUM_SESSIONS); - if (i < TEE_NUM_SESSIONS) + if (i < TEE_NUM_SESSIONS) { + sess->session_info[i] = session_info; + set_session_id(ta_handle, i, &arg->session); set_bit(i, sess->sess_mask); + } spin_unlock(&sess->lock); if (i >= TEE_NUM_SESSIONS) { pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS); + handle_close_session(ta_handle, session_info); handle_unload_ta(ta_handle); kref_put(&sess->refcount, destroy_session); rc = -ENOMEM; goto out; } - /* Open session with loaded TA */ - handle_open_session(arg, &session_info, param); - if (arg->ret != TEEC_SUCCESS) { - pr_err("open_session failed %d\n", arg->ret); - spin_lock(&sess->lock); - clear_bit(i, sess->sess_mask); - spin_unlock(&sess->lock); - handle_unload_ta(ta_handle); - kref_put(&sess->refcount, destroy_session); - goto out; - } - - sess->session_info[i] = session_info; - set_session_id(ta_handle, i, &arg->session); out: free_pages((u64)ta, get_order(ta_size)); return rc; From 85b637feee1e60e2dce3a8e9041ccfee202fbb4c Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Tue, 7 Mar 2023 16:23:24 +0000 Subject: [PATCH 0935/1017] firmware: arm_scmi: Fix device node validation for mailbox transport commit 2ab4f4018cb6b8010ca5002c3bdc37783b5d28c2 upstream. When mailboxes are used as a transport it is possible to setup the SCMI transport layer, depending on the underlying channels configuration, to use one or two mailboxes, associated, respectively, to one or two, distinct, shared memory areas: any other combination should be treated as invalid. Add more strict checking of SCMI mailbox transport device node descriptors. Fixes: 5c8a47a5a91d ("firmware: arm_scmi: Make scmi core independent of the transport type") Cc: # 4.19 Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20230307162324.891866-1-cristian.marussi@arm.com Signed-off-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/arm_scmi/mailbox.c | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c index 4626404be541..ad773a657ed2 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -52,6 +52,39 @@ static bool mailbox_chan_available(struct device *dev, int idx) "#mbox-cells", idx, NULL); } +static int mailbox_chan_validate(struct device *cdev) +{ + int num_mb, num_sh, ret = 0; + struct device_node *np = cdev->of_node; + + num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); + num_sh = of_count_phandle_with_args(np, "shmem", NULL); + /* Bail out if mboxes and shmem descriptors are inconsistent */ + if (num_mb <= 0 || num_sh > 2 || num_mb != num_sh) { + dev_warn(cdev, "Invalid channel descriptor for '%s'\n", + of_node_full_name(np)); + return -EINVAL; + } + + if (num_sh > 1) { + struct device_node *np_tx, *np_rx; + + np_tx = of_parse_phandle(np, "shmem", 0); + np_rx = of_parse_phandle(np, "shmem", 1); + /* SCMI Tx and Rx shared mem areas have to be distinct */ + if (!np_tx || !np_rx || np_tx == np_rx) { + dev_warn(cdev, "Invalid shmem descriptor for '%s'\n", + of_node_full_name(np)); + ret = -EINVAL; + } + + of_node_put(np_tx); + of_node_put(np_rx); + } + + return ret; +} + static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx) { @@ -64,6 +97,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, resource_size_t size; struct resource res; + ret = mailbox_chan_validate(cdev); + if (ret) + return ret; + smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL); if (!smbox) return -ENOMEM; From 1eaa2b7ae90c5a5e05586df310d804de250747d3 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Tue, 14 Mar 2023 16:54:21 +0000 Subject: [PATCH 0936/1017] i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer() commit 92fbb6d1296f81f41f65effd7f5f8c0f74943d15 upstream. The data->block[0] variable comes from user and is a number between 0-255. Without proper check, the variable may be very large to cause an out-of-bounds when performing memcpy in slimpro_i2c_blkwr. Fix this bug by checking the value of writelen. Fixes: f6505fbabc42 ("i2c: add SLIMpro I2C device driver on APM X-Gene platform") Signed-off-by: Wei Chen Cc: stable@vger.kernel.org Reviewed-by: Andi Shyti Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-xgene-slimpro.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c index 63cbb9c7c1b0..76e9dcd63856 100644 --- a/drivers/i2c/busses/i2c-xgene-slimpro.c +++ b/drivers/i2c/busses/i2c-xgene-slimpro.c @@ -308,6 +308,9 @@ static int slimpro_i2c_blkwr(struct slimpro_i2c_dev *ctx, u32 chip, u32 msg[3]; int rc; + if (writelen > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + memcpy(ctx->dma_buffer, data, writelen); paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen, DMA_TO_DEVICE); From c68f08cc745675a17894e1b4a5b5b9700ace6da4 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Thu, 16 Mar 2023 14:55:06 +0800 Subject: [PATCH 0937/1017] dm stats: check for and propagate alloc_percpu failure commit d3aa3e060c4a80827eb801fc448debc9daa7c46b upstream. Check alloc_precpu()'s return value and return an error from dm_stats_init() if it fails. Update alloc_dev() to fail if dm_stats_init() does. Otherwise, a NULL pointer dereference will occur in dm_stats_cleanup() even if dm-stats isn't being actively used. Fixes: fd2ed4d25270 ("dm: add statistics support") Cc: stable@vger.kernel.org Signed-off-by: Jiasheng Jiang Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-stats.c | 7 ++++++- drivers/md/dm-stats.h | 2 +- drivers/md/dm.c | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index 55443a6598fa..4029281ca383 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c @@ -188,7 +188,7 @@ static int dm_stat_in_flight(struct dm_stat_shared *shared) atomic_read(&shared->in_flight[WRITE]); } -void dm_stats_init(struct dm_stats *stats) +int dm_stats_init(struct dm_stats *stats) { int cpu; struct dm_stats_last_position *last; @@ -196,11 +196,16 @@ void dm_stats_init(struct dm_stats *stats) mutex_init(&stats->mutex); INIT_LIST_HEAD(&stats->list); stats->last = alloc_percpu(struct dm_stats_last_position); + if (!stats->last) + return -ENOMEM; + for_each_possible_cpu(cpu) { last = per_cpu_ptr(stats->last, cpu); last->last_sector = (sector_t)ULLONG_MAX; last->last_rw = UINT_MAX; } + + return 0; } void dm_stats_cleanup(struct dm_stats *stats) diff --git a/drivers/md/dm-stats.h b/drivers/md/dm-stats.h index 2ddfae678f32..dcac11fce03b 100644 --- a/drivers/md/dm-stats.h +++ b/drivers/md/dm-stats.h @@ -22,7 +22,7 @@ struct dm_stats_aux { unsigned long long duration_ns; }; -void dm_stats_init(struct dm_stats *st); +int dm_stats_init(struct dm_stats *st); void dm_stats_cleanup(struct dm_stats *st); struct mapped_device; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c60febd14be1..9029c1004b93 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1910,7 +1910,9 @@ static struct mapped_device *alloc_dev(int minor) if (!md->bdev) goto bad; - dm_stats_init(&md->stats); + r = dm_stats_init(&md->stats); + if (r < 0) + goto bad; /* Populate the mapping, nobody knows we exist yet */ spin_lock(&_minor_lock); From 66ff37993dd7e9954b6446237fe2453b380ce40d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 6 Mar 2023 11:17:58 -0500 Subject: [PATCH 0938/1017] dm crypt: add cond_resched() to dmcrypt_write() commit fb294b1c0ba982144ca467a75e7d01ff26304e2b upstream. The loop in dmcrypt_write may be running for unbounded amount of time, thus we need cond_resched() in it. This commit fixes the following warning: [ 3391.153255][ C12] watchdog: BUG: soft lockup - CPU#12 stuck for 23s! [dmcrypt_write/2:2897] ... [ 3391.387210][ C12] Call trace: [ 3391.390338][ C12] blk_attempt_bio_merge.part.6+0x38/0x158 [ 3391.395970][ C12] blk_attempt_plug_merge+0xc0/0x1b0 [ 3391.401085][ C12] blk_mq_submit_bio+0x398/0x550 [ 3391.405856][ C12] submit_bio_noacct+0x308/0x380 [ 3391.410630][ C12] dmcrypt_write+0x1e4/0x208 [dm_crypt] [ 3391.416005][ C12] kthread+0x130/0x138 [ 3391.419911][ C12] ret_from_fork+0x10/0x18 Reported-by: yangerkun Fixes: dc2676210c42 ("dm crypt: offload writes to thread") Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-crypt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 3d975db86434..17ddca293965 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1934,6 +1934,7 @@ pop_from_list: io = crypt_io_from_node(rb_first(&write_tree)); rb_erase(&io->rb_node, &write_tree); kcryptd_io_write(io); + cond_resched(); } while (!RB_EMPTY_ROOT(&write_tree)); blk_finish_plug(&plug); } From dfdcda25fb5e3c09394a28173f24b22e7c7e4731 Mon Sep 17 00:00:00 2001 From: Zhang Qiao Date: Mon, 30 Jan 2023 13:22:16 +0100 Subject: [PATCH 0939/1017] sched/fair: sanitize vruntime of entity being placed commit 829c1651e9c4a6f78398d3e67651cef9bb6b42cc upstream. When a scheduling entity is placed onto cfs_rq, its vruntime is pulled to the base level (around cfs_rq->min_vruntime), so that the entity doesn't gain extra boost when placed backwards. However, if the entity being placed wasn't executed for a long time, its vruntime may get too far behind (e.g. while cfs_rq was executing a low-weight hog), which can inverse the vruntime comparison due to s64 overflow. This results in the entity being placed with its original vruntime way forwards, so that it will effectively never get to the cpu. To prevent that, ignore the vruntime of the entity being placed if it didn't execute for much longer than the characteristic sheduler time scale. [rkagan: formatted, adjusted commit log, comments, cutoff value] Signed-off-by: Zhang Qiao Co-developed-by: Roman Kagan Signed-off-by: Roman Kagan Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20230130122216.3555094-1-rkagan@amazon.de Signed-off-by: Greg Kroah-Hartman --- kernel/sched/fair.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c39d2fc3f994..68166c599a35 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4278,6 +4278,7 @@ static void place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) { u64 vruntime = cfs_rq->min_vruntime; + u64 sleep_time; /* * The 'current' period is already promised to the current tasks, @@ -4302,8 +4303,18 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) vruntime -= thresh; } - /* ensure we never gain time by being placed backwards. */ - se->vruntime = max_vruntime(se->vruntime, vruntime); + /* + * Pull vruntime of the entity being placed to the base level of + * cfs_rq, to prevent boosting it if placed backwards. If the entity + * slept for a long time, don't even try to compare its vruntime with + * the base as it may be too far off and the comparison may get + * inversed due to s64 overflow. + */ + sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; + if ((s64)sleep_time > 60LL * NSEC_PER_SEC) + se->vruntime = vruntime; + else + se->vruntime = max_vruntime(se->vruntime, vruntime); } static void check_enqueue_throttle(struct cfs_rq *cfs_rq); From d4a5181ba1b1165b8607fa4e738ce7b4be68eb24 Mon Sep 17 00:00:00 2001 From: Vincent Guittot Date: Fri, 17 Mar 2023 17:08:10 +0100 Subject: [PATCH 0940/1017] sched/fair: Sanitize vruntime of entity being migrated commit a53ce18cacb477dd0513c607f187d16f0fa96f71 upstream. Commit 829c1651e9c4 ("sched/fair: sanitize vruntime of entity being placed") fixes an overflowing bug, but ignore a case that se->exec_start is reset after a migration. For fixing this case, we delay the reset of se->exec_start after placing the entity which se->exec_start to detect long sleeping task. In order to take into account a possible divergence between the clock_task of 2 rqs, we increase the threshold to around 104 days. Fixes: 829c1651e9c4 ("sched/fair: sanitize vruntime of entity being placed") Originally-by: Zhang Qiao Signed-off-by: Vincent Guittot Signed-off-by: Peter Zijlstra (Intel) Tested-by: Zhang Qiao Link: https://lore.kernel.org/r/20230317160810.107988-1-vincent.guittot@linaro.org Signed-off-by: Greg Kroah-Hartman --- kernel/sched/core.c | 3 +++ kernel/sched/fair.c | 53 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1303a2607f1f..abea8fb7bdd1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1601,6 +1601,9 @@ static inline void dequeue_task(struct rq *rq, struct task_struct *p, int flags) void activate_task(struct rq *rq, struct task_struct *p, int flags) { + if (task_on_rq_migrating(p)) + flags |= ENQUEUE_MIGRATED; + enqueue_task(rq, p, flags); p->on_rq = TASK_ON_RQ_QUEUED; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 68166c599a35..bb70a7856277 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4274,11 +4274,33 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se) #endif } +static inline bool entity_is_long_sleeper(struct sched_entity *se) +{ + struct cfs_rq *cfs_rq; + u64 sleep_time; + + if (se->exec_start == 0) + return false; + + cfs_rq = cfs_rq_of(se); + + sleep_time = rq_clock_task(rq_of(cfs_rq)); + + /* Happen while migrating because of clock task divergence */ + if (sleep_time <= se->exec_start) + return false; + + sleep_time -= se->exec_start; + if (sleep_time > ((1ULL << 63) / scale_load_down(NICE_0_LOAD))) + return true; + + return false; +} + static void place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) { u64 vruntime = cfs_rq->min_vruntime; - u64 sleep_time; /* * The 'current' period is already promised to the current tasks, @@ -4305,13 +4327,24 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) /* * Pull vruntime of the entity being placed to the base level of - * cfs_rq, to prevent boosting it if placed backwards. If the entity - * slept for a long time, don't even try to compare its vruntime with - * the base as it may be too far off and the comparison may get - * inversed due to s64 overflow. + * cfs_rq, to prevent boosting it if placed backwards. + * However, min_vruntime can advance much faster than real time, with + * the extreme being when an entity with the minimal weight always runs + * on the cfs_rq. If the waking entity slept for a long time, its + * vruntime difference from min_vruntime may overflow s64 and their + * comparison may get inversed, so ignore the entity's original + * vruntime in that case. + * The maximal vruntime speedup is given by the ratio of normal to + * minimal weight: scale_load_down(NICE_0_LOAD) / MIN_SHARES. + * When placing a migrated waking entity, its exec_start has been set + * from a different rq. In order to take into account a possible + * divergence between new and prev rq's clocks task because of irq and + * stolen time, we take an additional margin. + * So, cutting off on the sleep time of + * 2^63 / scale_load_down(NICE_0_LOAD) ~ 104 days + * should be safe. */ - sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; - if ((s64)sleep_time > 60LL * NSEC_PER_SEC) + if (entity_is_long_sleeper(se)) se->vruntime = vruntime; else se->vruntime = max_vruntime(se->vruntime, vruntime); @@ -4410,6 +4443,9 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) if (flags & ENQUEUE_WAKEUP) place_entity(cfs_rq, se, 0); + /* Entity has migrated, no longer consider this task hot */ + if (flags & ENQUEUE_MIGRATED) + se->exec_start = 0; check_schedstat_required(); update_stats_enqueue(cfs_rq, se, flags); @@ -6995,9 +7031,6 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu) /* Tell new CPU we are migrated */ p->se.avg.last_update_time = 0; - /* We have migrated, no longer consider this task hot */ - p->se.exec_start = 0; - update_scan_period(p, new_cpu); } From 91d7a4bd5656552d6259e2d0f8859f9e8cc5ef68 Mon Sep 17 00:00:00 2001 From: Jan Kara via Ocfs2-devel Date: Thu, 2 Mar 2023 16:38:43 +0100 Subject: [PATCH 0941/1017] ocfs2: fix data corruption after failed write commit 90410bcf873cf05f54a32183afff0161f44f9715 upstream. When buffered write fails to copy data into underlying page cache page, ocfs2_write_end_nolock() just zeroes out and dirties the page. This can leave dirty page beyond EOF and if page writeback tries to write this page before write succeeds and expands i_size, page gets into inconsistent state where page dirty bit is clear but buffer dirty bits stay set resulting in page data never getting written and so data copied to the page is lost. Fix the problem by invalidating page beyond EOF after failed write. Link: https://lkml.kernel.org/r/20230302153843.18499-1-jack@suse.cz Fixes: 6dbf7bb55598 ("fs: Don't invalidate page buffers in block_write_full_page()") Signed-off-by: Jan Kara Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Gang He Cc: Jun Piao Cc: Signed-off-by: Andrew Morton [ replace block_invalidate_folio to block_invalidatepage ] Signed-off-by: Joseph Qi Signed-off-by: Greg Kroah-Hartman --- fs/ocfs2/aops.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index ad20403b383f..9b23e74036eb 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -1981,11 +1981,25 @@ int ocfs2_write_end_nolock(struct address_space *mapping, } if (unlikely(copied < len) && wc->w_target_page) { + loff_t new_isize; + if (!PageUptodate(wc->w_target_page)) copied = 0; - ocfs2_zero_new_buffers(wc->w_target_page, start+copied, - start+len); + new_isize = max_t(loff_t, i_size_read(inode), pos + copied); + if (new_isize > page_offset(wc->w_target_page)) + ocfs2_zero_new_buffers(wc->w_target_page, start+copied, + start+len); + else { + /* + * When page is fully beyond new isize (data copy + * failed), do not bother zeroing the page. Invalidate + * it instead so that writeback does not get confused + * put page & buffer dirty bits into inconsistent + * state. + */ + block_invalidatepage(wc->w_target_page, 0, PAGE_SIZE); + } } if (wc->w_target_page) flush_dcache_page(wc->w_target_page); From cb61e1e36fb379228d41b6413487e8a33077828c Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 28 Mar 2023 10:35:11 +0300 Subject: [PATCH 0942/1017] xfs: shut down the filesystem if we screw up quota reservation commit 2a4bdfa8558ca2904dc17b83497dc82aa7fc05e9 upstream. If we ever screw up the quota reservations enough to trip the assertions, something's wrong with the quota code. Shut down the filesystem when this happens, because this is corruption. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Amir Goldstein Acked-by: Darrick J. Wong Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_trans_dquot.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 288ea38c43ad..5ca210e6626c 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -16,6 +16,7 @@ #include "xfs_quota.h" #include "xfs_qm.h" #include "xfs_trace.h" +#include "xfs_error.h" STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *); @@ -708,9 +709,11 @@ xfs_trans_dqresv( XFS_TRANS_DQ_RES_INOS, ninos); } - ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count); - ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count); - ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count); + + if (XFS_IS_CORRUPT(mp, dqp->q_blk.reserved < dqp->q_blk.count) || + XFS_IS_CORRUPT(mp, dqp->q_rtb.reserved < dqp->q_rtb.count) || + XFS_IS_CORRUPT(mp, dqp->q_ino.reserved < dqp->q_ino.count)) + goto error_corrupt; xfs_dqunlock(dqp); return 0; @@ -720,6 +723,10 @@ error_return: if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ) return -ENOSPC; return -EDQUOT; +error_corrupt: + xfs_dqunlock(dqp); + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); + return -EFSCORRUPTED; } From a6d345c3a31e1eaef6dbccfd57166a4da97c6dfe Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Tue, 28 Mar 2023 10:35:12 +0300 Subject: [PATCH 0943/1017] xfs: don't reuse busy extents on extent trim commit 06058bc40534530e617e5623775c53bb24f032cb upstream. Freed extents are marked busy from the point the freeing transaction commits until the associated CIL context is checkpointed to the log. This prevents reuse and overwrite of recently freed blocks before the changes are committed to disk, which can lead to corruption after a crash. The exception to this rule is that metadata allocation is allowed to reuse busy extents because metadata changes are also logged. As of commit 97d3ac75e5e0 ("xfs: exact busy extent tracking"), XFS has allowed modification or complete invalidation of outstanding busy extents for metadata allocations. This implementation assumes that use of the associated extent is imminent, which is not always the case. For example, the trimmed extent might not satisfy the minimum length of the allocation request, or the allocation algorithm might be involved in a search for the optimal result based on locality. generic/019 reproduces a corruption caused by this scenario. First, a metadata block (usually a bmbt or symlink block) is freed from an inode. A subsequent bmbt split on an unrelated inode attempts a near mode allocation request that invalidates the busy block during the search, but does not ultimately allocate it. Due to the busy state invalidation, the block is no longer considered busy to subsequent allocation. A direct I/O write request immediately allocates the block and writes to it. Finally, the filesystem crashes while in a state where the initial metadata block free had not committed to the on-disk log. After recovery, the original metadata block is in its original location as expected, but has been corrupted by the aforementioned dio. This demonstrates that it is fundamentally unsafe to modify busy extent state for extents that are not guaranteed to be allocated. This applies to pretty much all of the code paths that currently trim busy extents for one reason or another. Therefore to address this problem, drop the reuse mechanism from the busy extent trim path. This code already knows how to return partial non-busy ranges of the targeted free extent and higher level code tracks the busy state of the allocation attempt. If a block allocation fails where one or more candidate extents is busy, we force the log and retry the allocation. Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Signed-off-by: Amir Goldstein Acked-by: Darrick J. Wong Signed-off-by: Greg Kroah-Hartman --- fs/xfs/xfs_extent_busy.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/fs/xfs/xfs_extent_busy.c b/fs/xfs/xfs_extent_busy.c index 5c2695a42de1..a4075685d9eb 100644 --- a/fs/xfs/xfs_extent_busy.c +++ b/fs/xfs/xfs_extent_busy.c @@ -344,7 +344,6 @@ xfs_extent_busy_trim( ASSERT(*len > 0); spin_lock(&args->pag->pagb_lock); -restart: fbno = *bno; flen = *len; rbp = args->pag->pagb_tree.rb_node; @@ -363,19 +362,6 @@ restart: continue; } - /* - * If this is a metadata allocation, try to reuse the busy - * extent instead of trimming the allocation. - */ - if (!(args->datatype & XFS_ALLOC_USERDATA) && - !(busyp->flags & XFS_EXTENT_BUSY_DISCARDED)) { - if (!xfs_extent_busy_update_extent(args->mp, args->pag, - busyp, fbno, flen, - false)) - goto restart; - continue; - } - if (bbno <= fbno) { /* start overlap */ From 34ef9cd887d573babd5b7f689fc188eff14aa8ed Mon Sep 17 00:00:00 2001 From: Miaohe Lin Date: Tue, 23 Aug 2022 14:34:14 +0800 Subject: [PATCH 0944/1017] KVM: fix memoryleak in kvm_init() commit 5a2a961be2ad6a16eb388a80442443b353c11d16 upstream. When alloc_cpumask_var_node() fails for a certain cpu, there might be some allocated cpumasks for percpu cpu_kick_mask. We should free these cpumasks or memoryleak will occur. Fixes: baff59ccdc65 ("KVM: Pre-allocate cpumasks for kvm_make_all_cpus_request_except()") Signed-off-by: Miaohe Lin Link: https://lore.kernel.org/r/20220823063414.59778-1-linmiaohe@huawei.com Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- virt/kvm/kvm_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d2df08102171..356fd5d1a428 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5014,7 +5014,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, r = kvm_async_pf_init(); if (r) - goto out_free_5; + goto out_free_4; kvm_chardev_ops.owner = module; kvm_vm_fops.owner = module; @@ -5047,10 +5047,9 @@ err_register: kvm_vfio_ops_exit(); err_vfio: kvm_async_pf_deinit(); -out_free_5: +out_free_4: for_each_possible_cpu(cpu) free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); -out_free_4: kmem_cache_destroy(kvm_vcpu_cache); out_free_3: unregister_reboot_notifier(&kvm_reboot_notifier); From 01e4c9c03de8a9f8839cb7342bc4bccf9104efe5 Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Mon, 12 Dec 2022 14:50:11 -0800 Subject: [PATCH 0945/1017] NFSD: fix use-after-free in __nfs42_ssc_open() commit 75333d48f92256a0dec91dbf07835e804fc411c0 upstream. Problem caused by source's vfsmount being unmounted but remains on the delayed unmount list. This happens when nfs42_ssc_open() return errors. Fixed by removing nfsd4_interssc_connect(), leave the vfsmount for the laundromat to unmount when idle time expires. We don't need to call nfs_do_sb_deactive when nfs42_ssc_open return errors since the file was not opened so nfs_server->active was not incremented. Same as in nfsd4_copy, if we fail to launch nfsd4_do_async_copy thread then there's no need to call nfs_do_sb_deactive Reported-by: Xingyuan Mo Signed-off-by: Dai Ngo Tested-by: Xingyuan Mo Signed-off-by: Chuck Lever Signed-off-by: Ovidiu Panait Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4proc.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index f82cfe843b99..3c651cbcf897 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1248,13 +1248,6 @@ out_err: return status; } -static void -nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) -{ - nfs_do_sb_deactive(ss_mnt->mnt_sb); - mntput(ss_mnt); -} - /* * Verify COPY destination stateid. * @@ -1325,11 +1318,6 @@ nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src, { } -static void -nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) -{ -} - static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh, nfs4_stateid *stateid) @@ -1471,14 +1459,14 @@ static int nfsd4_do_async_copy(void *data) copy->nf_src = kzalloc(sizeof(struct nfsd_file), GFP_KERNEL); if (!copy->nf_src) { copy->nfserr = nfserr_serverfault; - nfsd4_interssc_disconnect(copy->ss_mnt); + /* ss_mnt will be unmounted by the laundromat */ goto do_callback; } copy->nf_src->nf_file = nfs42_ssc_open(copy->ss_mnt, ©->c_fh, ©->stateid); if (IS_ERR(copy->nf_src->nf_file)) { copy->nfserr = nfserr_offload_denied; - nfsd4_interssc_disconnect(copy->ss_mnt); + /* ss_mnt will be unmounted by the laundromat */ goto do_callback; } } @@ -1561,8 +1549,10 @@ out_err: if (async_copy) cleanup_async_copy(async_copy); status = nfserrno(-ENOMEM); - if (!copy->cp_intra) - nfsd4_interssc_disconnect(copy->ss_mnt); + /* + * source's vfsmount of inter-copy will be unmounted + * by the laundromat + */ goto out; } From ddb1973e67650dfdc66179b07895b20568a3b251 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Sun, 6 Mar 2022 22:12:51 +0100 Subject: [PATCH 0946/1017] usb: dwc3: gadget: move cmd_endtransfer to extra function [ Upstream commit e192cc7b52399d1b073f88cd3ba128b74d3a57f1 ] This patch adds the extra function __dwc3_stop_active_transfer to consolidate the same codepath. Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20220306211251.2281335-3-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman Stable-dep-of: d8a2bb4eb758 ("usb: dwc3: gadget: Add 1ms delay after end transfer command without IOC") Signed-off-by: Sasha Levin --- drivers/usb/dwc3/gadget.c | 69 +++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 28a1194f849f..ce5131ccd60a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1440,6 +1440,40 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc) return DWC3_DSTS_SOFFN(reg); } +/** + * __dwc3_stop_active_transfer - stop the current active transfer + * @dep: isoc endpoint + * @force: set forcerm bit in the command + * @interrupt: command complete interrupt after End Transfer command + * + * When setting force, the ForceRM bit will be set. In that case + * the controller won't update the TRB progress on command + * completion. It also won't clear the HWO bit in the TRB. + * The command will also not complete immediately in that case. + */ +static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) +{ + struct dwc3_gadget_ep_cmd_params params; + u32 cmd; + int ret; + + cmd = DWC3_DEPCMD_ENDTRANSFER; + cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0; + cmd |= interrupt ? DWC3_DEPCMD_CMDIOC : 0; + cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); + memset(¶ms, 0, sizeof(params)); + ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); + WARN_ON_ONCE(ret); + dep->resource_index = 0; + + if (!interrupt) + dep->flags &= ~DWC3_EP_TRANSFER_STARTED; + else if (!ret) + dep->flags |= DWC3_EP_END_TRANSFER_PENDING; + + return ret; +} + /** * dwc3_gadget_start_isoc_quirk - workaround invalid frame number * @dep: isoc endpoint @@ -1609,21 +1643,8 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) * status, issue END_TRANSFER command and retry on the next XferNotReady * event. */ - if (ret == -EAGAIN) { - struct dwc3_gadget_ep_cmd_params params; - u32 cmd; - - cmd = DWC3_DEPCMD_ENDTRANSFER | - DWC3_DEPCMD_CMDIOC | - DWC3_DEPCMD_PARAM(dep->resource_index); - - dep->resource_index = 0; - memset(¶ms, 0, sizeof(params)); - - ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); - if (!ret) - dep->flags |= DWC3_EP_END_TRANSFER_PENDING; - } + if (ret == -EAGAIN) + ret = __dwc3_stop_active_transfer(dep, false, true); return ret; } @@ -3250,10 +3271,6 @@ static void dwc3_reset_gadget(struct dwc3 *dwc) static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) { - struct dwc3_gadget_ep_cmd_params params; - u32 cmd; - int ret; - if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) || (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) return; @@ -3285,19 +3302,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, * This mode is NOT available on the DWC_usb31 IP. */ - cmd = DWC3_DEPCMD_ENDTRANSFER; - cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0; - cmd |= interrupt ? DWC3_DEPCMD_CMDIOC : 0; - cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); - memset(¶ms, 0, sizeof(params)); - ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); - WARN_ON_ONCE(ret); - dep->resource_index = 0; - - if (!interrupt) - dep->flags &= ~DWC3_EP_TRANSFER_STARTED; - else - dep->flags |= DWC3_EP_END_TRANSFER_PENDING; + __dwc3_stop_active_transfer(dep, force, interrupt); } static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) From a5ce0a559b66b001120af4dfacb75dce4c498c0b Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Mon, 6 Mar 2023 12:05:57 -0800 Subject: [PATCH 0947/1017] usb: dwc3: gadget: Add 1ms delay after end transfer command without IOC [ Upstream commit d8a2bb4eb75866275b5cf7de2e593ac3449643e2 ] Previously, there was a 100uS delay inserted after issuing an end transfer command for specific controller revisions. This was due to the fact that there was a GUCTL2 bit field which enabled synchronous completion of the end transfer command once the CMDACT bit was cleared in the DEPCMD register. Since this bit does not exist for all controller revisions and the current implementation heavily relies on utizling the EndTransfer command completion interrupt, add the delay back in for uses where the interrupt on completion bit is not set, and increase the duration to 1ms for the controller to complete the command. An issue was seen where the USB request buffer was unmapped while the DWC3 controller was still accessing the TRB. However, it was confirmed that the end transfer command was successfully submitted. (no end transfer timeout) In situations, such as dwc3_gadget_soft_disconnect() and __dwc3_gadget_ep_disable(), the dwc3_remove_request() is utilized, which will issue the end transfer command, and follow up with dwc3_gadget_giveback(). At least for the USB ep disable path, it is required for any pending and started requests to be completed and returned to the function driver in the same context of the disable call. Without the GUCTL2 bit, it is not ensured that the end transfer is completed before the buffers are unmapped. Fixes: cf2f8b63f7f1 ("usb: dwc3: gadget: Remove END_TRANSFER delay") Cc: stable Signed-off-by: Wesley Cheng Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20230306200557.29387-1-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/dwc3/gadget.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ce5131ccd60a..01cecde76140 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1453,6 +1453,7 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc) */ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) { + struct dwc3 *dwc = dep->dwc; struct dwc3_gadget_ep_cmd_params params; u32 cmd; int ret; @@ -1466,10 +1467,13 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int WARN_ON_ONCE(ret); dep->resource_index = 0; - if (!interrupt) + if (!interrupt) { + if (!DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC3, 310A)) + mdelay(1); dep->flags &= ~DWC3_EP_TRANSFER_STARTED; - else if (!ret) + } else if (!ret) { dep->flags |= DWC3_EP_END_TRANSFER_PENDING; + } return ret; } @@ -3299,7 +3303,11 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, * enabled, the EndTransfer command will have completed upon * returning from this function. * - * This mode is NOT available on the DWC_usb31 IP. + * This mode is NOT available on the DWC_usb31 IP. In this + * case, if the IOC bit is not set, then delay by 1ms + * after issuing the EndTransfer command. This allows for the + * controller to handle the command completely before DWC3 + * remove requests attempts to unmap USB request buffers. */ __dwc3_stop_active_transfer(dep, force, interrupt); From 46ae204069e7d09b36413e71228820153419150e Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Mon, 28 Nov 2022 11:43:58 +0100 Subject: [PATCH 0948/1017] kernel: kcsan: kcsan_test: build without structleak plugin [ Upstream commit 6fcd4267a840d0536b8e5334ad5f31e4105fce85 ] Building kcsan_test with structleak plugin enabled makes the stack frame size to grow. kernel/kcsan/kcsan_test.c:704:1: error: the frame size of 3296 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] Turn off the structleak plugin checks for kcsan_test. Link: https://lkml.kernel.org/r/20221128104358.2660634-1-anders.roxell@linaro.org Signed-off-by: Anders Roxell Suggested-by: Arnd Bergmann Acked-by: Marco Elver Cc: Arnd Bergmann Cc: David Gow Cc: Jason A. Donenfeld Cc: Kees Cook Signed-off-by: Andrew Morton Stable-dep-of: 5eb39cde1e24 ("kcsan: avoid passing -g for test") Signed-off-by: Sasha Levin --- kernel/kcsan/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/kcsan/Makefile b/kernel/kcsan/Makefile index 65ca5539c470..c95957741d36 100644 --- a/kernel/kcsan/Makefile +++ b/kernel/kcsan/Makefile @@ -14,4 +14,5 @@ obj-y := core.o debugfs.o report.o obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer +CFLAGS_kcsan_test.o += $(DISABLE_STRUCTLEAK_PLUGIN) obj-$(CONFIG_KCSAN_TEST) += kcsan-test.o From f7385e0886cda36050e84b15cae2cdbf61415f3d Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Thu, 16 Mar 2023 23:47:05 +0100 Subject: [PATCH 0949/1017] kcsan: avoid passing -g for test [ Upstream commit 5eb39cde1e2487ba5ec1802dc5e58a77e700d99e ] Nathan reported that when building with GNU as and a version of clang that defaults to DWARF5, the assembler will complain with: Error: non-constant .uleb128 is not supported This is because `-g` defaults to the compiler debug info default. If the assembler does not support some of the directives used, the above errors occur. To fix, remove the explicit passing of `-g`. All the test wants is that stack traces print valid function names, and debug info is not required for that. (I currently cannot recall why I added the explicit `-g`.) Link: https://lkml.kernel.org/r/20230316224705.709984-2-elver@google.com Fixes: 1fe84fd4a402 ("kcsan: Add test suite") Signed-off-by: Marco Elver Reported-by: Nathan Chancellor Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- kernel/kcsan/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kcsan/Makefile b/kernel/kcsan/Makefile index c95957741d36..a9b0ee63b697 100644 --- a/kernel/kcsan/Makefile +++ b/kernel/kcsan/Makefile @@ -13,6 +13,6 @@ CFLAGS_core.o := $(call cc-option,-fno-conserve-stack) \ obj-y := core.o debugfs.o report.o obj-$(CONFIG_KCSAN_SELFTEST) += selftest.o -CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -g -fno-omit-frame-pointer +CFLAGS_kcsan-test.o := $(CFLAGS_KCSAN) -fno-omit-frame-pointer CFLAGS_kcsan_test.o += $(DISABLE_STRUCTLEAK_PLUGIN) obj-$(CONFIG_KCSAN_TEST) += kcsan-test.o From 794a6cea22688db942ee10c258c5f353e7e1649d Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Fri, 31 Dec 2021 00:55:15 +0100 Subject: [PATCH 0950/1017] drm/meson: Fix error handling when afbcd.ops->init fails [ Upstream commit fa747d75f65d1b1cbc3f4691fa67b695e8a399c8 ] When afbcd.ops->init fails we need to free the struct drm_device. Also all errors which come after afbcd.ops->init was successful need to exit the AFBCD, just like meson_drv_unbind() does. Fixes: d1b5e41e13a7e9 ("drm/meson: Add AFBCD module driver") Signed-off-by: Martin Blumenstingl Acked-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20211230235515.1627522-3-martin.blumenstingl@googlemail.com Stable-dep-of: ba98413bf45e ("drm/meson: fix missing component unbind on bind errors") Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_drv.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index b0bfe85f5f6a..090878bd74f6 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -320,38 +320,38 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) if (priv->afbcd.ops) { ret = priv->afbcd.ops->init(priv); if (ret) - return ret; + goto free_drm; } /* Encoder Initialization */ ret = meson_venc_cvbs_create(priv); if (ret) - goto free_drm; + goto exit_afbcd; if (has_components) { ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all components\n"); - goto free_drm; + goto exit_afbcd; } } ret = meson_plane_create(priv); if (ret) - goto free_drm; + goto exit_afbcd; ret = meson_overlay_create(priv); if (ret) - goto free_drm; + goto exit_afbcd; ret = meson_crtc_create(priv); if (ret) - goto free_drm; + goto exit_afbcd; ret = drm_irq_install(drm, priv->vsync_irq); if (ret) - goto free_drm; + goto exit_afbcd; drm_mode_config_reset(drm); @@ -369,6 +369,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) uninstall_irq: drm_irq_uninstall(drm); +exit_afbcd: + if (priv->afbcd.ops) + priv->afbcd.ops->exit(priv); free_drm: drm_dev_put(drm); From 1635a062fa0e045fe9e0eddabdbeff2e66f038d2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 6 Mar 2023 11:35:33 +0100 Subject: [PATCH 0951/1017] drm/meson: fix missing component unbind on bind errors [ Upstream commit ba98413bf45edbf33672e2539e321b851b2cfbd1 ] Make sure to unbind all subcomponents when binding the aggregate device fails. Fixes: a41e82e6c457 ("drm/meson: Add support for components") Cc: stable@vger.kernel.org # 4.12 Cc: Neil Armstrong Signed-off-by: Johan Hovold Acked-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230306103533.4915-1-johan+linaro@kernel.org Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_drv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 090878bd74f6..5c29ddf93eb3 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -339,19 +339,19 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) ret = meson_plane_create(priv); if (ret) - goto exit_afbcd; + goto unbind_all; ret = meson_overlay_create(priv); if (ret) - goto exit_afbcd; + goto unbind_all; ret = meson_crtc_create(priv); if (ret) - goto exit_afbcd; + goto unbind_all; ret = drm_irq_install(drm, priv->vsync_irq); if (ret) - goto exit_afbcd; + goto unbind_all; drm_mode_config_reset(drm); @@ -369,6 +369,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) uninstall_irq: drm_irq_uninstall(drm); +unbind_all: + if (has_components) + component_unbind_all(drm->dev, drm); exit_afbcd: if (priv->afbcd.ops) priv->afbcd.ops->exit(priv); From b2d19565478f45b3055b70b034014a8bc10fdbfc Mon Sep 17 00:00:00 2001 From: Ivan Bornyakov Date: Mon, 6 Mar 2023 16:25:26 +0300 Subject: [PATCH 0952/1017] bus: imx-weim: fix branch condition evaluates to a garbage value [ Upstream commit 1adab2922c58e7ff4fa9f0b43695079402cce876 ] If bus type is other than imx50_weim_devtype and have no child devices, variable 'ret' in function weim_parse_dt() will not be initialized, but will be used as branch condition and return value. Fix this by initializing 'ret' with 0. This was discovered with help of clang-analyzer, but the situation is quite possible in real life. Fixes: 52c47b63412b ("bus: imx-weim: improve error handling upon child probe-failure") Signed-off-by: Ivan Bornyakov Cc: stable@vger.kernel.org Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- drivers/bus/imx-weim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c index 28bb65a5613f..201767823edb 100644 --- a/drivers/bus/imx-weim.c +++ b/drivers/bus/imx-weim.c @@ -192,8 +192,8 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) const struct of_device_id *of_id = of_match_device(weim_id_table, &pdev->dev); const struct imx_weim_devtype *devtype = of_id->data; + int ret = 0, have_child = 0; struct device_node *child; - int ret, have_child = 0; struct cs_timing_state ts = {}; u32 reg; From 0b9493b504fc15c63ec9c7d5b47e669a287837e6 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Wed, 8 Mar 2023 14:39:54 -0500 Subject: [PATCH 0953/1017] dm crypt: avoid accessing uninitialized tasklet [ Upstream commit d9a02e016aaf5a57fb44e9a5e6da8ccd3b9e2e70 ] When neither "no_read_workqueue" nor "no_write_workqueue" are enabled, tasklet_trylock() in crypt_dec_pending() may still return false due to an uninitialized state, and dm-crypt will unnecessarily do io completion in io_queue workqueue instead of current context. Fix this by adding an 'in_tasklet' flag to dm_crypt_io struct and initialize it to false in crypt_io_init(). Set this flag to true in kcryptd_queue_crypt() before calling tasklet_schedule(). If set crypt_dec_pending() will punt io completion to a workqueue. This also nicely avoids the tasklet_trylock/unlock hack when tasklets aren't in use. Fixes: 8e14f610159d ("dm crypt: do not call bio_endio() from the dm-crypt tasklet") Cc: stable@vger.kernel.org Reported-by: Hou Tao Suggested-by: Ignat Korchagin Reviewed-by: Ignat Korchagin Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/dm-crypt.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 17ddca293965..5d772f322a24 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -67,7 +67,9 @@ struct dm_crypt_io { struct crypt_config *cc; struct bio *base_bio; u8 *integrity_metadata; - bool integrity_metadata_from_pool; + bool integrity_metadata_from_pool:1; + bool in_tasklet:1; + struct work_struct work; struct tasklet_struct tasklet; @@ -1722,6 +1724,7 @@ static void crypt_io_init(struct dm_crypt_io *io, struct crypt_config *cc, io->ctx.r.req = NULL; io->integrity_metadata = NULL; io->integrity_metadata_from_pool = false; + io->in_tasklet = false; atomic_set(&io->io_pending, 0); } @@ -1767,14 +1770,13 @@ static void crypt_dec_pending(struct dm_crypt_io *io) * our tasklet. In this case we need to delay bio_endio() * execution to after the tasklet is done and dequeued. */ - if (tasklet_trylock(&io->tasklet)) { - tasklet_unlock(&io->tasklet); - bio_endio(base_bio); + if (io->in_tasklet) { + INIT_WORK(&io->work, kcryptd_io_bio_endio); + queue_work(cc->io_queue, &io->work); return; } - INIT_WORK(&io->work, kcryptd_io_bio_endio); - queue_work(cc->io_queue, &io->work); + bio_endio(base_bio); } /* @@ -2228,6 +2230,7 @@ static void kcryptd_queue_crypt(struct dm_crypt_io *io) * it is being executed with irqs disabled. */ if (in_irq() || irqs_disabled()) { + io->in_tasklet = true; tasklet_init(&io->tasklet, kcryptd_crypt_tasklet, (unsigned long)&io->work); tasklet_schedule(&io->tasklet); return; From 10941fd5c3e18e7958f2bca3904f6972d29b362a Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 14 Mar 2023 16:31:32 -0700 Subject: [PATCH 0954/1017] fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY [ Upstream commit a075bacde257f755bea0e53400c9f1cdd1b8e8e6 ] The full pagecache drop at the end of FS_IOC_ENABLE_VERITY is causing performance problems and is hindering adoption of fsverity. It was intended to solve a race condition where unverified pages might be left in the pagecache. But actually it doesn't solve it fully. Since the incomplete solution for this race condition has too much performance impact for it to be worth it, let's remove it for now. Fixes: 3fda4c617e84 ("fs-verity: implement FS_IOC_ENABLE_VERITY ioctl") Cc: stable@vger.kernel.org Reviewed-by: Victor Hsieh Link: https://lore.kernel.org/r/20230314235332.50270-1-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Sasha Levin --- fs/verity/enable.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/fs/verity/enable.c b/fs/verity/enable.c index 734862e608fd..5ceae66e1ae0 100644 --- a/fs/verity/enable.c +++ b/fs/verity/enable.c @@ -391,25 +391,27 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg) goto out_drop_write; err = enable_verity(filp, &arg); - if (err) - goto out_allow_write_access; /* - * Some pages of the file may have been evicted from pagecache after - * being used in the Merkle tree construction, then read into pagecache - * again by another process reading from the file concurrently. Since - * these pages didn't undergo verification against the file measurement - * which fs-verity now claims to be enforcing, we have to wipe the - * pagecache to ensure that all future reads are verified. + * We no longer drop the inode's pagecache after enabling verity. This + * used to be done to try to avoid a race condition where pages could be + * evicted after being used in the Merkle tree construction, then + * re-instantiated by a concurrent read. Such pages are unverified, and + * the backing storage could have filled them with different content, so + * they shouldn't be used to fulfill reads once verity is enabled. + * + * But, dropping the pagecache has a big performance impact, and it + * doesn't fully solve the race condition anyway. So for those reasons, + * and also because this race condition isn't very important relatively + * speaking (especially for small-ish files, where the chance of a page + * being used, evicted, *and* re-instantiated all while enabling verity + * is quite small), we no longer drop the inode's pagecache. */ - filemap_write_and_wait(inode->i_mapping); - invalidate_inode_pages2(inode->i_mapping); /* * allow_write_access() is needed to pair with deny_write_access(). * Regardless, the filesystem won't allow writing to verity files. */ -out_allow_write_access: allow_write_access(filp); out_drop_write: mnt_drop_write_file(filp); From 74d6d33f3695070850cc15d3058d1315fb94d380 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 6 Mar 2023 09:36:25 +1100 Subject: [PATCH 0955/1017] md: avoid signed overflow in slot_store() [ Upstream commit 3bc57292278a0b6ac4656cad94c14f2453344b57 ] slot_store() uses kstrtouint() to get a slot number, but stores the result in an "int" variable (by casting a pointer). This can result in a negative slot number if the unsigned int value is very large. A negative number means that the slot is empty, but setting a negative slot number this way will not remove the device from the array. I don't think this is a serious problem, but it could cause confusion and it is best to fix it. Reported-by: Dan Carpenter Signed-off-by: NeilBrown Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/md.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index c0b34637bd66..1553c2495841 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3207,6 +3207,9 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len) err = kstrtouint(buf, 10, (unsigned int *)&slot); if (err < 0) return err; + if (slot < 0) + /* overflow */ + return -ENOSPC; } if (rdev->mddev->pers && slot == -1) { /* Setting 'slot' on an active array requires also From b94ffa287415e3950b2fd846c9a10420533f7ef1 Mon Sep 17 00:00:00 2001 From: Kristian Overskeid Date: Tue, 7 Mar 2023 14:32:29 +0100 Subject: [PATCH 0956/1017] net: hsr: Don't log netdev_err message on unknown prp dst node [ Upstream commit 28e8cabe80f3e6e3c98121576eda898eeb20f1b1 ] If no frames has been exchanged with a node for HSR_NODE_FORGET_TIME, the node will be deleted from the node_db list. If a frame is sent to the node after it is deleted, a netdev_err message for each slave interface is produced. This should not happen with dan nodes because of supervision frames, but can happen often with san nodes, which clutters the kernel log. Since the hsr protocol does not support sans, this is only relevant for the prp protocol. Signed-off-by: Kristian Overskeid Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/hsr/hsr_framereg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 20cb6b7dbc69..08627c836884 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -380,7 +380,7 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb, node_dst = find_node_by_addr_A(&port->hsr->node_db, eth_hdr(skb)->h_dest); if (!node_dst) { - if (net_ratelimit()) + if (net_ratelimit() && port->hsr->prot_version != PRP_V1) netdev_err(skb->dev, "%s: Unknown node\n", __func__); return; } From fcf80111a4f69c85e5b393870f7fc4374d383334 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 13 Mar 2023 00:49:24 +0000 Subject: [PATCH 0957/1017] ALSA: asihpi: check pao in control_message() [ Upstream commit 9026c0bf233db53b86f74f4c620715e94eb32a09 ] control_message() might be called with pao = NULL. Here indicates control_message() as sample. (B) static void control_message(struct hpi_adapter_obj *pao, ...) { ^^^ struct hpi_hw_obj *phw = pao->priv; ... ^^^ } (A) void _HPI_6205(struct hpi_adapter_obj *pao, ...) { ^^^ ... case HPI_OBJ_CONTROL: (B) control_message(pao, phm, phr); break; ^^^ ... } void HPI_6205(...) { ... (A) _HPI_6205(NULL, phm, phr); ... ^^^^ } Therefore, We will get too many warning via cppcheck, like below sound/pci/asihpi/hpi6205.c:238:27: warning: Possible null pointer dereference: pao [nullPointer] struct hpi_hw_obj *phw = pao->priv; ^ sound/pci/asihpi/hpi6205.c:433:13: note: Calling function '_HPI_6205', 1st argument 'NULL' value is 0 _HPI_6205(NULL, phm, phr); ^ sound/pci/asihpi/hpi6205.c:401:20: note: Calling function 'control_message', 1st argument 'pao' value is 0 control_message(pao, phm, phr); ^ Set phr->error like many functions doing, and don't call _HPI_6205() with NULL. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87ttypeaqz.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/asihpi/hpi6205.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 3d6914c64c4a..4cdaeefeb688 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -430,7 +430,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) pao = hpi_find_adapter(phm->adapter_index); } else { /* subsys messages don't address an adapter */ - _HPI_6205(NULL, phm, phr); + phr->error = HPI_ERROR_INVALID_OBJ_INDEX; return; } From baef27176ea5fdc7ad0947e2dc7733855e35db71 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 13 Mar 2023 00:50:28 +0000 Subject: [PATCH 0958/1017] ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set() [ Upstream commit 98e5eb110095ec77cb6d775051d181edbf9cd3cf ] tuning_ctl_set() might have buffer overrun at (X) if it didn't break from loop by matching (A). static int tuning_ctl_set(...) { for (i = 0; i < TUNING_CTLS_COUNT; i++) (A) if (nid == ca0132_tuning_ctls[i].nid) break; snd_hda_power_up(...); (X) dspio_set_param(..., ca0132_tuning_ctls[i].mid, ...); snd_hda_power_down(...); ^ return 1; } We will get below error by cppcheck sound/pci/hda/patch_ca0132.c:4229:2: note: After for loop, i has value 12 for (i = 0; i < TUNING_CTLS_COUNT; i++) ^ sound/pci/hda/patch_ca0132.c:4234:43: note: Array index out of bounds dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20, ^ This patch cares non match case. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87sfe9eap7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/patch_ca0132.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 24c2638cde37..6057084da4cf 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4108,8 +4108,10 @@ static int tuning_ctl_set(struct hda_codec *codec, hda_nid_t nid, for (i = 0; i < TUNING_CTLS_COUNT; i++) if (nid == ca0132_tuning_ctls[i].nid) - break; + goto found; + return -EINVAL; +found: snd_hda_power_up(codec); dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20, ca0132_tuning_ctls[i].req, From 6eaa2254cc5ed8fbc583186083fc87e8aece759a Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Tue, 7 Mar 2023 13:08:56 +0000 Subject: [PATCH 0959/1017] fbdev: tgafb: Fix potential divide by zero [ Upstream commit f90bd245de82c095187d8c2cabb8b488a39eaecc ] fb_set_var would by called when user invokes ioctl with cmd FBIOPUT_VSCREENINFO. User-provided data would finally reach tgafb_check_var. In case var->pixclock is assigned to zero, divide by zero would occur when checking whether reciprocal of var->pixclock is too high. Similar crashes have happened in other fbdev drivers. There is no check and modification on var->pixclock along the call chain to tgafb_check_var. We believe it could also be triggered in driver tgafb from user site. Signed-off-by: Wei Chen Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/tgafb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c index 666fbe2f671c..98a2977fd427 100644 --- a/drivers/video/fbdev/tgafb.c +++ b/drivers/video/fbdev/tgafb.c @@ -166,6 +166,9 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct tga_par *par = (struct tga_par *)info->par; + if (!var->pixclock) + return -EINVAL; + if (par->tga_type == TGA_TYPE_8PLANE) { if (var->bits_per_pixel != 8) return -EINVAL; From 1f2a94baee431c73b7e2a3230b1adafef6128000 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 14 Mar 2023 19:32:38 -0700 Subject: [PATCH 0960/1017] sched_getaffinity: don't assume 'cpumask_size()' is fully initialized [ Upstream commit 6015b1aca1a233379625385feb01dd014aca60b5 ] The getaffinity() system call uses 'cpumask_size()' to decide how big the CPU mask is - so far so good. It is indeed the allocation size of a cpumask. But the code also assumes that the whole allocation is initialized without actually doing so itself. That's wrong, because we might have fixed-size allocations (making copying and clearing more efficient), but not all of it is then necessarily used if 'nr_cpu_ids' is smaller. Having checked other users of 'cpumask_size()', they all seem to be ok, either using it purely for the allocation size, or explicitly zeroing the cpumask before using the size in bytes to copy it. See for example the ublk_ctrl_get_queue_affinity() function that uses the proper 'zalloc_cpumask_var()' to make sure that the whole mask is cleared, whether the storage is on the stack or if it was an external allocation. Fix this by just zeroing the allocation before using it. Do the same for the compat version of sched_getaffinity(), which had the same logic. Also, for consistency, make sched_getaffinity() use 'cpumask_bits()' to access the bits. For a cpumask_var_t, it ends up being a pointer to the same data either way, but it's just a good idea to treat it like you would a 'cpumask_t'. The compat case already did that. Reported-by: Ryan Roberts Link: https://lore.kernel.org/lkml/7d026744-6bd6-6827-0471-b5e8eae0be3f@arm.com/ Cc: Yury Norov Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- kernel/compat.c | 2 +- kernel/sched/core.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/compat.c b/kernel/compat.c index 05adfd6fa8bf..f9f7a79e07c5 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -152,7 +152,7 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len, if (len & (sizeof(compat_ulong_t)-1)) return -EINVAL; - if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; ret = sched_getaffinity(pid, mask); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index abea8fb7bdd1..b4bd02d68185 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6067,14 +6067,14 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, if (len & (sizeof(unsigned long)-1)) return -EINVAL; - if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) return -ENOMEM; ret = sched_getaffinity(pid, mask); if (ret == 0) { unsigned int retlen = min(len, cpumask_size()); - if (copy_to_user(user_mask_ptr, mask, retlen)) + if (copy_to_user(user_mask_ptr, cpumask_bits(mask), retlen)) ret = -EFAULT; else ret = retlen; From 78eb964805f9ed40270a3c9339d68d7715cea18f Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Wed, 15 Mar 2023 07:18:31 +0000 Subject: [PATCH 0961/1017] fbdev: nvidia: Fix potential divide by zero [ Upstream commit 92e2a00f2987483e1f9253625828622edd442e61 ] variable var->pixclock can be set by user. In case it equals to zero, divide by zero would occur in nvidiafb_set_par. Similar crashes have happened in other fbdev drivers. There is no check and modification on var->pixclock along the call chain to nvidia_check_var and nvidiafb_set_par. We believe it could also be triggered in driver nvidia from user site. Signed-off-by: Wei Chen Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/nvidia/nvidia.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index a372a183c1f0..f9c388a8c10e 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -763,6 +763,8 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var, int pitch, err = 0; NVTRACE_ENTER(); + if (!var->pixclock) + return -EINVAL; var->transp.offset = 0; var->transp.length = 0; From c2be7f80562dcc82382857cecc97d4c23c1140cf Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Wed, 15 Mar 2023 08:33:47 +0000 Subject: [PATCH 0962/1017] fbdev: intelfb: Fix potential divide by zero [ Upstream commit d823685486a3446d061fed7c7d2f80af984f119a ] Variable var->pixclock is controlled by user and can be assigned to zero. Without proper check, divide by zero would occur in intelfbhw_validate_mode and intelfbhw_mode_to_hw. Error out if var->pixclock is zero. Signed-off-by: Wei Chen Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/intelfb/intelfbdrv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c index a9579964eaba..8a703adfa936 100644 --- a/drivers/video/fbdev/intelfb/intelfbdrv.c +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c @@ -1214,6 +1214,9 @@ static int intelfb_check_var(struct fb_var_screeninfo *var, dinfo = GET_DINFO(info); + if (!var->pixclock) + return -EINVAL; + /* update the pitch */ if (intelfbhw_validate_mode(dinfo, var) != 0) return -EINVAL; From ce5551db36294764bdbda7d2bf794d13d5dd352c Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Wed, 15 Mar 2023 09:05:18 +0000 Subject: [PATCH 0963/1017] fbdev: lxfb: Fix potential divide by zero [ Upstream commit 61ac4b86a4c047c20d5cb423ddd87496f14d9868 ] var->pixclock can be assigned to zero by user. Without proper check, divide by zero would occur in lx_set_clock. Error out if var->pixclock is zero. Signed-off-by: Wei Chen Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/geode/lxfb_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c index 66c81262d18f..6c6b6efb49f6 100644 --- a/drivers/video/fbdev/geode/lxfb_core.c +++ b/drivers/video/fbdev/geode/lxfb_core.c @@ -234,6 +234,9 @@ static void get_modedb(struct fb_videomode **modedb, unsigned int *size) static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { + if (!var->pixclock) + return -EINVAL; + if (var->xres > 1920 || var->yres > 1440) return -EINVAL; From 5ec5680dc656c80e4004969299bc6f27e2291434 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Wed, 15 Mar 2023 09:22:54 +0000 Subject: [PATCH 0964/1017] fbdev: au1200fb: Fix potential divide by zero [ Upstream commit 44a3b36b42acfc433aaaf526191dd12fbb919fdb ] var->pixclock can be assigned to zero by user. Without proper check, divide by zero would occur when invoking macro PICOS2KHZ in au1200fb_fb_check_var. Error out if var->pixclock is zero. Signed-off-by: Wei Chen Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/au1200fb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index c00e01a17368..a8a0a448cdb5 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1040,6 +1040,9 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, u32 pixclock; int screen_size, plane; + if (!var->pixclock) + return -EINVAL; + plane = fbdev->plane; /* Make sure that the mode respect all LCD controller and From 038765a095fd6dc13128c0d350c53d89ace690dc Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 15 Dec 2022 10:18:16 -0500 Subject: [PATCH 0965/1017] tools/power turbostat: Fix /dev/cpu_dma_latency warnings [ Upstream commit 40aafc7d58d3544f152a863a0e9863014b6d5d8c ] When running as non-root the following error is seen in turbostat: turbostat: fopen /dev/cpu_dma_latency : Permission denied turbostat and the man page have information on how to avoid other permission errors, so these can be fixed the same way. Provide better /dev/cpu_dma_latency warnings that provide instructions on how to avoid the error, and update the man page. Signed-off-by: Prarit Bhargava Cc: linux-pm@vger.kernel.org Signed-off-by: Len Brown Signed-off-by: Sasha Levin --- tools/power/x86/turbostat/turbostat.8 | 2 ++ tools/power/x86/turbostat/turbostat.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index f6b7e85b121c..71e3f3a68b9d 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -294,6 +294,8 @@ Alternatively, non-root users can be enabled to run turbostat this way: # chmod +r /dev/cpu/*/msr +# chmod +r /dev/cpu_dma_latency + .B "turbostat " reads hardware counters, but doesn't write them. So it will not interfere with the OS or other programs, including diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index ef65f7eed1ec..d33c9d427e57 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -5004,7 +5004,7 @@ void print_dev_latency(void) retval = read(fd, (void *)&value, sizeof(int)); if (retval != sizeof(int)) { - warn("read %s\n", path); + warn("read failed %s\n", path); close(fd); return; } From 8b1269b709c9d3314cb2c6283474c4e5340621b7 Mon Sep 17 00:00:00 2001 From: Anton Gusev Date: Tue, 31 Jan 2023 10:58:18 +0300 Subject: [PATCH 0966/1017] tracing: Fix wrong return in kprobe_event_gen_test.c [ Upstream commit bc4f359b3b607daac0290d0038561237a86b38cb ] Overwriting the error code with the deletion result may cause the function to return 0 despite encountering an error. Commit b111545d26c0 ("tracing: Remove the useless value assignment in test_create_synth_event()") solves a similar issue by returning the original error code, so this patch does the same. Found by Linux Verification Center (linuxtesting.org) with SVACE. Link: https://lore.kernel.org/linux-trace-kernel/20230131075818.5322-1-aagusev@ispras.ru Signed-off-by: Anton Gusev Reviewed-by: Steven Rostedt (Google) Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/kprobe_event_gen_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c index c736487fc0e4..e0c420eb0b2b 100644 --- a/kernel/trace/kprobe_event_gen_test.c +++ b/kernel/trace/kprobe_event_gen_test.c @@ -146,7 +146,7 @@ static int __init test_gen_kprobe_cmd(void) if (trace_event_file_is_valid(gen_kprobe_test)) gen_kprobe_test = NULL; /* We got an error after creating the event, delete it */ - ret = kprobe_event_delete("gen_kprobe_test"); + kprobe_event_delete("gen_kprobe_test"); goto out; } @@ -211,7 +211,7 @@ static int __init test_gen_kretprobe_cmd(void) if (trace_event_file_is_valid(gen_kretprobe_test)) gen_kretprobe_test = NULL; /* We got an error after creating the event, delete it */ - ret = kprobe_event_delete("gen_kretprobe_test"); + kprobe_event_delete("gen_kretprobe_test"); goto out; } From ac63f78d9aca3cd10802b2d9e6c12a3f03b262c7 Mon Sep 17 00:00:00 2001 From: Harshit Mogalapalli Date: Mon, 6 Mar 2023 11:18:24 -0800 Subject: [PATCH 0967/1017] ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx() [ Upstream commit 748b2f5e82d17480404b3e2895388fc2925f7caf ] mac_len is of type unsigned, which can never be less than zero. mac_len = ieee802154_hdr_peek_addrs(skb, &header); if (mac_len < 0) return mac_len; Change this to type int as ieee802154_hdr_peek_addrs() can return negative integers, this is found by static analysis with smatch. Fixes: 6c993779ea1d ("ca8210: fix mac_len negative array access") Signed-off-by: Harshit Mogalapalli Acked-by: Alexander Aring Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230306191824.4115839-1-harshit.m.mogalapalli@oracle.com Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin --- drivers/net/ieee802154/ca8210.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index 5beb447529f9..1c5d70c60354 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -1945,10 +1945,9 @@ static int ca8210_skb_tx( struct ca8210_priv *priv ) { - int status; struct ieee802154_hdr header = { }; struct secspec secspec; - unsigned int mac_len; + int mac_len, status; dev_dbg(&priv->spi->dev, "%s called\n", __func__); From 47a449ec09b4479b89dcc6b27ec3829fc82ffafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 17 Mar 2023 11:20:04 +0100 Subject: [PATCH 0968/1017] mips: bmips: BCM6358: disable RAC flush for TP1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ab327f8acdf8d06601fbf058859a539a9422afff ] RAC flush causes kernel panics on BCM6358 with EHCI/OHCI when booting from TP1: [ 3.881739] usb 1-1: new high-speed USB device number 2 using ehci-platform [ 3.895011] Reserved instruction in kernel code[#1]: [ 3.900113] CPU: 0 PID: 1 Comm: init Not tainted 5.10.16 #0 [ 3.905829] $ 0 : 00000000 10008700 00000000 77d94060 [ 3.911238] $ 4 : 7fd1f088 00000000 81431cac 81431ca0 [ 3.916641] $ 8 : 00000000 ffffefff 8075cd34 00000000 [ 3.922043] $12 : 806f8d40 f3e812b7 00000000 000d9aaa [ 3.927446] $16 : 7fd1f068 7fd1f080 7ff559b8 81428470 [ 3.932848] $20 : 00000000 00000000 55590000 77d70000 [ 3.938251] $24 : 00000018 00000010 [ 3.943655] $28 : 81430000 81431e60 81431f28 800157fc [ 3.949058] Hi : 00000000 [ 3.952013] Lo : 00000000 [ 3.955019] epc : 80015808 setup_sigcontext+0x54/0x24c [ 3.960464] ra : 800157fc setup_sigcontext+0x48/0x24c [ 3.965913] Status: 10008703 KERNEL EXL IE [ 3.970216] Cause : 00800028 (ExcCode 0a) [ 3.974340] PrId : 0002a010 (Broadcom BMIPS4350) [ 3.979170] Modules linked in: ohci_platform ohci_hcd fsl_mph_dr_of ehci_platform ehci_fsl ehci_hcd gpio_button_hotplug usbcore nls_base usb_common [ 3.992907] Process init (pid: 1, threadinfo=(ptrval), task=(ptrval), tls=77e22ec8) [ 4.000776] Stack : 81431ef4 7fd1f080 81431f28 81428470 7fd1f068 81431edc 7ff559b8 81428470 [ 4.009467] 81431f28 7fd1f080 55590000 77d70000 77d5498c 80015c70 806f0000 8063ae74 [ 4.018149] 08100002 81431f28 0000000a 08100002 81431f28 0000000a 77d6b418 00000003 [ 4.026831] ffffffff 80016414 80080734 81431ecc 81431ecc 00000001 00000000 04000000 [ 4.035512] 77d54874 00000000 00000000 00000000 00000000 00000012 00000002 00000000 [ 4.044196] ... [ 4.046706] Call Trace: [ 4.049238] [<80015808>] setup_sigcontext+0x54/0x24c [ 4.054356] [<80015c70>] setup_frame+0xdc/0x124 [ 4.059015] [<80016414>] do_notify_resume+0x1dc/0x288 [ 4.064207] [<80011b50>] work_notifysig+0x10/0x18 [ 4.069036] [ 4.070538] Code: 8fc300b4 00001025 26240008 ac830004 3c048063 0c0228aa 24846a00 26240010 [ 4.080686] [ 4.082517] ---[ end trace 22a8edb41f5f983b ]--- [ 4.087374] Kernel panic - not syncing: Fatal exception [ 4.092753] Rebooting in 1 seconds.. Because the bootloader (CFE) is not initializing the Read-ahead cache properly on the second thread (TP1). Since the RAC was not initialized properly, we should avoid flushing it at the risk of corrupting the instruction stream as seen in the trace above. Fixes: d59098a0e9cb ("MIPS: bmips: use generic dma noncoherent ops") Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/bmips/dma.c | 5 +++++ arch/mips/bmips/setup.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c index 49061b870680..daef44f68298 100644 --- a/arch/mips/bmips/dma.c +++ b/arch/mips/bmips/dma.c @@ -64,6 +64,8 @@ phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dma_addr) return dma_addr; } +bool bmips_rac_flush_disable; + void arch_sync_dma_for_cpu_all(void) { void __iomem *cbr = BMIPS_GET_CBR(); @@ -74,6 +76,9 @@ void arch_sync_dma_for_cpu_all(void) boot_cpu_type() != CPU_BMIPS4380) return; + if (unlikely(bmips_rac_flush_disable)) + return; + /* Flush stale data out of the readahead cache */ cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG); diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index 1b06b25aea87..16063081d61e 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c @@ -34,6 +34,8 @@ #define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c)) #define BCM6328_TP1_DISABLED BIT(9) +extern bool bmips_rac_flush_disable; + static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000; struct bmips_quirk { @@ -103,6 +105,12 @@ static void bcm6358_quirks(void) * disable SMP for now */ bmips_smp_enabled = 0; + + /* + * RAC flush causes kernel panics on BCM6358 when booting from TP1 + * because the bootloader is not initializing it properly. + */ + bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)); } static void bcm6368_quirks(void) From 4a81e2da7297f0518e27308f8fcc41db380d4fbc Mon Sep 17 00:00:00 2001 From: Arseniy Krasnov Date: Mon, 13 Mar 2023 10:32:44 +0300 Subject: [PATCH 0969/1017] mtd: rawnand: meson: invalidate cache on polling ECC bit [ Upstream commit e732e39ed9929c05fd219035bc9653ba4100d4fa ] 'info_buf' memory is cached and driver polls ECC bit in it. This bit is set by the NAND controller. If 'usleep_range()' returns before device sets this bit, 'info_buf' will be cached and driver won't see update of this bit and will loop forever. Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller") Signed-off-by: Arseniy Krasnov Reviewed-by: Neil Armstrong Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/d4ef0bd6-816e-f6fa-9385-f05f775f0ae2@sberdevices.ru Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/meson_nand.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index 38f490088d76..dc631c514318 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -172,6 +172,7 @@ struct meson_nfc { dma_addr_t daddr; dma_addr_t iaddr; + u32 info_bytes; unsigned long assigned_cs; }; @@ -499,6 +500,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, nfc->daddr, datalen, dir); return ret; } + nfc->info_bytes = infolen; cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); writel(cmd, nfc->reg_base + NFC_REG_CMD); @@ -516,8 +518,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand, struct meson_nfc *nfc = nand_get_controller_data(nand); dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); - if (infolen) + if (infolen) { dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); + nfc->info_bytes = 0; + } } static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) @@ -706,6 +710,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc, usleep_range(10, 15); /* info is updated by nfc dma engine*/ smp_rmb(); + dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes, + DMA_FROM_DEVICE); ret = *info & ECC_COMPLETE; } while (!ret); } From 059c3a7a3d6ddc48f6b93c21bdfb6585bc2a6888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= Date: Thu, 23 Mar 2023 09:34:17 +0100 Subject: [PATCH 0970/1017] sfc: ef10: don't overwrite offload features at NIC reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ca4a80e4bb7e87daf33b27d2ab9e4f5311018a89 ] At NIC reset, some offload features related to encapsulated traffic might have changed (this mainly happens if the firmware-variant is changed with the sfboot userspace tool). Because of this, features are checked and set again at reset time. However, this was not done right, and some features were improperly overwritten at NIC reset: - Tunneled IPv6 segmentation was always disabled - Features disabled with ethtool were reenabled - Features that becomes unsupported after the reset were not disabled Also, checking if the device supports IPV6_CSUM to enable TSO6 is no longer necessary because all currently supported devices support it. Additionally, move the assignment of some other features to the EF10_OFFLOAD_FEATURES macro, like it is done in ef100, leaving the selection of features in efx_pci_probe_post_io a bit cleaner. Fixes: ffffd2454a7a ("sfc: correctly advertise tunneled IPv6 segmentation") Fixes: 24b2c3751aa3 ("sfc: advertise encapsulated offloads on EF10") Reported-by: Tianhao Zhao Suggested-by: Jonathan Cooper Tested-by: Jonathan Cooper Signed-off-by: Íñigo Huguet Acked-by: Edward Cree Link: https://lore.kernel.org/r/20230323083417.7345-1-ihuguet@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/sfc/ef10.c | 40 ++++++++++++++++++++++----------- drivers/net/ethernet/sfc/efx.c | 17 ++++++-------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index eb1be7302082..32654fe1f8b5 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1304,7 +1304,8 @@ static void efx_ef10_fini_nic(struct efx_nic *efx) static int efx_ef10_init_nic(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data; - netdev_features_t hw_enc_features = 0; + struct net_device *net_dev = efx->net_dev; + netdev_features_t tun_feats, tso_feats; int rc; if (nic_data->must_check_datapath_caps) { @@ -1349,20 +1350,30 @@ static int efx_ef10_init_nic(struct efx_nic *efx) nic_data->must_restore_piobufs = false; } - /* add encapsulated checksum offload features */ + /* encap features might change during reset if fw variant changed */ if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx)) - hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - /* add encapsulated TSO features */ + net_dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + else + net_dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + + tun_feats = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE | + NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM; + tso_feats = NETIF_F_TSO | NETIF_F_TSO6; + if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) { - netdev_features_t encap_tso_features; - - encap_tso_features = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM; - - hw_enc_features |= encap_tso_features | NETIF_F_TSO; - efx->net_dev->features |= encap_tso_features; + /* If this is first nic_init, or if it is a reset and a new fw + * variant has added new features, enable them by default. + * If the features are not new, maintain their current value. + */ + if (!(net_dev->hw_features & tun_feats)) + net_dev->features |= tun_feats; + net_dev->hw_enc_features |= tun_feats | tso_feats; + net_dev->hw_features |= tun_feats; + } else { + net_dev->hw_enc_features &= ~(tun_feats | tso_feats); + net_dev->hw_features &= ~tun_feats; + net_dev->features &= ~tun_feats; } - efx->net_dev->hw_enc_features = hw_enc_features; /* don't fail init if RSS setup doesn't work */ rc = efx->type->rx_push_rss_config(efx, false, @@ -3977,7 +3988,10 @@ static unsigned int ef10_check_caps(const struct efx_nic *efx, NETIF_F_HW_VLAN_CTAG_FILTER | \ NETIF_F_IPV6_CSUM | \ NETIF_F_RXHASH | \ - NETIF_F_NTUPLE) + NETIF_F_NTUPLE | \ + NETIF_F_SG | \ + NETIF_F_RXCSUM | \ + NETIF_F_RXALL) const struct efx_nic_type efx_hunt_a0_vf_nic_type = { .is_vf = true, diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 29c8d2c99004..c069659c9e2d 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1045,21 +1045,18 @@ static int efx_pci_probe_post_io(struct efx_nic *efx) } /* Determine netdevice features */ - net_dev->features |= (efx->type->offload_features | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL); - if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) { - net_dev->features |= NETIF_F_TSO6; - if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) - net_dev->hw_enc_features |= NETIF_F_TSO6; - } - /* Check whether device supports TSO */ - if (!efx->type->tso_versions || !efx->type->tso_versions(efx)) - net_dev->features &= ~NETIF_F_ALL_TSO; + net_dev->features |= efx->type->offload_features; + + /* Add TSO features */ + if (efx->type->tso_versions && efx->type->tso_versions(efx)) + net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6; + /* Mask for features that also apply to VLAN devices */ net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_ALL_TSO | NETIF_F_RXCSUM); + /* Determine user configurable features */ net_dev->hw_features |= net_dev->features & ~efx->fixed_features; /* Disable receiving frames with bad FCS, by default. */ From 6ff4a54c0218a2e23b808648a3c0689589d0c502 Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Fri, 24 Mar 2023 16:01:34 +0100 Subject: [PATCH 0971/1017] scsi: megaraid_sas: Fix crash after a double completion [ Upstream commit 2309df27111a51734cb9240b4d3c25f2f3c6ab06 ] When a physical disk is attached directly "without JBOD MAP support" (see megasas_get_tm_devhandle()) then there is no real error handling in the driver. Return FAILED instead of SUCCESS. Fixes: 18365b138508 ("megaraid_sas: Task management support") Signed-off-by: Tomas Henzl Link: https://lore.kernel.org/r/20230324150134.14696-1-thenzl@redhat.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 7838c7911add..8eb126d48462 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -4656,7 +4656,7 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd) devhandle = megasas_get_tm_devhandle(scmd->device); if (devhandle == (u16)ULONG_MAX) { - ret = SUCCESS; + ret = FAILED; sdev_printk(KERN_INFO, scmd->device, "task abort issued for invalid devhandle\n"); mutex_unlock(&instance->reset_mutex); @@ -4726,7 +4726,7 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd) devhandle = megasas_get_tm_devhandle(scmd->device); if (devhandle == (u16)ULONG_MAX) { - ret = SUCCESS; + ret = FAILED; sdev_printk(KERN_INFO, scmd->device, "target reset issued for invalid devhandle\n"); mutex_unlock(&instance->reset_mutex); From 3907fcb5a439933cf8c10d6dc300bc11eba30de3 Mon Sep 17 00:00:00 2001 From: SongJingyi Date: Fri, 24 Mar 2023 11:14:06 +0800 Subject: [PATCH 0972/1017] ptp_qoriq: fix memory leak in probe() [ Upstream commit f33642224e38d7e0d59336e10e7b4e370b1c4506 ] Smatch complains that: drivers/ptp/ptp_qoriq.c ptp_qoriq_probe() warn: 'base' from ioremap() not released. Fix this by revising the parameter from 'ptp_qoriq->base' to 'base'. This is only a bug if ptp_qoriq_init() returns on the first -ENODEV error path. For other error paths ptp_qoriq->base and base are the same. And this change makes the code more readable. Fixes: 7f4399ba405b ("ptp_qoriq: fix NULL access if ptp dt node missing") Signed-off-by: SongJingyi Reviewed-by: Dan Carpenter Reviewed-by: Dongliang Mu Link: https://lore.kernel.org/r/20230324031406.1895159-1-u201912584@hust.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/ptp/ptp_qoriq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c index 08f4cf0ad9e3..8fa9772acf79 100644 --- a/drivers/ptp/ptp_qoriq.c +++ b/drivers/ptp/ptp_qoriq.c @@ -601,7 +601,7 @@ static int ptp_qoriq_probe(struct platform_device *dev) return 0; no_clock: - iounmap(ptp_qoriq->base); + iounmap(base); no_ioremap: release_resource(ptp_qoriq->rsrc); no_resource: From 69ed49a7b881ffe6588058411b0205f49b81071a Mon Sep 17 00:00:00 2001 From: ChunHao Lin Date: Thu, 23 Mar 2023 22:33:09 +0800 Subject: [PATCH 0973/1017] r8169: fix RTL8168H and RTL8107E rx crc error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 33189f0a94b9639c058781fcf82e4ea3803b1682 ] When link speed is 10 Mbps and temperature is under -20°C, RTL8168H and RTL8107E may have rx crc error. Disable phy 10 Mbps pll off to fix this issue. Fixes: 6e1d0b898818 ("r8169:add support for RTL8168H and RTL8107E") Signed-off-by: ChunHao Lin Reviewed-by: Heiner Kallweit Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/realtek/r8169_phy_config.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c index 913d030d73eb..e18a76f5049f 100644 --- a/drivers/net/ethernet/realtek/r8169_phy_config.c +++ b/drivers/net/ethernet/realtek/r8169_phy_config.c @@ -970,6 +970,9 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp, /* disable phy pfm mode */ phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0); + /* disable 10m pll off */ + phy_modify_paged(phydev, 0x0a43, 0x10, BIT(0), 0); + rtl8168g_disable_aldps(phydev); rtl8168g_config_eee_phy(phydev); } From 1025c471517bba5a43ded0f37be6f6ea2dbb5f29 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 26 Mar 2023 10:29:33 +0200 Subject: [PATCH 0974/1017] regulator: Handle deferred clk [ Upstream commit 02bcba0b9f9da706d5bd1e8cbeb83493863e17b5 ] devm_clk_get() can return -EPROBE_DEFER. So it is better to return the error code from devm_clk_get(), instead of a hard coded -ENOENT. This gives more opportunities to successfully probe the driver. Fixes: 8959e5324485 ("regulator: fixed: add possibility to enable by clock") Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/18459fae3d017a66313699c7c8456b28158b2dd0.1679819354.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/fixed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 3de7709bdcd4..4acfff190807 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -175,7 +175,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) drvdata->enable_clock = devm_clk_get(dev, NULL); if (IS_ERR(drvdata->enable_clock)) { dev_err(dev, "Can't get enable-clock from devicetree\n"); - return -ENOENT; + return PTR_ERR(drvdata->enable_clock); } } else { drvdata->desc.ops = &fixed_voltage_ops; From f032e125149d914e542548c17ebd613851031368 Mon Sep 17 00:00:00 2001 From: Faicker Mo Date: Fri, 24 Mar 2023 17:19:54 +0800 Subject: [PATCH 0975/1017] net/net_failover: fix txq exceeding warning [ Upstream commit e3cbdcb0fbb61045ef3ce0e072927cc41737f787 ] The failover txq is inited as 16 queues. when a packet is transmitted from the failover device firstly, the failover device will select the queue which is returned from the primary device if the primary device is UP and running. If the primary device txq is bigger than the default 16, it can lead to the following warning: eth0 selects TX queue 18, but real number of TX queues is 16 The warning backtrace is: [ 32.146376] CPU: 18 PID: 9134 Comm: chronyd Tainted: G E 6.2.8-1.el7.centos.x86_64 #1 [ 32.147175] Hardware name: Red Hat KVM, BIOS 1.10.2-3.el7_4.1 04/01/2014 [ 32.147730] Call Trace: [ 32.147971] [ 32.148183] dump_stack_lvl+0x48/0x70 [ 32.148514] dump_stack+0x10/0x20 [ 32.148820] netdev_core_pick_tx+0xb1/0xe0 [ 32.149180] __dev_queue_xmit+0x529/0xcf0 [ 32.149533] ? __check_object_size.part.0+0x21c/0x2c0 [ 32.149967] ip_finish_output2+0x278/0x560 [ 32.150327] __ip_finish_output+0x1fe/0x2f0 [ 32.150690] ip_finish_output+0x2a/0xd0 [ 32.151032] ip_output+0x7a/0x110 [ 32.151337] ? __pfx_ip_finish_output+0x10/0x10 [ 32.151733] ip_local_out+0x5e/0x70 [ 32.152054] ip_send_skb+0x19/0x50 [ 32.152366] udp_send_skb.isra.0+0x163/0x3a0 [ 32.152736] udp_sendmsg+0xba8/0xec0 [ 32.153060] ? __folio_memcg_unlock+0x25/0x60 [ 32.153445] ? __pfx_ip_generic_getfrag+0x10/0x10 [ 32.153854] ? sock_has_perm+0x85/0xa0 [ 32.154190] inet_sendmsg+0x6d/0x80 [ 32.154508] ? inet_sendmsg+0x6d/0x80 [ 32.154838] sock_sendmsg+0x62/0x70 [ 32.155152] ____sys_sendmsg+0x134/0x290 [ 32.155499] ___sys_sendmsg+0x81/0xc0 [ 32.155828] ? _get_random_bytes.part.0+0x79/0x1a0 [ 32.156240] ? ip4_datagram_release_cb+0x5f/0x1e0 [ 32.156649] ? get_random_u16+0x69/0xf0 [ 32.156989] ? __fget_light+0xcf/0x110 [ 32.157326] __sys_sendmmsg+0xc4/0x210 [ 32.157657] ? __sys_connect+0xb7/0xe0 [ 32.157995] ? __audit_syscall_entry+0xce/0x140 [ 32.158388] ? syscall_trace_enter.isra.0+0x12c/0x1a0 [ 32.158820] __x64_sys_sendmmsg+0x24/0x30 [ 32.159171] do_syscall_64+0x38/0x90 [ 32.159493] entry_SYSCALL_64_after_hwframe+0x72/0xdc Fix that by reducing txq number as the non-existent primary-dev does. Fixes: cfc80d9a1163 ("net: Introduce net_failover driver") Signed-off-by: Faicker Mo Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/net_failover.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c index fb182bec8f06..6b7bba720d8c 100644 --- a/drivers/net/net_failover.c +++ b/drivers/net/net_failover.c @@ -130,14 +130,10 @@ static u16 net_failover_select_queue(struct net_device *dev, txq = ops->ndo_select_queue(primary_dev, skb, sb_dev); else txq = netdev_pick_tx(primary_dev, skb, NULL); - - qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; - - return txq; + } else { + txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; } - txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; - /* Save the original txq to restore before passing to the driver */ qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; From 9b22e0cfc4d737b4cf70debbbb835abd71c8121e Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sat, 25 Mar 2023 13:28:15 +0200 Subject: [PATCH 0976/1017] net: stmmac: don't reject VLANs when IFF_PROMISC is set [ Upstream commit a7602e7332b97cfbec7bacb0f1ade99a575fe104 ] The blamed commit has introduced the following tests to dwmac4_add_hw_vlan_rx_fltr(), called from stmmac_vlan_rx_add_vid(): if (hw->promisc) { netdev_err(dev, "Adding VLAN in promisc mode not supported\n"); return -EPERM; } "VLAN promiscuous" mode is keyed in this driver to IFF_PROMISC, and so, vlan_vid_add() and vlan_vid_del() calls cannot take place in IFF_PROMISC mode. I have the following 2 arguments that this restriction is.... hm, how shall I put it nicely... unproductive :) First, take the case of a Linux bridge. If the kernel is compiled with CONFIG_BRIDGE_VLAN_FILTERING=y, then this bridge shall have a VLAN database. The bridge shall try to call vlan_add_vid() on its bridge ports for each VLAN in the VLAN table. It will do this irrespectively of whether that port is *currently* VLAN-aware or not. So it will do this even when the bridge was created with vlan_filtering 0. But the Linux bridge, in VLAN-unaware mode, configures its ports in promiscuous (IFF_PROMISC) mode, so that they accept packets with any MAC DA (a switch must do this in order to forward those packets which are not directly targeted to its MAC address). As a result, the stmmac driver does not work as a bridge port, when the kernel is compiled with CONFIG_BRIDGE_VLAN_FILTERING=y. $ ip link add br0 type bridge && ip link set br0 up $ ip link set eth0 master br0 && ip link set eth0 up [ 2333.943296] br0: port 1(eth0) entered blocking state [ 2333.943381] br0: port 1(eth0) entered disabled state [ 2333.943782] device eth0 entered promiscuous mode [ 2333.944080] 4033c000.ethernet eth0: Adding VLAN in promisc mode not supported [ 2333.976509] 4033c000.ethernet eth0: failed to initialize vlan filtering on this port RTNETLINK answers: Operation not permitted Secondly, take the case of stmmac as DSA master. Some switch tagging protocols are based on 802.1Q VLANs (tag_sja1105.c), and as such, tag_8021q.c uses vlan_vid_add() to work with VLAN-filtering DSA masters. But also, when a DSA port becomes promiscuous (for example when it joins a bridge), the DSA framework also makes the DSA master promiscuous. Moreover, for every VLAN that a DSA switch sends to the CPU, DSA also programs a VLAN filter on the DSA master, because if the the DSA switch uses a tail tag, then the hardware frame parser of the DSA master will see VLAN as VLAN, and might filter them out, for being unknown. Due to the above 2 reasons, my belief is that the stmmac driver does not get to choose to not accept vlan_vid_add() calls while IFF_PROMISC is enabled, because the 2 are completely independent and there are code paths in the network stack which directly lead to this situation occurring, without the user's direct input. In fact, my belief is that "VLAN promiscuous" mode should have never been keyed on IFF_PROMISC in the first place, but rather, on the NETIF_F_HW_VLAN_CTAG_FILTER feature flag which can be toggled by the user through ethtool -k, when present in netdev->hw_features. In the stmmac driver, NETIF_F_HW_VLAN_CTAG_FILTER is only present in "features", making this feature "on [fixed]". I have this belief because I am unaware of any definition of promiscuity which implies having an effect on anything other than MAC DA (therefore not VLAN). However, I seem to be rather alone in having this opinion, looking back at the disagreements from this discussion: https://lore.kernel.org/netdev/20201110153958.ci5ekor3o2ekg3ky@ipetronik.com/ In any case, to remove the vlan_vid_add() dependency on !IFF_PROMISC, one would need to remove the check and see what fails. I guess the test was there because of the way in which dwmac4_vlan_promisc_enable() is implemented. For context, the dwmac4 supports Perfect Filtering for a limited number of VLANs - dwmac4_get_num_vlan(), priv->hw->num_vlan, with a fallback on Hash Filtering - priv->dma_cap.vlhash - see stmmac_vlan_update(), also visible in cat /sys/kernel/debug/stmmaceth/eth0/dma_cap | grep 'VLAN Hash Filtering'. The perfect filtering is based on MAC_VLAN_Tag_Filter/MAC_VLAN_Tag_Data registers, accessed in the driver through dwmac4_write_vlan_filter(). The hash filtering is based on the MAC_VLAN_Hash_Table register, named GMAC_VLAN_HASH_TABLE in the driver and accessed by dwmac4_update_vlan_hash(). The control bit for enabling hash filtering is GMAC_VLAN_VTHM (MAC_VLAN_Tag_Ctrl bit VTHM: VLAN Tag Hash Table Match Enable). Now, the description of dwmac4_vlan_promisc_enable() is that it iterates through the driver's cache of perfect filter entries (hw->vlan_filter[i], added by dwmac4_add_hw_vlan_rx_fltr()), and evicts them from hardware by unsetting their GMAC_VLAN_TAG_DATA_VEN (MAC_VLAN_Tag_Data bit VEN - VLAN Tag Enable) bit. Then it unsets the GMAC_VLAN_VTHM bit, which disables hash matching. This leaves the MAC, according to table "VLAN Match Status" from the documentation, to always enter these data paths: VID |VLAN Perfect Filter |VTHM Bit |VLAN Hash Filter |Final VLAN Match |Match Result | |Match Result |Status -------|--------------------|---------|-----------------|---------------- VID!=0 |Fail |0 |don't care |Pass So, dwmac4_vlan_promisc_enable() does its job, but by unsetting GMAC_VLAN_VTHM, it conflicts with the other code path which controls this bit: dwmac4_update_vlan_hash(), called through stmmac_update_vlan_hash() from stmmac_vlan_rx_add_vid() and from stmmac_vlan_rx_kill_vid(). This is, I guess, why dwmac4_add_hw_vlan_rx_fltr() is not allowed to run after dwmac4_vlan_promisc_enable() has unset GMAC_VLAN_VTHM: because if it did, then dwmac4_update_vlan_hash() would set GMAC_VLAN_VTHM again, breaking the "VLAN promiscuity". It turns out that dwmac4_vlan_promisc_enable() is way too complicated for what needs to be done. The MAC_Packet_Filter register also has the VTFE bit (VLAN Tag Filter Enable), which simply controls whether VLAN tagged packets which don't match the filtering tables (either perfect or hash) are dropped or not. At the moment, this driver unconditionally sets GMAC_PACKET_FILTER_VTFE if NETIF_F_HW_VLAN_CTAG_FILTER was detected through the priv->dma_cap.vlhash capability bits of the device, in stmmac_dvr_probe(). I would suggest deleting the unnecessarily complex logic from dwmac4_vlan_promisc_enable(), and simply unsetting GMAC_PACKET_FILTER_VTFE when becoming IFF_PROMISC, which has the same effect of allowing packets with any VLAN tags, but has the additional benefit of being able to run concurrently with stmmac_vlan_rx_add_vid() and stmmac_vlan_rx_kill_vid(). As much as I believe that the VTFE bit should have been exclusively controlled by NETIF_F_HW_VLAN_CTAG_FILTER through ethtool, and not by IFF_PROMISC, changing that is not a punctual fix to the problem, and it would probably break the VFFQ feature added by the later commit e0f9956a3862 ("net: stmmac: Add option for VLAN filter fail queue enable"). From the commit description, VFFQ needs IFF_PROMISC=on and VTFE=off in order to work (and this change respects that). But if VTFE was changed to be controlled through ethtool -k, then a user-visible change would have been introduced in Intel's scripts (a need to run "ethtool -k eth0 rx-vlan-filter off" which did not exist before). The patch was tested with this set of commands: ip link set eth0 up ip link add link eth0 name eth0.100 type vlan id 100 ip addr add 192.168.100.2/24 dev eth0.100 && ip link set eth0.100 up ip link set eth0 promisc on ip link add link eth0 name eth0.101 type vlan id 101 ip addr add 192.168.101.2/24 dev eth0.101 && ip link set eth0.101 up ip link set eth0 promisc off ping -c 5 192.168.100.1 ping -c 5 192.168.101.1 ip link set eth0 promisc on ping -c 5 192.168.100.1 ping -c 5 192.168.101.1 ip link del eth0.100 ip link del eth0.101 # Wait for VLAN-tagged pings from the other end... # Check with "tcpdump -i eth0 -e -n -p" and we should see them ip link set eth0 promisc off # Wait for VLAN-tagged pings from the other end... # Check with "tcpdump -i eth0 -e -n -p" and we shouldn't see them # anymore, but remove the "-p" argument from tcpdump and they're there. Fixes: c89f44ff10fd ("net: stmmac: Add support for VLAN promiscuous mode") Signed-off-by: Vladimir Oltean Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/common.h | 1 - .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 61 +------------------ 2 files changed, 3 insertions(+), 59 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index df7de50497a0..af4303523929 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -480,7 +480,6 @@ struct mac_device_info { unsigned int xlgmac; unsigned int num_vlan; u32 vlan_filter[32]; - unsigned int promisc; bool vlan_fail_q_en; u8 vlan_fail_q; }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 5b052fdd2696..cd11be005390 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -453,12 +453,6 @@ static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev, if (vid > 4095) return -EINVAL; - if (hw->promisc) { - netdev_err(dev, - "Adding VLAN in promisc mode not supported\n"); - return -EPERM; - } - /* Single Rx VLAN Filter */ if (hw->num_vlan == 1) { /* For single VLAN filter, VID 0 means VLAN promiscuous */ @@ -508,12 +502,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev, { int i, ret = 0; - if (hw->promisc) { - netdev_err(dev, - "Deleting VLAN in promisc mode not supported\n"); - return -EPERM; - } - /* Single Rx VLAN Filter */ if (hw->num_vlan == 1) { if ((hw->vlan_filter[0] & GMAC_VLAN_TAG_VID) == vid) { @@ -538,39 +526,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev, return ret; } -static void dwmac4_vlan_promisc_enable(struct net_device *dev, - struct mac_device_info *hw) -{ - void __iomem *ioaddr = hw->pcsr; - u32 value; - u32 hash; - u32 val; - int i; - - /* Single Rx VLAN Filter */ - if (hw->num_vlan == 1) { - dwmac4_write_single_vlan(dev, 0); - return; - } - - /* Extended Rx VLAN Filter Enable */ - for (i = 0; i < hw->num_vlan; i++) { - if (hw->vlan_filter[i] & GMAC_VLAN_TAG_DATA_VEN) { - val = hw->vlan_filter[i] & ~GMAC_VLAN_TAG_DATA_VEN; - dwmac4_write_vlan_filter(dev, hw, i, val); - } - } - - hash = readl(ioaddr + GMAC_VLAN_HASH_TABLE); - if (hash & GMAC_VLAN_VLHT) { - value = readl(ioaddr + GMAC_VLAN_TAG); - if (value & GMAC_VLAN_VTHM) { - value &= ~GMAC_VLAN_VTHM; - writel(value, ioaddr + GMAC_VLAN_TAG); - } - } -} - static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev, struct mac_device_info *hw) { @@ -690,22 +645,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw, } /* VLAN filtering */ - if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) + if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) + value &= ~GMAC_PACKET_FILTER_VTFE; + else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) value |= GMAC_PACKET_FILTER_VTFE; writel(value, ioaddr + GMAC_PACKET_FILTER); - - if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) { - if (!hw->promisc) { - hw->promisc = 1; - dwmac4_vlan_promisc_enable(dev, hw); - } - } else { - if (hw->promisc) { - hw->promisc = 0; - dwmac4_restore_hw_vlan_rx_fltr(dev, hw); - } - } } static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, From ab2a55907823f0bca56b6d03ea05e4071ba8535f Mon Sep 17 00:00:00 2001 From: Ivan Orlov Date: Tue, 14 Mar 2023 16:04:45 +0400 Subject: [PATCH 0977/1017] can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write [ Upstream commit 2b4c99f7d9a57ecd644eda9b1fb0a1072414959f ] Syzkaller reported the following issue: ===================================================== BUG: KMSAN: uninit-value in aio_rw_done fs/aio.c:1520 [inline] BUG: KMSAN: uninit-value in aio_write+0x899/0x950 fs/aio.c:1600 aio_rw_done fs/aio.c:1520 [inline] aio_write+0x899/0x950 fs/aio.c:1600 io_submit_one+0x1d1c/0x3bf0 fs/aio.c:2019 __do_sys_io_submit fs/aio.c:2078 [inline] __se_sys_io_submit+0x293/0x770 fs/aio.c:2048 __x64_sys_io_submit+0x92/0xd0 fs/aio.c:2048 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Uninit was created at: slab_post_alloc_hook mm/slab.h:766 [inline] slab_alloc_node mm/slub.c:3452 [inline] __kmem_cache_alloc_node+0x71f/0xce0 mm/slub.c:3491 __do_kmalloc_node mm/slab_common.c:967 [inline] __kmalloc+0x11d/0x3b0 mm/slab_common.c:981 kmalloc_array include/linux/slab.h:636 [inline] bcm_tx_setup+0x80e/0x29d0 net/can/bcm.c:930 bcm_sendmsg+0x3a2/0xce0 net/can/bcm.c:1351 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg net/socket.c:734 [inline] sock_write_iter+0x495/0x5e0 net/socket.c:1108 call_write_iter include/linux/fs.h:2189 [inline] aio_write+0x63a/0x950 fs/aio.c:1600 io_submit_one+0x1d1c/0x3bf0 fs/aio.c:2019 __do_sys_io_submit fs/aio.c:2078 [inline] __se_sys_io_submit+0x293/0x770 fs/aio.c:2048 __x64_sys_io_submit+0x92/0xd0 fs/aio.c:2048 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd CPU: 1 PID: 5034 Comm: syz-executor350 Not tainted 6.2.0-rc6-syzkaller-80422-geda666ff2276 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/12/2023 ===================================================== We can follow the call chain and find that 'bcm_tx_setup' function calls 'memcpy_from_msg' to copy some content to the newly allocated frame of 'op->frames'. After that the 'len' field of copied structure being compared with some constant value (64 or 8). However, if 'memcpy_from_msg' returns an error, we will compare some uninitialized memory. This triggers 'uninit-value' issue. This patch will add 'memcpy_from_msg' possible errors processing to avoid uninit-value issue. Tested via syzkaller Reported-by: syzbot+c9bfd85eca611ebf5db1@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=47f897f8ad958bbde5790ebf389b5e7e0a345089 Signed-off-by: Ivan Orlov Fixes: 6f3b911d5f29b ("can: bcm: add support for CAN FD frames") Acked-by: Oliver Hartkopp Link: https://lore.kernel.org/all/20230314120445.12407-1-ivan.orlov0322@gmail.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- net/can/bcm.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/net/can/bcm.c b/net/can/bcm.c index afa82adaf6cd..ddba4e12da78 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -936,6 +936,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, cf = op->frames + op->cfsiz * i; err = memcpy_from_msg((u8 *)cf, msg, op->cfsiz); + if (err < 0) + goto free_op; if (op->flags & CAN_FD_FRAME) { if (cf->len > 64) @@ -945,12 +947,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, err = -EINVAL; } - if (err < 0) { - if (op->frames != &op->sframe) - kfree(op->frames); - kfree(op); - return err; - } + if (err < 0) + goto free_op; if (msg_head->flags & TX_CP_CAN_ID) { /* copy can_id into frame */ @@ -1021,6 +1019,12 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, bcm_tx_start_timer(op); return msg_head->nframes * op->cfsiz + MHSIZ; + +free_op: + if (op->frames != &op->sframe) + kfree(op->frames); + kfree(op); + return err; } /* From ee17dea3072dec0bc34399a32fa884e26342e4ea Mon Sep 17 00:00:00 2001 From: Tony Krowiak Date: Mon, 20 Mar 2023 11:04:47 -0400 Subject: [PATCH 0978/1017] s390/vfio-ap: fix memory leak in vfio_ap device driver [ Upstream commit 8f8cf767589f2131ae5d40f3758429095c701c84 ] The device release callback function invoked to release the matrix device uses the dev_get_drvdata(device *dev) function to retrieve the pointer to the vfio_matrix_dev object in order to free its storage. The problem is, this object is not stored as drvdata with the device; since the kfree function will accept a NULL pointer, the memory for the vfio_matrix_dev object is never freed. Since the device being released is contained within the vfio_matrix_dev object, the container_of macro will be used to retrieve its pointer. Fixes: 1fde573413b5 ("s390: vfio-ap: base implementation of VFIO AP device driver") Signed-off-by: Tony Krowiak Reviewed-by: Harald Freudenberger Link: https://lore.kernel.org/r/20230320150447.34557-1-akrowiak@linux.ibm.com Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Sasha Levin --- drivers/s390/crypto/vfio_ap_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c index 7dc72cb718b0..22128eb44f7f 100644 --- a/drivers/s390/crypto/vfio_ap_drv.c +++ b/drivers/s390/crypto/vfio_ap_drv.c @@ -82,8 +82,9 @@ static void vfio_ap_queue_dev_remove(struct ap_device *apdev) static void vfio_ap_matrix_dev_release(struct device *dev) { - struct ap_matrix_dev *matrix_dev = dev_get_drvdata(dev); + struct ap_matrix_dev *matrix_dev; + matrix_dev = container_of(dev, struct ap_matrix_dev, device); kfree(matrix_dev); } From 688b1178c443fd1bac47bfc5beb90f356f02569d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Jun 2021 16:05:26 +0200 Subject: [PATCH 0979/1017] ALSA: ymfpci: Fix assignment in if condition [ Upstream commit e7daaeedb4f270126792ae216f406c1ba2b8f4d9 ] PCI YMFPCI driver code contains lots of assignments in if condition, which is a bad coding style that may confuse readers and occasionally lead to bugs. This patch is merely for coding-style fixes, no functional changes. Link: https://lore.kernel.org/r/20210608140540.17885-53-tiwai@suse.de Signed-off-by: Takashi Iwai Stable-dep-of: 6be2e7522eb5 ("ALSA: ymfpci: Fix BUG_ON in probe function") Signed-off-by: Sasha Levin --- sound/pci/ymfpci/ymfpci.c | 71 +++++++++++++++++++-------------- sound/pci/ymfpci/ymfpci_main.c | 72 +++++++++++++++++++++++----------- 2 files changed, 91 insertions(+), 52 deletions(-) diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 9b0d18a7bf35..27fd10b976f7 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -78,7 +78,8 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, if (io_port == 1) { /* auto-detect */ - if (!(io_port = pci_resource_start(chip->pci, 2))) + io_port = pci_resource_start(chip->pci, 2); + if (!io_port) return -ENODEV; } } else { @@ -87,7 +88,8 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, for (io_port = 0x201; io_port <= 0x205; io_port++) { if (io_port == 0x203) continue; - if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL) + r = request_region(io_port, 1, "YMFPCI gameport"); + if (r) break; } if (!r) { @@ -108,10 +110,13 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, } } - if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) { - dev_err(chip->card->dev, - "joystick port %#x is in use.\n", io_port); - return -EBUSY; + if (!r) { + r = request_region(io_port, 1, "YMFPCI gameport"); + if (!r) { + dev_err(chip->card->dev, + "joystick port %#x is in use.\n", io_port); + return -EBUSY; + } } chip->gameport = gp = gameport_allocate_port(); @@ -199,8 +204,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, /* auto-detect */ fm_port[dev] = pci_resource_start(pci, 1); } - if (fm_port[dev] > 0 && - (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) { + if (fm_port[dev] > 0) + fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3"); + if (fm_res) { legacy_ctrl |= YMFPCI_LEGACY_FMEN; pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]); } @@ -208,8 +214,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, /* auto-detect */ mpu_port[dev] = pci_resource_start(pci, 1) + 0x20; } - if (mpu_port[dev] > 0 && - (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) { + if (mpu_port[dev] > 0) + mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401"); + if (mpu_res) { legacy_ctrl |= YMFPCI_LEGACY_MEN; pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]); } @@ -221,8 +228,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, case 0x3a8: legacy_ctrl2 |= 3; break; default: fm_port[dev] = 0; break; } - if (fm_port[dev] > 0 && - (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) { + if (fm_port[dev] > 0) + fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3"); + if (fm_res) { legacy_ctrl |= YMFPCI_LEGACY_FMEN; } else { legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO; @@ -235,8 +243,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, case 0x334: legacy_ctrl2 |= 3 << 4; break; default: mpu_port[dev] = 0; break; } - if (mpu_port[dev] > 0 && - (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) { + if (mpu_port[dev] > 0) + mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401"); + if (mpu_res) { legacy_ctrl |= YMFPCI_LEGACY_MEN; } else { legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO; @@ -250,9 +259,8 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl); pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2); - if ((err = snd_ymfpci_create(card, pci, - old_legacy_ctrl, - &chip)) < 0) { + err = snd_ymfpci_create(card, pci, old_legacy_ctrl, &chip); + if (err < 0) { release_and_free_resource(mpu_res); release_and_free_resource(fm_res); goto free_card; @@ -293,11 +301,12 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, goto free_card; if (chip->mpu_res) { - if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, - mpu_port[dev], - MPU401_INFO_INTEGRATED | - MPU401_INFO_IRQ_HOOK, - -1, &chip->rawmidi)) < 0) { + err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, + mpu_port[dev], + MPU401_INFO_INTEGRATED | + MPU401_INFO_IRQ_HOOK, + -1, &chip->rawmidi); + if (err < 0) { dev_warn(card->dev, "cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); @@ -306,18 +315,22 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, } } if (chip->fm_res) { - if ((err = snd_opl3_create(card, - fm_port[dev], - fm_port[dev] + 2, - OPL3_HW_OPL3, 1, &opl3)) < 0) { + err = snd_opl3_create(card, + fm_port[dev], + fm_port[dev] + 2, + OPL3_HW_OPL3, 1, &opl3); + if (err < 0) { dev_warn(card->dev, "cannot initialize FM OPL3 at 0x%lx, skipping...\n", fm_port[dev]); legacy_ctrl &= ~YMFPCI_LEGACY_FMEN; pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); - } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { - dev_err(card->dev, "cannot create opl3 hwdep\n"); - goto free_card; + } else { + err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (err < 0) { + dev_err(card->dev, "cannot create opl3 hwdep\n"); + goto free_card; + } } } diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index cacc6a9d14c8..8fd060769882 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -292,7 +292,8 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_ struct snd_ymfpci_pcm *ypcm; u32 pos, delta; - if ((ypcm = voice->ypcm) == NULL) + ypcm = voice->ypcm; + if (!ypcm) return; if (ypcm->substream == NULL) return; @@ -628,7 +629,8 @@ static int snd_ymfpci_playback_hw_params(struct snd_pcm_substream *substream, struct snd_ymfpci_pcm *ypcm = runtime->private_data; int err; - if ((err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params))) < 0) + err = snd_ymfpci_pcm_voice_alloc(ypcm, params_channels(hw_params)); + if (err < 0) return err; return 0; } @@ -932,7 +934,8 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) struct snd_ymfpci_pcm *ypcm; int err; - if ((err = snd_ymfpci_playback_open_1(substream)) < 0) + err = snd_ymfpci_playback_open_1(substream); + if (err < 0) return err; ypcm = runtime->private_data; ypcm->output_front = 1; @@ -954,7 +957,8 @@ static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream) struct snd_ymfpci_pcm *ypcm; int err; - if ((err = snd_ymfpci_playback_open_1(substream)) < 0) + err = snd_ymfpci_playback_open_1(substream); + if (err < 0) return err; ypcm = runtime->private_data; ypcm->output_front = 0; @@ -982,7 +986,8 @@ static int snd_ymfpci_playback_4ch_open(struct snd_pcm_substream *substream) struct snd_ymfpci_pcm *ypcm; int err; - if ((err = snd_ymfpci_playback_open_1(substream)) < 0) + err = snd_ymfpci_playback_open_1(substream); + if (err < 0) return err; ypcm = runtime->private_data; ypcm->output_front = 0; @@ -1124,7 +1129,8 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device) struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0) + err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm); + if (err < 0) return err; pcm->private_data = chip; @@ -1157,7 +1163,8 @@ int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device) struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0) + err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm); + if (err < 0) return err; pcm->private_data = chip; @@ -1190,7 +1197,8 @@ int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device) struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0) + err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm); + if (err < 0) return err; pcm->private_data = chip; @@ -1230,7 +1238,8 @@ int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device) struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0) + err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm); + if (err < 0) return err; pcm->private_data = chip; @@ -1785,7 +1794,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) .read = snd_ymfpci_codec_read, }; - if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0) + err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus); + if (err < 0) return err; chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus; chip->ac97_bus->no_vra = 1; /* YMFPCI doesn't need VRA */ @@ -1793,7 +1803,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) memset(&ac97, 0, sizeof(ac97)); ac97.private_data = chip; ac97.private_free = snd_ymfpci_mixer_free_ac97; - if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) + err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97); + if (err < 0) return err; /* to be sure */ @@ -1801,7 +1812,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) AC97_EA_VRA|AC97_EA_VRM, 0); for (idx = 0; idx < ARRAY_SIZE(snd_ymfpci_controls); idx++) { - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) + err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip)); + if (err < 0) return err; } if (chip->ac97->ext_id & AC97_EI_SDAC) { @@ -1814,27 +1826,37 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) /* add S/PDIF control */ if (snd_BUG_ON(!chip->pcm_spdif)) return -ENXIO; - if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0) + kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip); + err = snd_ctl_add(chip->card, kctl); + if (err < 0) return err; kctl->id.device = chip->pcm_spdif->device; - if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip))) < 0) + kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip); + err = snd_ctl_add(chip->card, kctl); + if (err < 0) return err; kctl->id.device = chip->pcm_spdif->device; - if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip))) < 0) + kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip); + err = snd_ctl_add(chip->card, kctl); + if (err < 0) return err; kctl->id.device = chip->pcm_spdif->device; chip->spdif_pcm_ctl = kctl; /* direct recording source */ - if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754 && - (err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip))) < 0) - return err; + if (chip->device_id == PCI_DEVICE_ID_YAMAHA_754) { + kctl = snd_ctl_new1(&snd_ymfpci_drec_source, chip); + err = snd_ctl_add(chip->card, kctl); + if (err < 0) + return err; + } /* * shared rear/line-in */ if (rear_switch) { - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0) + err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip)); + if (err < 0) return err; } @@ -1847,7 +1869,8 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) kctl->id.device = chip->pcm->device; kctl->id.subdevice = idx; kctl->private_value = (unsigned long)substream; - if ((err = snd_ctl_add(chip->card, kctl)) < 0) + err = snd_ctl_add(chip->card, kctl); + if (err < 0) return err; chip->pcm_mixer[idx].left = 0x8000; chip->pcm_mixer[idx].right = 0x8000; @@ -1928,7 +1951,8 @@ int snd_ymfpci_timer(struct snd_ymfpci *chip, int device) tid.card = chip->card->number; tid.device = device; tid.subdevice = 0; - if ((err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer)) >= 0) { + err = snd_timer_new(chip->card, "YMFPCI", &tid, &timer); + if (err >= 0) { strcpy(timer->name, "YMFPCI timer"); timer->private_data = chip; timer->hw = snd_ymfpci_timer_hw; @@ -2334,7 +2358,8 @@ int snd_ymfpci_create(struct snd_card *card, *rchip = NULL; /* enable PCI device */ - if ((err = pci_enable_device(pci)) < 0) + err = pci_enable_device(pci); + if (err < 0) return err; chip = kzalloc(sizeof(*chip), GFP_KERNEL); @@ -2357,7 +2382,8 @@ int snd_ymfpci_create(struct snd_card *card, pci_set_master(pci); chip->src441_used = -1; - if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) { + chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI"); + if (!chip->res_reg_area) { dev_err(chip->card->dev, "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); From 96e34c88000febc83e41aa7db0b0a41676314818 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Wed, 29 Mar 2023 06:28:08 +0300 Subject: [PATCH 0980/1017] ALSA: ymfpci: Fix BUG_ON in probe function [ Upstream commit 6be2e7522eb529b41c16d459f33bbdbcddbf5c15 ] The snd_dma_buffer.bytes field now contains the aligned size, which this snd_BUG_ON() did not account for, resulting in the following: [ 9.625915] ------------[ cut here ]------------ [ 9.633440] WARNING: CPU: 0 PID: 126 at sound/pci/ymfpci/ymfpci_main.c:2168 snd_ymfpci_create+0x681/0x698 [snd_ymfpci] [ 9.648926] Modules linked in: snd_ymfpci(+) snd_intel_dspcfg kvm(+) snd_intel_sdw_acpi snd_ac97_codec snd_mpu401_uart snd_opl3_lib irqbypass snd_hda_codec gameport snd_rawmidi crct10dif_pclmul crc32_pclmul cfg80211 snd_hda_core polyval_clmulni polyval_generic gf128mul snd_seq_device ghash_clmulni_intel snd_hwdep ac97_bus sha512_ssse3 rfkill snd_pcm aesni_intel tg3 snd_timer crypto_simd snd mxm_wmi libphy cryptd k10temp fam15h_power pcspkr soundcore sp5100_tco wmi acpi_cpufreq mac_hid dm_multipath sg loop fuse dm_mod bpf_preload ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 sr_mod cdrom ata_generic pata_acpi firewire_ohci crc32c_intel firewire_core xhci_pci crc_itu_t pata_via xhci_pci_renesas floppy [ 9.711849] CPU: 0 PID: 126 Comm: kworker/0:2 Not tainted 6.1.21-1-lts #1 08d2e5ece03136efa7c6aeea9a9c40916b1bd8da [ 9.722200] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./990FX Extreme4, BIOS P2.70 06/05/2014 [ 9.732204] Workqueue: events work_for_cpu_fn [ 9.736580] RIP: 0010:snd_ymfpci_create+0x681/0x698 [snd_ymfpci] [ 9.742594] Code: 8c c0 4c 89 e2 48 89 df 48 c7 c6 92 c6 8c c0 e8 15 d0 e9 ff 48 83 c4 08 44 89 e8 5b 5d 41 5c 41 5d 41 5e 41 5f e9 d3 7a 33 e3 <0f> 0b e9 cb fd ff ff 41 bd fb ff ff ff eb db 41 bd f4 ff ff ff eb [ 9.761358] RSP: 0018:ffffab64804e7da0 EFLAGS: 00010287 [ 9.766594] RAX: ffff8fa2df06c400 RBX: ffff8fa3073a8000 RCX: ffff8fa303fbc4a8 [ 9.773734] RDX: ffff8fa2df06d000 RSI: 0000000000000010 RDI: 0000000000000020 [ 9.780876] RBP: ffff8fa300b5d0d0 R08: ffff8fa3073a8e50 R09: 00000000df06bf00 [ 9.788018] R10: ffff8fa2df06bf00 R11: 00000000df068200 R12: ffff8fa3073a8918 [ 9.795159] R13: 0000000000000000 R14: 0000000000000080 R15: ffff8fa2df068200 [ 9.802317] FS: 0000000000000000(0000) GS:ffff8fa9fec00000(0000) knlGS:0000000000000000 [ 9.810414] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 9.816158] CR2: 000055febaf66500 CR3: 0000000101a2e000 CR4: 00000000000406f0 [ 9.823301] Call Trace: [ 9.825747] [ 9.827889] snd_card_ymfpci_probe+0x194/0x950 [snd_ymfpci b78a5fe64b5663a6390a909c67808567e3e73615] [ 9.837030] ? finish_task_switch.isra.0+0x90/0x2d0 [ 9.841918] local_pci_probe+0x45/0x80 [ 9.845680] work_for_cpu_fn+0x1a/0x30 [ 9.849431] process_one_work+0x1c7/0x380 [ 9.853464] worker_thread+0x1af/0x390 [ 9.857225] ? rescuer_thread+0x3b0/0x3b0 [ 9.861254] kthread+0xde/0x110 [ 9.864414] ? kthread_complete_and_exit+0x20/0x20 [ 9.869210] ret_from_fork+0x22/0x30 [ 9.872792] [ 9.874985] ---[ end trace 0000000000000000 ]--- Fixes: 5c1733e33c88 ("ALSA: memalloc: Align buffer allocations in page size") Signed-off-by: Tasos Sahanidis Link: https://lore.kernel.org/r/20230329032808.170403-1-tasos@tasossah.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/ymfpci/ymfpci_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 8fd060769882..0cd9b4029dab 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2164,7 +2164,7 @@ static int snd_ymfpci_memalloc(struct snd_ymfpci *chip) chip->work_base = ptr; chip->work_base_addr = ptr_addr; - snd_BUG_ON(ptr + chip->work_size != + snd_BUG_ON(ptr + PAGE_ALIGN(chip->work_size) != chip->work_ptr.area + chip->work_ptr.bytes); snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr); From fa7fafedc9fddfbc715132fdf35f6c2fa9c43e02 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Tue, 28 Mar 2023 11:27:51 -0500 Subject: [PATCH 0981/1017] net: ipa: compute DMA pool size properly [ Upstream commit 6c75dc94f2b27fff57b305af9236eea181a00b6c ] In gsi_trans_pool_init_dma(), the total size of a pool of memory used for DMA transactions is calculated. However the calculation is done incorrectly. For 4KB pages, this total size is currently always more than one page, and as a result, the calculation produces a positive (though incorrect) total size. The code still works in this case; we just end up with fewer DMA pool entries than we intended. Bjorn Andersson tested booting a kernel with 16KB pages, and hit a null pointer derereference in sg_alloc_append_table_from_pages(), descending from gsi_trans_pool_init_dma(). The cause of this was that a 16KB total size was going to be allocated, and with 16KB pages the order of that allocation is 0. The total_size calculation yielded 0, which eventually led to the crash. Correcting the total_size calculation fixes the problem. Reported-by: Bjorn Andersson Tested-by: Bjorn Andersson Fixes: 9dd441e4ed57 ("soc: qcom: ipa: GSI transactions") Reviewed-by: Mark Bloch Signed-off-by: Alex Elder Reviewed-by: Leon Romanovsky Link: https://lore.kernel.org/r/20230328162751.2861791-1-elder@linaro.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ipa/gsi_trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c index 70c2b585f98d..1e0d62639301 100644 --- a/drivers/net/ipa/gsi_trans.c +++ b/drivers/net/ipa/gsi_trans.c @@ -159,7 +159,7 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool, * gsi_trans_pool_exit_dma() can assume the total allocated * size is exactly (count * size). */ - total_size = get_order(total_size) << PAGE_SHIFT; + total_size = PAGE_SIZE << get_order(total_size); virt = dma_alloc_coherent(dev, total_size, &addr, GFP_KERNEL); if (!virt) From f524d1e55013b64ec14be012d839b919d65d2481 Mon Sep 17 00:00:00 2001 From: Radoslaw Tyl Date: Tue, 28 Mar 2023 10:26:59 -0700 Subject: [PATCH 0982/1017] i40e: fix registers dump after run ethtool adapter self test [ Upstream commit c5cff16f461a4a434a9915a7be7ac9ced861a8a4 ] Fix invalid registers dump from ethtool -d ethX after adapter self test by ethtool -t ethY. It causes invalid data display. The problem was caused by overwriting i40e_reg_list[].elements which is common for ethtool self test and dump. Fixes: 22dd9ae8afcc ("i40e: Rework register diagnostic") Signed-off-by: Radoslaw Tyl Reviewed-by: Michal Swiatkowski Tested-by: Arpana Arland (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Reviewed-by: Leon Romanovsky Link: https://lore.kernel.org/r/20230328172659.3906413-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/i40e/i40e_diag.c | 11 ++++++----- drivers/net/ethernet/intel/i40e/i40e_diag.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.c b/drivers/net/ethernet/intel/i40e/i40e_diag.c index ef4d3762bf37..ca229b0efeb6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_diag.c +++ b/drivers/net/ethernet/intel/i40e/i40e_diag.c @@ -44,7 +44,7 @@ static i40e_status i40e_diag_reg_pattern_test(struct i40e_hw *hw, return 0; } -struct i40e_diag_reg_test_info i40e_reg_list[] = { +const struct i40e_diag_reg_test_info i40e_reg_list[] = { /* offset mask elements stride */ {I40E_QTX_CTL(0), 0x0000FFBF, 1, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)}, @@ -78,27 +78,28 @@ i40e_status i40e_diag_reg_test(struct i40e_hw *hw) { i40e_status ret_code = 0; u32 reg, mask; + u32 elements; u32 i, j; for (i = 0; i40e_reg_list[i].offset != 0 && !ret_code; i++) { + elements = i40e_reg_list[i].elements; /* set actual reg range for dynamically allocated resources */ if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) && hw->func_caps.num_tx_qp != 0) - i40e_reg_list[i].elements = hw->func_caps.num_tx_qp; + elements = hw->func_caps.num_tx_qp; if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) || i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) || i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) || i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) || i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) && hw->func_caps.num_msix_vectors != 0) - i40e_reg_list[i].elements = - hw->func_caps.num_msix_vectors - 1; + elements = hw->func_caps.num_msix_vectors - 1; /* test register access */ mask = i40e_reg_list[i].mask; - for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) { + for (j = 0; j < elements && !ret_code; j++) { reg = i40e_reg_list[i].offset + (j * i40e_reg_list[i].stride); ret_code = i40e_diag_reg_pattern_test(hw, reg, mask); diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.h b/drivers/net/ethernet/intel/i40e/i40e_diag.h index c3340f320a18..1db7c6d57231 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_diag.h +++ b/drivers/net/ethernet/intel/i40e/i40e_diag.h @@ -20,7 +20,7 @@ struct i40e_diag_reg_test_info { u32 stride; /* bytes between each element */ }; -extern struct i40e_diag_reg_test_info i40e_reg_list[]; +extern const struct i40e_diag_reg_test_info i40e_reg_list[]; i40e_status i40e_diag_reg_test(struct i40e_hw *hw); i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw); From 62850a076353cafcb17adc8fa2dc67cc0aced58d Mon Sep 17 00:00:00 2001 From: Kalesh AP Date: Tue, 28 Mar 2023 18:30:20 -0700 Subject: [PATCH 0983/1017] bnxt_en: Fix typo in PCI id to device description string mapping [ Upstream commit 62aad36ed31abc80f35db11e187e690448a79f7d ] Fix 57502 and 57508 NPAR description string entries. The typos caused these devices to not match up with lspci output. Fixes: 49c98421e6ab ("bnxt_en: Add PCI IDs for 57500 series NPAR devices.") Reviewed-by: Pavan Chebbi Signed-off-by: Kalesh AP Signed-off-by: Michael Chan Reviewed-by: Simon Horman Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 6928c0b578ab..3a9fcf942a6d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -219,12 +219,12 @@ static const struct pci_device_id bnxt_pci_tbl[] = { { PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 }, { PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 }, { PCI_VDEVICE(BROADCOM, 0x1752), .driver_data = BCM57502 }, - { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57508_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57502_NPAR }, { PCI_VDEVICE(BROADCOM, 0x1801), .driver_data = BCM57504_NPAR }, - { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57502_NPAR }, - { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57508_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57508_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57502_NPAR }, { PCI_VDEVICE(BROADCOM, 0x1804), .driver_data = BCM57504_NPAR }, - { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57502_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57508_NPAR }, { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 }, { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 }, #ifdef CONFIG_BNXT_SRIOV From 8104c795517c2f10e2720c16b216abb9a68746ee Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 28 Mar 2023 18:30:21 -0700 Subject: [PATCH 0984/1017] bnxt_en: Add missing 200G link speed reporting [ Upstream commit 581bce7bcb7e7f100908728e7b292e266c76895b ] bnxt_fw_to_ethtool_speed() is missing the case statement for 200G link speed reported by firmware. As a result, ethtool will report unknown speed when the firmware reports 200G link speed. Fixes: 532262ba3b84 ("bnxt_en: ethtool: support PAM4 link speeds up to 200G") Signed-off-by: Michael Chan Reviewed-by: Simon Horman Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 34affd1de91d..b7b07beb17ff 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1198,6 +1198,7 @@ struct bnxt_link_info { #define BNXT_LINK_SPEED_40GB PORT_PHY_QCFG_RESP_LINK_SPEED_40GB #define BNXT_LINK_SPEED_50GB PORT_PHY_QCFG_RESP_LINK_SPEED_50GB #define BNXT_LINK_SPEED_100GB PORT_PHY_QCFG_RESP_LINK_SPEED_100GB +#define BNXT_LINK_SPEED_200GB PORT_PHY_QCFG_RESP_LINK_SPEED_200GB u16 support_speeds; u16 support_pam4_speeds; u16 auto_link_speeds; /* fw adv setting */ diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 81b63d1c2391..1e67e86fc334 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1653,6 +1653,8 @@ u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) return SPEED_50000; case BNXT_LINK_SPEED_100GB: return SPEED_100000; + case BNXT_LINK_SPEED_200GB: + return SPEED_200000; default: return SPEED_UNKNOWN; } From ed3439a8c4fe7fc7d8c20b9e89aa16d45f8e0a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20B=C3=A4tz?= Date: Wed, 29 Mar 2023 12:01:40 -0300 Subject: [PATCH 0985/1017] net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 7bcad0f0e6fbc1d613e49e0ee35c8e5f2e685bb0 ] Do not set the MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP bit on CPU or DSA ports. This allows the host CPU port to be a regular IGMP listener by sending out IGMP Membership Reports, which would otherwise not be forwarded by the mv88exxx chip, but directly looped back to the CPU port itself. Fixes: 54d792f257c6 ("net: dsa: Centralise global and port setup code into mv88e6xxx.") Signed-off-by: Steffen Bätz Signed-off-by: Fabio Estevam Reviewed-by: Andrew Lunn Reviewed-by: Vladimir Oltean Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20230329150140.701559-1-festevam@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/dsa/mv88e6xxx/chip.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index a253476a52b0..0b104a90c0d8 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2611,9 +2611,14 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) * If this is the upstream port for this switch, enable * forwarding of unknown unicasts and multicasts. */ - reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP | - MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | + reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | MV88E6XXX_PORT_CTL0_STATE_FORWARDING; + /* Forward any IPv4 IGMP or IPv6 MLD frames received + * by a USER port to the CPU port to allow snooping. + */ + if (dsa_is_user_port(ds, port)) + reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP; + err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); if (err) return err; From 988061d09972dba1374426924531a85e6d306f47 Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Mon, 6 Feb 2023 21:37:20 +0100 Subject: [PATCH 0986/1017] pinctrl: ocelot: Fix alt mode for ocelot [ Upstream commit 657fd9da2d4b4aa0a384105b236baa22fa0233bf ] In case the driver was trying to set an alternate mode for gpio 0 or 32 then the mode was not set correctly. The reason is that there is computation error inside the function ocelot_pinmux_set_mux because in this case it was trying to shift to left by -1. Fix this by actually shifting the function bits and not the position. Fixes: 4b36082e2e09 ("pinctrl: ocelot: fix pinmuxing for pins after 31") Signed-off-by: Horatiu Vultur Link: https://lore.kernel.org/r/20230206203720.1177718-1-horatiu.vultur@microchip.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/pinctrl-ocelot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index a4a1b00f7f0d..c42a5b0bc4f0 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -575,7 +575,7 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, regmap_update_bits(info->map, REG_ALT(0, info, pin->pin), BIT(p), f << p); regmap_update_bits(info->map, REG_ALT(1, info, pin->pin), - BIT(p), f << (p - 1)); + BIT(p), (f >> 1) << p); return 0; } From 449a1a61f7f148aed285cd098e940ae6bc19246a Mon Sep 17 00:00:00 2001 From: msizanoen Date: Sun, 19 Mar 2023 23:02:56 -0700 Subject: [PATCH 0987/1017] Input: alps - fix compatibility with -funsigned-char commit 754ff5060daf5a1cf4474eff9b4edeb6c17ef7ab upstream. The AlpsPS/2 code previously relied on the assumption that `char` is a signed type, which was true on x86 platforms (the only place where this driver is used) before kernel 6.2. However, on 6.2 and later, this assumption is broken due to the introduction of -funsigned-char as a new global compiler flag. Fix this by explicitly specifying the signedness of `char` when sign extending the values received from the device. Fixes: f3f33c677699 ("Input: alps - Rushmore and v7 resolution support") Signed-off-by: msizanoen Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230320045228.182259-1-msizanoen@qtmlabs.xyz Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/alps.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index b067bfd2699c..0b10c466659e 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -852,8 +852,8 @@ static void alps_process_packet_v6(struct psmouse *psmouse) x = y = z = 0; /* Divide 4 since trackpoint's speed is too fast */ - input_report_rel(dev2, REL_X, (char)x / 4); - input_report_rel(dev2, REL_Y, -((char)y / 4)); + input_report_rel(dev2, REL_X, (s8)x / 4); + input_report_rel(dev2, REL_Y, -((s8)y / 4)); psmouse_report_standard_buttons(dev2, packet[3]); @@ -1104,8 +1104,8 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) ((packet[3] & 0x20) << 1); z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1); - input_report_rel(dev2, REL_X, (char)x); - input_report_rel(dev2, REL_Y, -((char)y)); + input_report_rel(dev2, REL_X, (s8)x); + input_report_rel(dev2, REL_Y, -((s8)y)); input_report_abs(dev2, ABS_PRESSURE, z); psmouse_report_standard_buttons(dev2, packet[1]); @@ -2294,20 +2294,20 @@ static int alps_get_v3_v7_resolution(struct psmouse *psmouse, int reg_pitch) if (reg < 0) return reg; - x_pitch = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */ + x_pitch = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */ x_pitch = 50 + 2 * x_pitch; /* In 0.1 mm units */ - y_pitch = (char)reg >> 4; /* sign extend upper 4 bits */ + y_pitch = (s8)reg >> 4; /* sign extend upper 4 bits */ y_pitch = 36 + 2 * y_pitch; /* In 0.1 mm units */ reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1); if (reg < 0) return reg; - x_electrode = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */ + x_electrode = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */ x_electrode = 17 + x_electrode; - y_electrode = (char)reg >> 4; /* sign extend upper 4 bits */ + y_electrode = (s8)reg >> 4; /* sign extend upper 4 bits */ y_electrode = 13 + y_electrode; x_phys = x_pitch * (x_electrode - 1); /* In 0.1 mm units */ From 8b3d7ad3e8f13a90d56c4d6b3b4eee78634615ab Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 19 Mar 2023 21:36:36 -0700 Subject: [PATCH 0988/1017] Input: focaltech - use explicitly signed char type commit 8980f190947ba29f23110408e712444884b74251 upstream. The recent change of -funsigned-char causes additions of negative numbers to become additions of large positive numbers, leading to wrong calculations of mouse movement. Change these casts to be explicitly signed, to take into account negative offsets. Fixes: 3bc753c06dd0 ("kbuild: treat char as always unsigned") Signed-off-by: Jason A. Donenfeld Reviewed-by: Hans de Goede Cc: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=217211 Link: https://lore.kernel.org/r/20230318133010.1285202-1-Jason@zx2c4.com Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/mouse/focaltech.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index 6fd5fff0cbff..c74b99077d16 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -202,8 +202,8 @@ static void focaltech_process_rel_packet(struct psmouse *psmouse, state->pressed = packet[0] >> 7; finger1 = ((packet[0] >> 4) & 0x7) - 1; if (finger1 < FOC_MAX_FINGERS) { - state->fingers[finger1].x += (char)packet[1]; - state->fingers[finger1].y += (char)packet[2]; + state->fingers[finger1].x += (s8)packet[1]; + state->fingers[finger1].y += (s8)packet[2]; } else { psmouse_err(psmouse, "First finger in rel packet invalid: %d\n", finger1); @@ -218,8 +218,8 @@ static void focaltech_process_rel_packet(struct psmouse *psmouse, */ finger2 = ((packet[3] >> 4) & 0x7) - 1; if (finger2 < FOC_MAX_FINGERS) { - state->fingers[finger2].x += (char)packet[4]; - state->fingers[finger2].y += (char)packet[5]; + state->fingers[finger2].x += (s8)packet[4]; + state->fingers[finger2].y += (s8)packet[5]; } } From 63bbe24b99f9187584be28a3a2336dddb5524c95 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 29 Mar 2023 17:14:22 -0300 Subject: [PATCH 0989/1017] cifs: prevent infinite recursion in CIFSGetDFSRefer() commit 09ba47b44d26b475bbdf9c80db9e0193d2b58956 upstream. We can't call smb_init() in CIFSGetDFSRefer() as cifs_reconnect_tcon() may end up calling CIFSGetDFSRefer() again to get new DFS referrals and thus causing an infinite recursion. Signed-off-by: Paulo Alcantara (SUSE) Reviewed-by: Ronnie Sahlberg Cc: stable@vger.kernel.org # 6.2 Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/cifssmb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c279527aae92..95992c93bbe3 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -4859,8 +4859,13 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, return -ENODEV; getDFSRetry: - rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB, - (void **) &pSMBr); + /* + * Use smb_init_no_reconnect() instead of smb_init() as + * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus + * causing an infinite recursion. + */ + rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, + (void **)&pSMB, (void **)&pSMBr); if (rc) return rc; From 26a32a212bc540f4773cd6af8cf73e967d72569c Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 29 Mar 2023 22:24:06 +0200 Subject: [PATCH 0990/1017] cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL commit 179a88a8558bbf42991d361595281f3e45d7edfc upstream. When compiled with CONFIG_CIFS_DFS_UPCALL disabled, cifs_dfs_d_automount is NULL. cifs.ko logic for mapping CIFS_FATTR_DFS_REFERRAL attributes to S_AUTOMOUNT and corresponding dentry flags is retained regardless of CONFIG_CIFS_DFS_UPCALL, leading to a NULL pointer dereference in VFS follow_automount() when traversing a DFS referral link: BUG: kernel NULL pointer dereference, address: 0000000000000000 ... Call Trace: __traverse_mounts+0xb5/0x220 ? cifs_revalidate_mapping+0x65/0xc0 [cifs] step_into+0x195/0x610 ? lookup_fast+0xe2/0xf0 path_lookupat+0x64/0x140 filename_lookup+0xc2/0x140 ? __create_object+0x299/0x380 ? kmem_cache_alloc+0x119/0x220 ? user_path_at_empty+0x31/0x50 user_path_at_empty+0x31/0x50 __x64_sys_chdir+0x2a/0xd0 ? exit_to_user_mode_prepare+0xca/0x100 do_syscall_64+0x42/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc This fix adds an inline cifs_dfs_d_automount() {return -EREMOTE} handler when CONFIG_CIFS_DFS_UPCALL is disabled. An alternative would be to avoid flagging S_AUTOMOUNT, etc. without CONFIG_CIFS_DFS_UPCALL. This approach was chosen as it provides more control over the error path. Signed-off-by: David Disseldorp Cc: stable@vger.kernel.org Reviewed-by: Paulo Alcantara (SUSE) Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/cifsfs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index e996f0bef414..59c41412ebaf 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -126,7 +126,10 @@ extern const struct dentry_operations cifs_ci_dentry_ops; #ifdef CONFIG_CIFS_DFS_UPCALL extern struct vfsmount *cifs_dfs_d_automount(struct path *path); #else -#define cifs_dfs_d_automount NULL +static inline struct vfsmount *cifs_dfs_d_automount(struct path *path) +{ + return ERR_PTR(-EREMOTE); +} #endif /* Functions related to symlinks */ From ba5deb64ddde2cb68b981f4d108b5cbed2633cfb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 17 Mar 2023 03:13:12 -0700 Subject: [PATCH 0991/1017] Input: goodix - add Lenovo Yoga Book X90F to nine_bytes_report DMI table commit 8a0432bab6ea3203d220785da7ab3c7677f70ecb upstream. The Android Lenovo Yoga Book X90F / X90L uses the same goodix touchscreen with 9 bytes touch reports for its touch keyboard as the already supported Windows Lenovo Yoga Book X91F/L, add a DMI match for this to the nine_bytes_report DMI table. When the quirk for the X91F/L was initially added it was written to also apply to the X90F/L but this does not work because the Android version of the Yoga Book uses completely different DMI strings. Also adjust the X91F/L quirk to reflect that it only applies to the X91F/L models. Signed-off-by: Hans de Goede Reviewed-by: Bastien Nocera Link: https://lore.kernel.org/r/20230315134442.71787-1-hdegoede@redhat.com Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/touchscreen/goodix.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index b7f87ad4b9a9..098115eb8084 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -183,10 +183,18 @@ static const unsigned long goodix_irq_flags[] = { static const struct dmi_system_id nine_bytes_report[] = { #if defined(CONFIG_DMI) && defined(CONFIG_X86) { - .ident = "Lenovo YogaBook", - /* YB1-X91L/F and YB1-X90L/F */ + /* Lenovo Yoga Book X90F / X90L */ .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9") + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), + } + }, + { + /* Lenovo Yoga Book X91F / X91L */ + .matches = { + /* Non exact match to match F + L versions */ + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), } }, #endif From 5f6347034341bf45056ca1ec3fa72040152ecf83 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 22 Mar 2023 10:33:28 +0000 Subject: [PATCH 0992/1017] btrfs: fix race between quota disable and quota assign ioctls commit 2f1a6be12ab6c8470d5776e68644726c94257c54 upstream. The quota assign ioctl can currently run in parallel with a quota disable ioctl call. The assign ioctl uses the quota root, while the disable ioctl frees that root, and therefore we can have a use-after-free triggered in the assign ioctl, leading to a trace like the following when KASAN is enabled: [672.723][T736] BUG: KASAN: slab-use-after-free in btrfs_search_slot+0x2962/0x2db0 [672.723][T736] Read of size 8 at addr ffff888022ec0208 by task btrfs_search_sl/27736 [672.724][T736] [672.725][T736] CPU: 1 PID: 27736 Comm: btrfs_search_sl Not tainted 6.3.0-rc3 #37 [672.723][T736] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [672.727][T736] Call Trace: [672.728][T736] [672.728][T736] dump_stack_lvl+0xd9/0x150 [672.725][T736] print_report+0xc1/0x5e0 [672.720][T736] ? __virt_addr_valid+0x61/0x2e0 [672.727][T736] ? __phys_addr+0xc9/0x150 [672.725][T736] ? btrfs_search_slot+0x2962/0x2db0 [672.722][T736] kasan_report+0xc0/0xf0 [672.729][T736] ? btrfs_search_slot+0x2962/0x2db0 [672.724][T736] btrfs_search_slot+0x2962/0x2db0 [672.723][T736] ? fs_reclaim_acquire+0xba/0x160 [672.722][T736] ? split_leaf+0x13d0/0x13d0 [672.726][T736] ? rcu_is_watching+0x12/0xb0 [672.723][T736] ? kmem_cache_alloc+0x338/0x3c0 [672.722][T736] update_qgroup_status_item+0xf7/0x320 [672.724][T736] ? add_qgroup_rb+0x3d0/0x3d0 [672.739][T736] ? do_raw_spin_lock+0x12d/0x2b0 [672.730][T736] ? spin_bug+0x1d0/0x1d0 [672.737][T736] btrfs_run_qgroups+0x5de/0x840 [672.730][T736] ? btrfs_qgroup_rescan_worker+0xa70/0xa70 [672.738][T736] ? __del_qgroup_relation+0x4ba/0xe00 [672.738][T736] btrfs_ioctl+0x3d58/0x5d80 [672.735][T736] ? tomoyo_path_number_perm+0x16a/0x550 [672.737][T736] ? tomoyo_execute_permission+0x4a0/0x4a0 [672.731][T736] ? btrfs_ioctl_get_supported_features+0x50/0x50 [672.737][T736] ? __sanitizer_cov_trace_switch+0x54/0x90 [672.734][T736] ? do_vfs_ioctl+0x132/0x1660 [672.730][T736] ? vfs_fileattr_set+0xc40/0xc40 [672.730][T736] ? _raw_spin_unlock_irq+0x2e/0x50 [672.732][T736] ? sigprocmask+0xf2/0x340 [672.737][T736] ? __fget_files+0x26a/0x480 [672.732][T736] ? bpf_lsm_file_ioctl+0x9/0x10 [672.738][T736] ? btrfs_ioctl_get_supported_features+0x50/0x50 [672.736][T736] __x64_sys_ioctl+0x198/0x210 [672.736][T736] do_syscall_64+0x39/0xb0 [672.731][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.739][T736] RIP: 0033:0x4556ad [672.742][T736] [672.743][T736] [672.748][T736] Allocated by task 27677: [672.743][T736] kasan_save_stack+0x22/0x40 [672.741][T736] kasan_set_track+0x25/0x30 [672.741][T736] __kasan_kmalloc+0xa4/0xb0 [672.749][T736] btrfs_alloc_root+0x48/0x90 [672.746][T736] btrfs_create_tree+0x146/0xa20 [672.744][T736] btrfs_quota_enable+0x461/0x1d20 [672.743][T736] btrfs_ioctl+0x4a1c/0x5d80 [672.747][T736] __x64_sys_ioctl+0x198/0x210 [672.749][T736] do_syscall_64+0x39/0xb0 [672.744][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.756][T736] [672.757][T736] Freed by task 27677: [672.759][T736] kasan_save_stack+0x22/0x40 [672.759][T736] kasan_set_track+0x25/0x30 [672.756][T736] kasan_save_free_info+0x2e/0x50 [672.751][T736] ____kasan_slab_free+0x162/0x1c0 [672.758][T736] slab_free_freelist_hook+0x89/0x1c0 [672.752][T736] __kmem_cache_free+0xaf/0x2e0 [672.752][T736] btrfs_put_root+0x1ff/0x2b0 [672.759][T736] btrfs_quota_disable+0x80a/0xbc0 [672.752][T736] btrfs_ioctl+0x3e5f/0x5d80 [672.756][T736] __x64_sys_ioctl+0x198/0x210 [672.753][T736] do_syscall_64+0x39/0xb0 [672.765][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.769][T736] [672.768][T736] The buggy address belongs to the object at ffff888022ec0000 [672.768][T736] which belongs to the cache kmalloc-4k of size 4096 [672.769][T736] The buggy address is located 520 bytes inside of [672.769][T736] freed 4096-byte region [ffff888022ec0000, ffff888022ec1000) [672.760][T736] [672.764][T736] The buggy address belongs to the physical page: [672.761][T736] page:ffffea00008bb000 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x22ec0 [672.766][T736] head:ffffea00008bb000 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [672.779][T736] flags: 0xfff00000010200(slab|head|node=0|zone=1|lastcpupid=0x7ff) [672.770][T736] raw: 00fff00000010200 ffff888012842140 ffffea000054ba00 dead000000000002 [672.770][T736] raw: 0000000000000000 0000000000040004 00000001ffffffff 0000000000000000 [672.771][T736] page dumped because: kasan: bad access detected [672.778][T736] page_owner tracks the page as allocated [672.777][T736] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd2040(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 88 [672.779][T736] get_page_from_freelist+0x119c/0x2d50 [672.779][T736] __alloc_pages+0x1cb/0x4a0 [672.776][T736] alloc_pages+0x1aa/0x270 [672.773][T736] allocate_slab+0x260/0x390 [672.771][T736] ___slab_alloc+0xa9a/0x13e0 [672.778][T736] __slab_alloc.constprop.0+0x56/0xb0 [672.771][T736] __kmem_cache_alloc_node+0x136/0x320 [672.789][T736] __kmalloc+0x4e/0x1a0 [672.783][T736] tomoyo_realpath_from_path+0xc3/0x600 [672.781][T736] tomoyo_path_perm+0x22f/0x420 [672.782][T736] tomoyo_path_unlink+0x92/0xd0 [672.780][T736] security_path_unlink+0xdb/0x150 [672.788][T736] do_unlinkat+0x377/0x680 [672.788][T736] __x64_sys_unlink+0xca/0x110 [672.789][T736] do_syscall_64+0x39/0xb0 [672.783][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.784][T736] page last free stack trace: [672.787][T736] free_pcp_prepare+0x4e5/0x920 [672.787][T736] free_unref_page+0x1d/0x4e0 [672.784][T736] __unfreeze_partials+0x17c/0x1a0 [672.797][T736] qlist_free_all+0x6a/0x180 [672.796][T736] kasan_quarantine_reduce+0x189/0x1d0 [672.797][T736] __kasan_slab_alloc+0x64/0x90 [672.793][T736] kmem_cache_alloc+0x17c/0x3c0 [672.799][T736] getname_flags.part.0+0x50/0x4e0 [672.799][T736] getname_flags+0x9e/0xe0 [672.792][T736] vfs_fstatat+0x77/0xb0 [672.791][T736] __do_sys_newlstat+0x84/0x100 [672.798][T736] do_syscall_64+0x39/0xb0 [672.796][T736] entry_SYSCALL_64_after_hwframe+0x63/0xcd [672.790][T736] [672.791][T736] Memory state around the buggy address: [672.799][T736] ffff888022ec0100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.805][T736] ffff888022ec0180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.802][T736] >ffff888022ec0200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.809][T736] ^ [672.809][T736] ffff888022ec0280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [672.809][T736] ffff888022ec0300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb Fix this by having the qgroup assign ioctl take the qgroup ioctl mutex before calling btrfs_run_qgroups(), which is what all qgroup ioctls should call. Reported-by: butt3rflyh4ck Link: https://lore.kernel.org/linux-btrfs/CAFcO6XN3VD8ogmHwqRk4kbiwtpUSNySu2VAxN8waEPciCHJvMA@mail.gmail.com/ CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ioctl.c | 2 ++ fs/btrfs/qgroup.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index fc335b5e44df..10686b494f0a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4254,7 +4254,9 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) } /* update qgroup status and info */ + mutex_lock(&fs_info->qgroup_ioctl_lock); err = btrfs_run_qgroups(trans); + mutex_unlock(&fs_info->qgroup_ioctl_lock); if (err < 0) btrfs_handle_fs_error(fs_info, err, "failed to update qgroup status and info"); diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 9fe6a01ea8b8..3fc689154bb5 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2762,13 +2762,22 @@ cleanup: } /* - * called from commit_transaction. Writes all changed qgroups to disk. + * Writes all changed qgroups to disk. + * Called by the transaction commit path and the qgroup assign ioctl. */ int btrfs_run_qgroups(struct btrfs_trans_handle *trans) { struct btrfs_fs_info *fs_info = trans->fs_info; int ret = 0; + /* + * In case we are called from the qgroup assign ioctl, assert that we + * are holding the qgroup_ioctl_lock, otherwise we can race with a quota + * disable operation (ioctl) and access a freed quota root. + */ + if (trans->transaction->state != TRANS_STATE_COMMIT_DOING) + lockdep_assert_held(&fs_info->qgroup_ioctl_lock); + if (!fs_info->quota_root) return ret; From b3d7a4478ce0a32bccef6631d3330e3bbc4090a9 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 27 Mar 2023 10:36:45 +0200 Subject: [PATCH 0993/1017] xen/netback: don't do grant copy across page boundary commit 05310f31ca74673a96567fb14637b7d5d6c82ea5 upstream. Fix xenvif_get_requests() not to do grant copy operations across local page boundaries. This requires to double the maximum number of copy operations per queue, as each copy could now be split into 2. Make sure that struct xenvif_tx_cb doesn't grow too large. Cc: stable@vger.kernel.org Fixes: ad7f402ae4f4 ("xen/netback: Ensure protocol headers don't fall in the non-linear area") Signed-off-by: Juergen Gross Reviewed-by: Paul Durrant Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/common.h | 2 +- drivers/net/xen-netback/netback.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 1ba974969216..fe99439ad5fb 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -166,7 +166,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */ struct pending_tx_info pending_tx_info[MAX_PENDING_REQS]; grant_handle_t grant_tx_handle[MAX_PENDING_REQS]; - struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS]; + struct gnttab_copy tx_copy_ops[2 * MAX_PENDING_REQS]; struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS]; struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS]; /* passed to gnttab_[un]map_refs with pages under (un)mapping */ diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f9373a88cf37..67614e7166ac 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -334,6 +334,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue, struct xenvif_tx_cb { u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1]; u8 copy_count; + u32 split_mask; }; #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb) @@ -361,6 +362,8 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size) struct sk_buff *skb = alloc_skb(size + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC | __GFP_NOWARN); + + BUILD_BUG_ON(sizeof(*XENVIF_TX_CB(skb)) > sizeof(skb->cb)); if (unlikely(skb == NULL)) return NULL; @@ -396,11 +399,13 @@ static void xenvif_get_requests(struct xenvif_queue *queue, nr_slots = shinfo->nr_frags + 1; copy_count(skb) = 0; + XENVIF_TX_CB(skb)->split_mask = 0; /* Create copy ops for exactly data_len bytes into the skb head. */ __skb_put(skb, data_len); while (data_len > 0) { int amount = data_len > txp->size ? txp->size : data_len; + bool split = false; cop->source.u.ref = txp->gref; cop->source.domid = queue->vif->domid; @@ -413,6 +418,13 @@ static void xenvif_get_requests(struct xenvif_queue *queue, cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb) - data_len); + /* Don't cross local page boundary! */ + if (cop->dest.offset + amount > XEN_PAGE_SIZE) { + amount = XEN_PAGE_SIZE - cop->dest.offset; + XENVIF_TX_CB(skb)->split_mask |= 1U << copy_count(skb); + split = true; + } + cop->len = amount; cop->flags = GNTCOPY_source_gref; @@ -420,7 +432,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, pending_idx = queue->pending_ring[index]; callback_param(queue, pending_idx).ctx = NULL; copy_pending_idx(skb, copy_count(skb)) = pending_idx; - copy_count(skb)++; + if (!split) + copy_count(skb)++; cop++; data_len -= amount; @@ -441,7 +454,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue, nr_slots--; } else { /* The copy op partially covered the tx_request. - * The remainder will be mapped. + * The remainder will be mapped or copied in the next + * iteration. */ txp->offset += amount; txp->size -= amount; @@ -539,6 +553,13 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue, pending_idx = copy_pending_idx(skb, i); newerr = (*gopp_copy)->status; + + /* Split copies need to be handled together. */ + if (XENVIF_TX_CB(skb)->split_mask & (1U << i)) { + (*gopp_copy)++; + if (!newerr) + newerr = (*gopp_copy)->status; + } if (likely(!newerr)) { /* The first frag might still have this slot mapped */ if (i < copy_count(skb) - 1 || !sharedslot) From fbf3fe7f7bc3713ef191c1edcc30a46e90c1ea09 Mon Sep 17 00:00:00 2001 From: Josua Mayer Date: Thu, 23 Mar 2023 12:25:36 +0200 Subject: [PATCH 0994/1017] net: phy: dp83869: fix default value for tx-/rx-internal-delay commit 82e2c39f9ef78896e9b634dfd82dc042e6956bb7 upstream. dp83869 internally uses a look-up table for mapping supported delays in nanoseconds to register values. When specific delays are defined in device-tree, phy_get_internal_delay does the lookup automatically returning an index. The default case wrongly assigns the nanoseconds value from the lookup table, resulting in numeric value 2000 applied to delay configuration register, rather than the expected index values 0-7 (7 for 2000). Ultimately this issue broke RX for 1Gbps links. Fix default delay configuration by assigning the intended index value directly. Cc: stable@vger.kernel.org Fixes: 736b25afe284 ("net: dp83869: Add RGMII internal delay configuration") Co-developed-by: Yazan Shhady Signed-off-by: Yazan Shhady Signed-off-by: Josua Mayer Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230323102536.31988-1-josua@solid-run.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/dp83869.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c index a9daff88006b..65b69ff35e40 100644 --- a/drivers/net/phy/dp83869.c +++ b/drivers/net/phy/dp83869.c @@ -553,15 +553,13 @@ static int dp83869_of_init(struct phy_device *phydev) &dp83869_internal_delay[0], delay_size, true); if (dp83869->rx_int_delay < 0) - dp83869->rx_int_delay = - dp83869_internal_delay[DP83869_CLK_DELAY_DEF]; + dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF; dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev, &dp83869_internal_delay[0], delay_size, false); if (dp83869->tx_int_delay < 0) - dp83869->tx_int_delay = - dp83869_internal_delay[DP83869_CLK_DELAY_DEF]; + dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF; return ret; } From 25065ed83b5ffaada1768e0416c6e96fdb8da032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Dul=C4=99ba?= Date: Mon, 20 Mar 2023 09:32:59 +0000 Subject: [PATCH 0995/1017] pinctrl: amd: Disable and mask interrupts on resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b26cd9325be4c1fcd331b77f10acb627c560d4d7 upstream. This fixes a similar problem to the one observed in: commit 4e5a04be88fe ("pinctrl: amd: disable and mask interrupts on probe"). On some systems, during suspend/resume cycle firmware leaves an interrupt enabled on a pin that is not used by the kernel. This confuses the AMD pinctrl driver and causes spurious interrupts. The driver already has logic to detect if a pin is used by the kernel. Leverage it to re-initialize interrupt fields of a pin only if it's not used by us. Cc: stable@vger.kernel.org Fixes: dbad75dd1f25 ("pinctrl: add AMD GPIO driver support.") Signed-off-by: Kornel Dulęba Link: https://lore.kernel.org/r/20230320093259.845178-1-korneld@chromium.org Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/pinctrl-amd.c | 36 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 82b658a3c220..7bfdf5ad77c4 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -764,32 +764,34 @@ static const struct pinconf_ops amd_pinconf_ops = { .pin_config_group_set = amd_pinconf_group_set, }; -static void amd_gpio_irq_init(struct amd_gpio *gpio_dev) +static void amd_gpio_irq_init_pin(struct amd_gpio *gpio_dev, int pin) { - struct pinctrl_desc *desc = gpio_dev->pctrl->desc; + const struct pin_desc *pd; unsigned long flags; u32 pin_reg, mask; - int i; mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3) | BIT(INTERRUPT_MASK_OFF) | BIT(INTERRUPT_ENABLE_OFF) | BIT(WAKE_CNTRL_OFF_S4); - for (i = 0; i < desc->npins; i++) { - int pin = desc->pins[i].number; - const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin); + pd = pin_desc_get(gpio_dev->pctrl, pin); + if (!pd) + return; - if (!pd) - continue; + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + pin_reg = readl(gpio_dev->base + pin * 4); + pin_reg &= ~mask; + writel(pin_reg, gpio_dev->base + pin * 4); + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); +} - raw_spin_lock_irqsave(&gpio_dev->lock, flags); +static void amd_gpio_irq_init(struct amd_gpio *gpio_dev) +{ + struct pinctrl_desc *desc = gpio_dev->pctrl->desc; + int i; - pin_reg = readl(gpio_dev->base + i * 4); - pin_reg &= ~mask; - writel(pin_reg, gpio_dev->base + i * 4); - - raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); - } + for (i = 0; i < desc->npins; i++) + amd_gpio_irq_init_pin(gpio_dev, i); } #ifdef CONFIG_PM_SLEEP @@ -842,8 +844,10 @@ static int amd_gpio_resume(struct device *dev) for (i = 0; i < desc->npins; i++) { int pin = desc->pins[i].number; - if (!amd_gpio_should_save(gpio_dev, pin)) + if (!amd_gpio_should_save(gpio_dev, pin)) { + amd_gpio_irq_init_pin(gpio_dev, pin); continue; + } raw_spin_lock_irqsave(&gpio_dev->lock, flags); gpio_dev->saved_regs[i] |= readl(gpio_dev->base + pin * 4) & PIN_IRQ_PENDING; From 12c2612e18cabec2320b7068e829f0101d0254f2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 24 Feb 2023 14:08:28 +0100 Subject: [PATCH 0996/1017] pinctrl: at91-pio4: fix domain name assignment commit 7bb97e360acdd38b68ad0a1defb89c6e89c85596 upstream. Since commit d59f6617eef0 ("genirq: Allow fwnode to carry name information only") an IRQ domain is always given a name during allocation (e.g. used for the debugfs entry). Drop the no longer valid name assignment, which would lead to an attempt to free a string constant when removing the domain on late probe failures (e.g. probe deferral). Fixes: d59f6617eef0 ("genirq: Allow fwnode to carry name information only") Cc: stable@vger.kernel.org # 4.13 Signed-off-by: Johan Hovold Reviewed-by: Claudiu Beznea Tested-by: Claudiu Beznea # on SAMA7G5 Link: https://lore.kernel.org/r/20230224130828.27985-1-johan+linaro@kernel.org Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/pinctrl-at91-pio4.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index d2e2b101978f..315a6c4d9ade 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -1139,7 +1139,6 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) dev_err(dev, "can't add the irq domain\n"); return -ENODEV; } - atmel_pioctrl->irq_domain->name = "atmel gpio"; for (i = 0; i < atmel_pioctrl->npins; i++) { int irq = irq_create_mapping(atmel_pioctrl->irq_domain, i); From 80a4200d51e5a7e046f4a90f5faa5bafd5a60c58 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 26 Mar 2023 16:15:57 -0600 Subject: [PATCH 0997/1017] powerpc: Don't try to copy PPR for task with NULL pt_regs commit fd7276189450110ed835eb0a334e62d2f1c4e3be upstream. powerpc sets up PF_KTHREAD and PF_IO_WORKER with a NULL pt_regs, which from my (arguably very short) checking is not commonly done for other archs. This is fine, except when PF_IO_WORKER's have been created and the task does something that causes a coredump to be generated. Then we get this crash: Kernel attempted to read user page (160) - exploit attempt? (uid: 1000) BUG: Kernel NULL pointer dereference on read at 0x00000160 Faulting instruction address: 0xc0000000000c3a60 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=32 NUMA pSeries Modules linked in: bochs drm_vram_helper drm_kms_helper xts binfmt_misc ecb ctr syscopyarea sysfillrect cbc sysimgblt drm_ttm_helper aes_generic ttm sg libaes evdev joydev virtio_balloon vmx_crypto gf128mul drm dm_mod fuse loop configfs drm_panel_orientation_quirks ip_tables x_tables autofs4 hid_generic usbhid hid xhci_pci xhci_hcd usbcore usb_common sd_mod CPU: 1 PID: 1982 Comm: ppc-crash Not tainted 6.3.0-rc2+ #88 Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries NIP: c0000000000c3a60 LR: c000000000039944 CTR: c0000000000398e0 REGS: c0000000041833b0 TRAP: 0300 Not tainted (6.3.0-rc2+) MSR: 800000000280b033 CR: 88082828 XER: 200400f8 ... NIP memcpy_power7+0x200/0x7d0 LR ppr_get+0x64/0xb0 Call Trace: ppr_get+0x40/0xb0 (unreliable) __regset_get+0x180/0x1f0 regset_get_alloc+0x64/0x90 elf_core_dump+0xb98/0x1b60 do_coredump+0x1c34/0x24a0 get_signal+0x71c/0x1410 do_notify_resume+0x140/0x6f0 interrupt_exit_user_prepare_main+0x29c/0x320 interrupt_exit_user_prepare+0x6c/0xa0 interrupt_return_srr_user+0x8/0x138 Because ppr_get() is trying to copy from a PF_IO_WORKER with a NULL pt_regs. Check for a valid pt_regs in both ppc_get/ppr_set, and return an error if not set. The actual error value doesn't seem to be important here, so just pick -EINVAL. Fixes: fa439810cc1b ("powerpc/ptrace: Enable support for NT_PPPC_TAR, NT_PPC_PPR, NT_PPC_DSCR") Cc: stable@vger.kernel.org # v4.8+ Signed-off-by: Jens Axboe [mpe: Trim oops in change log, add Fixes & Cc stable] Signed-off-by: Michael Ellerman Link: https://msgid.link/d9f63344-fe7c-56ae-b420-4a1a04a2ae4c@kernel.dk Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/ptrace/ptrace-view.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c index 7e6478e7ed07..67c126d4f431 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-view.c +++ b/arch/powerpc/kernel/ptrace/ptrace-view.c @@ -298,6 +298,9 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset, static int ppr_get(struct task_struct *target, const struct user_regset *regset, struct membuf to) { + if (!target->thread.regs) + return -EINVAL; + return membuf_write(&to, &target->thread.regs->ppr, sizeof(u64)); } @@ -305,6 +308,9 @@ static int ppr_set(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { + if (!target->thread.regs) + return -EINVAL; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.regs->ppr, 0, sizeof(u64)); } From 3d328a17c8cb4117cfa8d711d91faeb7c7819484 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 21 Mar 2023 00:17:36 -0400 Subject: [PATCH 0998/1017] NFSv4: Fix hangs when recovering open state after a server reboot commit 6165a16a5ad9b237bb3131cff4d3c601ccb8f9a3 upstream. When we're using a cached open stateid or a delegation in order to avoid sending a CLAIM_PREVIOUS open RPC call to the server, we don't have a new open stateid to present to update_open_stateid(). Instead rely on nfs4_try_open_cached(), just as if we were doing a normal open. Fixes: d2bfda2e7aa0 ("NFSv4: don't reprocess cached open CLAIM_PREVIOUS") Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker Signed-off-by: Greg Kroah-Hartman --- fs/nfs/nfs4proc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8653335c17b6..bca5d1bdd79b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1975,8 +1975,7 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data) if (!data->rpc_done) { if (data->rpc_status) return ERR_PTR(data->rpc_status); - /* cached opens have already been processed */ - goto update; + return nfs4_try_open_cached(data); } ret = nfs_refresh_inode(inode, &data->f_attr); @@ -1985,7 +1984,7 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data) if (data->o_res.delegation_type != 0) nfs4_opendata_check_deleg(data, state); -update: + if (!update_open_stateid(state, &data->o_res.stateid, NULL, data->o_arg.fmode)) return ERR_PTR(-EAGAIN); From 0044721f4f9553f4001f5a469ac45d2a10e17139 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Mar 2023 15:09:54 +0100 Subject: [PATCH 0999/1017] ALSA: hda/conexant: Partial revert of a quirk for Lenovo commit b871cb971c683f7f212e7ca3c9a6709a75785116 upstream. The recent commit f83bb2592482 ("ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model") introduced a quirk for the device with 17aa:3977, but this caused a regression on another model (Lenovo Ideadpad U31) with the very same PCI SSID. And, through skimming over the net, it seems that this PCI SSID is used for multiple different models, so it's no good idea to apply the quirk with the SSID. Although we may take a different ID check (e.g. the codec SSID instead of the PCI SSID), unfortunately, the original patch author couldn't identify the hardware details any longer as the machine was returned, and we can't develop the further proper fix. In this patch, instead, we partially revert the change so that the quirk won't be applied as default for addressing the regression. Meanwhile, the quirk function itself is kept, and it's now made to be applicable via the explicit model=lenovo-20149 option. Fixes: f83bb2592482 ("ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model") Reported-by: Jetro Jormalainen Link: https://lore.kernel.org/r/20230308215009.4d3e58a6@mopti Cc: Link: https://lore.kernel.org/r/20230320140954.31154-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_conexant.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 48b802563c2d..e35c470eb481 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -973,7 +973,10 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_PINCFG_LENOVO_NOTEBOOK), + /* NOTE: we'd need to extend the quirk for 17aa:3977 as the same + * PCI SSID is used on multiple Lenovo models + */ + SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI), @@ -996,6 +999,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, + { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, {} }; From 3b6992bdf09d7e46e9bfb92a98c4ca1f2779466a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 24 Mar 2023 08:50:05 +0100 Subject: [PATCH 1000/1017] ALSA: usb-audio: Fix regression on detection of Roland VS-100 commit fa4e7a6fa12b1132340785e14bd439cbe95b7a5a upstream. It's been reported that the recent kernel can't probe the PCM devices on Roland VS-100 properly, and it turned out to be a regression by the recent addition of the bit shift range check for the format bits. In the old code, we just did bit-shift and it resulted in zero, which is then corrected to the standard PCM format, while the new code explicitly returns an error in such a case. For addressing the regression, relax the check and fallback to the standard PCM type (with the info output). Fixes: 43d5ca88dfcd ("ALSA: usb-audio: Fix potential out-of-bounds shift") Cc: Link: https://bugzilla.kernel.org/show_bug.cgi?id=217084 Link: https://lore.kernel.org/r/20230324075005.19403-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/format.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/usb/format.c b/sound/usb/format.c index e8a63ea2189d..e0fda244a942 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -40,8 +40,12 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, case UAC_VERSION_1: default: { struct uac_format_type_i_discrete_descriptor *fmt = _fmt; - if (format >= 64) - return 0; /* invalid format */ + if (format >= 64) { + usb_audio_info(chip, + "%u:%d: invalid format type 0x%llx is detected, processed as PCM\n", + fp->iface, fp->altsetting, format); + format = UAC_FORMAT_TYPE_I_PCM; + } sample_width = fmt->bBitResolution; sample_bytes = fmt->bSubframeSize; format = 1ULL << format; From 8ada1b5c8b43222d962231c58aebe4c72e5bf90c Mon Sep 17 00:00:00 2001 From: huangwenhui Date: Tue, 28 Mar 2023 15:46:44 +0800 Subject: [PATCH 1001/1017] ALSA: hda/realtek: Add quirk for Lenovo ZhaoYang CF4620Z commit 52aad39385e1bfdb34a1b405f699a8ef302c58b0 upstream. Fix headset microphone detection on Lenovo ZhaoYang CF4620Z. [ adjusted to be applicable to the latest tree -- tiwai ] Signed-off-by: huangwenhui Cc: Link: https://lore.kernel.org/r/20230328074644.30142-1-huangwenhuia@uniontech.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2cf6600c9ca8..2af9cd7b7999 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9253,6 +9253,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), + SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), From 08bfd05987df2756aaf7b2b8f014c4cdcc6bcb39 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 16 Mar 2023 23:00:21 -0700 Subject: [PATCH 1002/1017] xtensa: fix KASAN report for show_stack commit 1d3b7a788ca7435156809a6bd5b20c95b2370d45 upstream. show_stack dumps raw stack contents which may trigger an unnecessary KASAN report. Fix it by copying stack contents to a temporary buffer with __memcpy and then printing that buffer instead of passing stack pointer directly to the print_hex_dump. Cc: stable@vger.kernel.org Signed-off-by: Max Filippov Signed-off-by: Greg Kroah-Hartman --- arch/xtensa/kernel/traps.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 129f23c0ab55..6af68305b795 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -503,7 +503,7 @@ static size_t kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH; void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) { - size_t len; + size_t len, off = 0; if (!sp) sp = stack_pointer(task); @@ -512,9 +512,17 @@ void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE); printk("%sStack:\n", loglvl); - print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE, - STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE, - sp, len, false); + while (off < len) { + u8 line[STACK_DUMP_LINE_SIZE]; + size_t line_len = len - off > STACK_DUMP_LINE_SIZE ? + STACK_DUMP_LINE_SIZE : len - off; + + __memcpy(line, (u8 *)sp + off, line_len); + print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE, + STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE, + line, line_len, false); + off += STACK_DUMP_LINE_SIZE; + } show_trace(task, sp, loglvl); } From a484f8bec8ee33e596d6936241bb397e76144ef8 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Mon, 6 Mar 2023 12:27:43 +0000 Subject: [PATCH 1003/1017] rcu: Fix rcu_torture_read ftrace event commit d18a04157fc171fd48075e3dc96471bd3b87f0dd upstream. Fix the rcutorturename field so that its size is correctly reported in the text format embedded in trace.dat files. As it stands, it is reported as being of size 1: field:char rcutorturename[8]; offset:8; size:1; signed:0; Signed-off-by: Douglas Raillard Reviewed-by: Mukesh Ojha Cc: stable@vger.kernel.org Fixes: 04ae87a52074e ("ftrace: Rework event_create_dir()") Reviewed-by: Steven Rostedt (Google) [ boqun: Add "Cc" and "Fixes" tags per Steven ] Signed-off-by: Boqun Feng Signed-off-by: Paul E. McKenney Signed-off-by: Greg Kroah-Hartman --- include/trace/events/rcu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 155b5cb43cfd..2d8790e40901 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h @@ -713,7 +713,7 @@ TRACE_EVENT_RCU(rcu_torture_read, TP_ARGS(rcutorturename, rhp, secs, c_old, c), TP_STRUCT__entry( - __field(char, rcutorturename[RCUTORTURENAME_LEN]) + __array(char, rcutorturename, RCUTORTURENAME_LEN) __field(struct rcu_head *, rhp) __field(unsigned long, secs) __field(unsigned long, c_old) From 79815326a516f70af8a79f1a49e50f3efd11a1db Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 24 Feb 2023 18:21:54 +0100 Subject: [PATCH 1004/1017] drm/etnaviv: fix reference leak when mmaping imported buffer commit 963b2e8c428f79489ceeb058e8314554ec9cbe6f upstream. drm_gem_prime_mmap() takes a reference on the GEM object, but before that drm_gem_mmap_obj() already takes a reference, which will be leaked as only one reference is dropped when the mapping is closed. Drop the extra reference when dma_buf_mmap() succeeds. Cc: stable@vger.kernel.org Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 4aa3426a9ba4..33974cc57e32 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -93,7 +93,15 @@ static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj) static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj, struct vm_area_struct *vma) { - return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0); + int ret; + + ret = dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0); + if (!ret) { + /* Drop the reference acquired by drm_gem_mmap_obj(). */ + drm_gem_object_put(&etnaviv_obj->base); + } + + return ret; } static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = { From 7051d51f1241d02a9db159485bddfe508427ab01 Mon Sep 17 00:00:00 2001 From: Fangzhi Zuo Date: Fri, 24 Feb 2023 13:45:21 -0500 Subject: [PATCH 1005/1017] drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub commit f4f3b7dedbe849e780c779ba67365bb1db0d8637 upstream. Traditional synaptics hub has one MST branch device without virtual dpcd. Synaptics cascaded hub has two chained MST branch devices. DSC decoding is performed via root MST branch device, instead of the second MST branch device. Reviewed-by: Hersen Wu Acked-by: Qingqing Zhuo Signed-off-by: Fangzhi Zuo Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 19 +++++++++++++++++++ .../display/amdgpu_dm/amdgpu_dm_mst_types.h | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index d617e98afb76..767b3d31c720 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -164,6 +164,21 @@ static bool needs_dsc_aux_workaround(struct dc_link *link) return false; } +bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port) +{ + u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F + + if (drm_dp_dpcd_read(port->mgr->aux, DP_BRANCH_VENDOR_SPECIFIC_START, &branch_vendor_data, 4) == 4) { + if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && + IS_SYNAPTICS_CASCADED_PANAMERA(link->dpcd_caps.branch_dev_name, branch_vendor_data)) { + DRM_INFO("Synaptics Cascaded MST hub\n"); + return true; + } + } + + return false; +} + static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) { struct dc_sink *dc_sink = aconnector->dc_sink; @@ -185,6 +200,10 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto needs_dsc_aux_workaround(aconnector->dc_link)) aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; + /* synaptics cascaded MST hub case */ + if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port)) + aconnector->dsc_aux = port->mgr->aux; + if (!aconnector->dsc_aux) return false; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index b38bd68121ce..5d60e2bf0bd8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -26,6 +26,18 @@ #ifndef __DAL_AMDGPU_DM_MST_TYPES_H__ #define __DAL_AMDGPU_DM_MST_TYPES_H__ +#define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C + +/** + * Panamera MST Hub detection + * Offset DPCD 050Eh == 0x5A indicates cascaded MST hub case + * Check from beginning of branch device vendor specific field (050Ch) + */ +#define IS_SYNAPTICS_PANAMERA(branchDevName) (((int)branchDevName[4] & 0xF0) == 0x50 ? 1 : 0) +#define BRANCH_HW_REVISION_PANAMERA_A2 0x10 +#define SYNAPTICS_CASCADED_HUB_ID 0x5A +#define IS_SYNAPTICS_CASCADED_PANAMERA(devName, data) ((IS_SYNAPTICS_PANAMERA(devName) && ((int)data[2] == SYNAPTICS_CASCADED_HUB_ID)) ? 1 : 0) + struct amdgpu_display_manager; struct amdgpu_dm_connector; From 3eeff8d26c6dceeaf10b552e8a5ce9010d818f41 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 23 Mar 2023 13:09:16 +0100 Subject: [PATCH 1006/1017] s390/uaccess: add missing earlyclobber annotations to __clear_user() commit 89aba4c26fae4e459f755a18912845c348ee48f3 upstream. Add missing earlyclobber annotation to size, to, and tmp2 operands of the __clear_user() inline assembly since they are modified or written to before the last usage of all input operands. This can lead to incorrect register allocation for the inline assembly. Fixes: 6c2a9e6df604 ("[S390] Use alternative user-copy operations for new hardware.") Reported-by: Mark Rutland Link: https://lore.kernel.org/all/20230321122514.1743889-3-mark.rutland@arm.com/ Cc: stable@vger.kernel.org Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Greg Kroah-Hartman --- arch/s390/lib/uaccess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index 0267405ab7c6..fcfd78f99cb4 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -339,7 +339,7 @@ static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size "4: slgr %0,%0\n" "5:\n" EX_TABLE(0b,2b) EX_TABLE(3b,5b) - : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2) + : "+&a" (size), "+&a" (to), "+a" (tmp1), "=&a" (tmp2) : "a" (empty_zero_page), "d" (reg0) : "cc", "memory"); return size; } From b51e4422952b5c98dad46caa017c233ac783679f Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Thu, 23 Mar 2023 15:56:48 +0800 Subject: [PATCH 1007/1017] btrfs: scan device in non-exclusive mode commit 50d281fc434cb8e2497f5e70a309ccca6b1a09f0 upstream. This fixes mkfs/mount/check failures due to race with systemd-udevd scan. During the device scan initiated by systemd-udevd, other user space EXCL operations such as mkfs, mount, or check may get blocked and result in a "Device or resource busy" error. This is because the device scan process opens the device with the EXCL flag in the kernel. Two reports were received: - btrfs/179 test case, where the fsck command failed with the -EBUSY error - LTP pwritev03 test case, where mkfs.vfs failed with the -EBUSY error, when mkfs.vfs tried to overwrite old btrfs filesystem on the device. In both cases, fsck and mkfs (respectively) were racing with a systemd-udevd device scan, and systemd-udevd won, resulting in the -EBUSY error for fsck and mkfs. Reproducing the problem has been difficult because there is a very small window during which these userspace threads can race to acquire the exclusive device open. Even on the system where the problem was observed, the problem occurrences were anywhere between 10 to 400 iterations and chances of reproducing decreases with debug printk()s. However, an exclusive device open is unnecessary for the scan process, as there are no write operations on the device during scan. Furthermore, during the mount process, the superblock is re-read in the below function call chain: btrfs_mount_root btrfs_open_devices open_fs_devices btrfs_open_one_device btrfs_get_bdev_and_sb So, to fix this issue, removes the FMODE_EXCL flag from the scan operation, and add a comment. The case where mkfs may still write to the device and a scan is running, the btrfs signature is not written at that time so scan will not recognize such device. Reported-by: Sherry Yang Reported-by: kernel test robot Link: https://lore.kernel.org/oe-lkp/202303170839.fdf23068-oliver.sang@intel.com CC: stable@vger.kernel.org # 5.4+ Signed-off-by: Anand Jain Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/volumes.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 15435f983180..83dca79ff042 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1411,8 +1411,17 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags, * later supers, using BTRFS_SUPER_MIRROR_MAX instead */ bytenr = btrfs_sb_offset(0); - flags |= FMODE_EXCL; + /* + * Avoid using flag |= FMODE_EXCL here, as the systemd-udev may + * initiate the device scan which may race with the user's mount + * or mkfs command, resulting in failure. + * Since the device scan is solely for reading purposes, there is + * no need for FMODE_EXCL. Additionally, the devices are read again + * during the mount process. It is ok to get some inconsistent + * values temporarily, as the device paths of the fsid are the only + * required information for assembling the volume. + */ bdev = blkdev_get_by_path(path, flags, holder); if (IS_ERR(bdev)) return ERR_CAST(bdev); From f1c17475a9dcb947dafcebc1c4940750ddf495bb Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Mon, 20 Mar 2023 22:49:15 +0900 Subject: [PATCH 1008/1017] zonefs: Fix error message in zonefs_file_dio_append() commit 88b170088ad2c3e27086fe35769aa49f8a512564 upstream. Since the expected write location in a sequential file is always at the end of the file (append write), when an invalid write append location is detected in zonefs_file_dio_append(), print the invalid written location instead of the expected write location. Fixes: a608da3bd730 ("zonefs: Detect append writes at invalid locations") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Himanshu Madhani Signed-off-by: Greg Kroah-Hartman --- fs/zonefs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 66a089a62c39..b9522eee1257 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -789,7 +789,7 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from) if (bio->bi_iter.bi_sector != wpsector) { zonefs_warn(inode->i_sb, "Corrupted write pointer %llu for zone at %llu\n", - wpsector, zi->i_zsector); + bio->bi_iter.bi_sector, zi->i_zsector); ret = -EIO; } } From b9f7422dd94a6ec5572a3e895157ec1dad2952a7 Mon Sep 17 00:00:00 2001 From: Eduard Zingerman Date: Sat, 1 Oct 2022 13:44:25 +0300 Subject: [PATCH 1009/1017] selftests/bpf: Test btf dump for struct with padding only fields [ Upstream commit d503f1176b14f722a40ea5110312614982f9a80b ] Structures with zero regular fields but some padding constitute a special case in btf_dump.c:btf_dump_emit_struct_def with regards to newline before closing '}'. Signed-off-by: Eduard Zingerman Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20221001104425.415768-2-eddyz87@gmail.com Stable-dep-of: ea2ce1ba99aa ("libbpf: Fix BTF-to-C converter's padding logic") Signed-off-by: Sasha Levin --- .../selftests/bpf/progs/btf_dump_test_case_padding.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c index 35c512818a56..db5458da6182 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c @@ -102,12 +102,21 @@ struct zone { struct zone_padding __pad__; }; +/* ----- START-EXPECTED-OUTPUT ----- */ +struct padding_wo_named_members { + long: 64; + long: 64; +}; + +/* ------ END-EXPECTED-OUTPUT ------ */ + int f(struct { struct padded_implicitly _1; struct padded_explicitly _2; struct padded_a_lot _3; struct padded_cache_line _4; struct zone _5; + struct padding_wo_named_members _6; } *_) { return 0; From e5a16bcb131c969befc4ede5542a1c2bd3ecf11b Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Mon, 12 Dec 2022 13:15:04 -0800 Subject: [PATCH 1010/1017] libbpf: Fix BTF-to-C converter's padding logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ea2ce1ba99aa6a60c8d8a706e3abadf3de372163 ] Turns out that btf_dump API doesn't handle a bunch of tricky corner cases, as reported by Per, and further discovered using his testing Python script ([0]). This patch revamps btf_dump's padding logic significantly, making it more correct and also avoiding unnecessary explicit padding, where compiler would pad naturally. This overall topic turned out to be very tricky and subtle, there are lots of subtle corner cases. The comments in the code tries to give some clues, but comments themselves are supposed to be paired with good understanding of C alignment and padding rules. Plus some experimentation to figure out subtle things like whether `long :0;` means that struct is now forced to be long-aligned (no, it's not, turns out). Anyways, Per's script, while not completely correct in some known situations, doesn't show any obvious cases where this logic breaks, so this is a nice improvement over the previous state of this logic. Some selftests had to be adjusted to accommodate better use of natural alignment rules, eliminating some unnecessary padding, or changing it to `type: 0;` alignment markers. Note also that for when we are in between bitfields, we emit explicit bit size, while otherwise we use `: 0`, this feels much more natural in practice. Next patch will add few more test cases, found through randomized Per's script. [0] https://lore.kernel.org/bpf/85f83c333f5355c8ac026f835b18d15060725fcb.camel@ericsson.com/ Reported-by: Per Sundström XP Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20221212211505.558851-6-andrii@kernel.org Signed-off-by: Sasha Levin --- tools/lib/bpf/btf_dump.c | 167 +++++++++++++----- .../bpf/progs/btf_dump_test_case_bitfields.c | 2 +- .../bpf/progs/btf_dump_test_case_padding.c | 58 ++++-- 3 files changed, 163 insertions(+), 64 deletions(-) diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 0e2d63da24e9..4d27b08074a5 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -788,6 +788,25 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) } } +static int btf_natural_align_of(const struct btf *btf, __u32 id) +{ + const struct btf_type *t = btf__type_by_id(btf, id); + int i, align, vlen; + const struct btf_member *m; + + if (!btf_is_composite(t)) + return btf__align_of(btf, id); + + align = 1; + m = btf_members(t); + vlen = btf_vlen(t); + for (i = 0; i < vlen; i++, m++) { + align = max(align, btf__align_of(btf, m->type)); + } + + return align; +} + static bool btf_is_struct_packed(const struct btf *btf, __u32 id, const struct btf_type *t) { @@ -795,16 +814,16 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id, int align, i, bit_sz; __u16 vlen; - align = btf__align_of(btf, id); - /* size of a non-packed struct has to be a multiple of its alignment*/ - if (align && t->size % align) + align = btf_natural_align_of(btf, id); + /* size of a non-packed struct has to be a multiple of its alignment */ + if (align && (t->size % align) != 0) return true; m = btf_members(t); vlen = btf_vlen(t); /* all non-bitfield fields have to be naturally aligned */ for (i = 0; i < vlen; i++, m++) { - align = btf__align_of(btf, m->type); + align = btf_natural_align_of(btf, m->type); bit_sz = btf_member_bitfield_size(t, i); if (align && bit_sz == 0 && m->offset % (8 * align) != 0) return true; @@ -817,44 +836,97 @@ static bool btf_is_struct_packed(const struct btf *btf, __u32 id, return false; } -static int chip_away_bits(int total, int at_most) -{ - return total % at_most ? : at_most; -} - static void btf_dump_emit_bit_padding(const struct btf_dump *d, - int cur_off, int m_off, int m_bit_sz, - int align, int lvl) + int cur_off, int next_off, int next_align, + bool in_bitfield, int lvl) { - int off_diff = m_off - cur_off; - int ptr_bits = d->ptr_sz * 8; + const struct { + const char *name; + int bits; + } pads[] = { + {"long", d->ptr_sz * 8}, {"int", 32}, {"short", 16}, {"char", 8} + }; + int new_off, pad_bits, bits, i; + const char *pad_type; - if (off_diff <= 0) - /* no gap */ - return; - if (m_bit_sz == 0 && off_diff < align * 8) - /* natural padding will take care of a gap */ - return; + if (cur_off >= next_off) + return; /* no gap */ - while (off_diff > 0) { - const char *pad_type; - int pad_bits; + /* For filling out padding we want to take advantage of + * natural alignment rules to minimize unnecessary explicit + * padding. First, we find the largest type (among long, int, + * short, or char) that can be used to force naturally aligned + * boundary. Once determined, we'll use such type to fill in + * the remaining padding gap. In some cases we can rely on + * compiler filling some gaps, but sometimes we need to force + * alignment to close natural alignment with markers like + * `long: 0` (this is always the case for bitfields). Note + * that even if struct itself has, let's say 4-byte alignment + * (i.e., it only uses up to int-aligned types), using `long: + * X;` explicit padding doesn't actually change struct's + * overall alignment requirements, but compiler does take into + * account that type's (long, in this example) natural + * alignment requirements when adding implicit padding. We use + * this fact heavily and don't worry about ruining correct + * struct alignment requirement. + */ + for (i = 0; i < ARRAY_SIZE(pads); i++) { + pad_bits = pads[i].bits; + pad_type = pads[i].name; - if (ptr_bits > 32 && off_diff > 32) { - pad_type = "long"; - pad_bits = chip_away_bits(off_diff, ptr_bits); - } else if (off_diff > 16) { - pad_type = "int"; - pad_bits = chip_away_bits(off_diff, 32); - } else if (off_diff > 8) { - pad_type = "short"; - pad_bits = chip_away_bits(off_diff, 16); - } else { - pad_type = "char"; - pad_bits = chip_away_bits(off_diff, 8); + new_off = roundup(cur_off, pad_bits); + if (new_off <= next_off) + break; + } + + if (new_off > cur_off && new_off <= next_off) { + /* We need explicit `: 0` aligning mark if next + * field is right on alignment offset and its + * alignment requirement is less strict than 's + * alignment (so compiler won't naturally align to the + * offset we expect), or if subsequent `: X`, + * will actually completely fit in the remaining hole, + * making compiler basically ignore `: X` + * completely. + */ + if (in_bitfield || + (new_off == next_off && roundup(cur_off, next_align * 8) != new_off) || + (new_off != next_off && next_off - new_off <= new_off - cur_off)) + /* but for bitfields we'll emit explicit bit count */ + btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, + in_bitfield ? new_off - cur_off : 0); + cur_off = new_off; + } + + /* Now we know we start at naturally aligned offset for a chosen + * padding type (long, int, short, or char), and so the rest is just + * a straightforward filling of remaining padding gap with full + * `: sizeof();` markers, except for the last one, which + * might need smaller than sizeof() padding. + */ + while (cur_off != next_off) { + bits = min(next_off - cur_off, pad_bits); + if (bits == pad_bits) { + btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits); + cur_off += bits; + continue; + } + /* For the remainder padding that doesn't cover entire + * pad_type bit length, we pick the smallest necessary type. + * This is pure aesthetics, we could have just used `long`, + * but having smallest necessary one communicates better the + * scale of the padding gap. + */ + for (i = ARRAY_SIZE(pads) - 1; i >= 0; i--) { + pad_type = pads[i].name; + pad_bits = pads[i].bits; + if (pad_bits < bits) + continue; + + btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, bits); + cur_off += bits; + break; } - btf_dump_printf(d, "\n%s%s: %d;", pfx(lvl), pad_type, pad_bits); - off_diff -= pad_bits; } } @@ -873,9 +945,11 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, { const struct btf_member *m = btf_members(t); bool is_struct = btf_is_struct(t); - int align, i, packed, off = 0; + bool packed, prev_bitfield = false; + int align, i, off = 0; __u16 vlen = btf_vlen(t); + align = btf__align_of(d->btf, id); packed = is_struct ? btf_is_struct_packed(d->btf, id, t) : 0; btf_dump_printf(d, "%s%s%s {", @@ -885,33 +959,36 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, for (i = 0; i < vlen; i++, m++) { const char *fname; - int m_off, m_sz; + int m_off, m_sz, m_align; + bool in_bitfield; fname = btf_name_of(d, m->name_off); m_sz = btf_member_bitfield_size(t, i); m_off = btf_member_bit_offset(t, i); - align = packed ? 1 : btf__align_of(d->btf, m->type); + m_align = packed ? 1 : btf__align_of(d->btf, m->type); - btf_dump_emit_bit_padding(d, off, m_off, m_sz, align, lvl + 1); + in_bitfield = prev_bitfield && m_sz != 0; + + btf_dump_emit_bit_padding(d, off, m_off, m_align, in_bitfield, lvl + 1); btf_dump_printf(d, "\n%s", pfx(lvl + 1)); btf_dump_emit_type_decl(d, m->type, fname, lvl + 1); if (m_sz) { btf_dump_printf(d, ": %d", m_sz); off = m_off + m_sz; + prev_bitfield = true; } else { m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type)); off = m_off + m_sz * 8; + prev_bitfield = false; } + btf_dump_printf(d, ";"); } /* pad at the end, if necessary */ - if (is_struct) { - align = packed ? 1 : btf__align_of(d->btf, id); - btf_dump_emit_bit_padding(d, off, t->size * 8, 0, align, - lvl + 1); - } + if (is_struct) + btf_dump_emit_bit_padding(d, off, t->size * 8, align, false, lvl + 1); if (vlen) btf_dump_printf(d, "\n"); diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c index 8f44767a75fa..22a7cd8fd9ac 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_bitfields.c @@ -53,7 +53,7 @@ struct bitfields_only_mixed_types { */ /* ------ END-EXPECTED-OUTPUT ------ */ struct bitfield_mixed_with_others { - long: 4; /* char is enough as a backing field */ + char: 4; /* char is enough as a backing field */ int a: 4; /* 8-bit implicit padding */ short b; /* combined with previous bitfield */ diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c index db5458da6182..28833f2694e9 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c @@ -19,7 +19,7 @@ struct padded_implicitly { /* *struct padded_explicitly { * int a; - * int: 32; + * long: 0; * int b; *}; * @@ -28,41 +28,28 @@ struct padded_implicitly { struct padded_explicitly { int a; - int: 1; /* algo will explicitly pad with full 32 bits here */ + int: 1; /* algo will emit aligning `long: 0;` here */ int b; }; /* ----- START-EXPECTED-OUTPUT ----- */ -/* - *struct padded_a_lot { - * int a; - * long: 32; - * long: 64; - * long: 64; - * int b; - *}; - * - */ -/* ------ END-EXPECTED-OUTPUT ------ */ - struct padded_a_lot { int a; - /* 32 bit of implicit padding here, which algo will make explicit */ long: 64; long: 64; int b; }; +/* ------ END-EXPECTED-OUTPUT ------ */ + /* ----- START-EXPECTED-OUTPUT ----- */ /* *struct padded_cache_line { * int a; - * long: 32; * long: 64; * long: 64; * long: 64; * int b; - * long: 32; * long: 64; * long: 64; * long: 64; @@ -85,7 +72,7 @@ struct padded_cache_line { *struct zone { * int a; * short b; - * short: 16; + * long: 0; * struct zone_padding __pad__; *}; * @@ -108,6 +95,39 @@ struct padding_wo_named_members { long: 64; }; +struct padding_weird_1 { + int a; + long: 64; + short: 16; + short b; +}; + +/* ------ END-EXPECTED-OUTPUT ------ */ + +/* ----- START-EXPECTED-OUTPUT ----- */ +/* + *struct padding_weird_2 { + * long: 56; + * char a; + * long: 56; + * char b; + * char: 8; + *}; + * + */ +/* ------ END-EXPECTED-OUTPUT ------ */ +struct padding_weird_2 { + int: 32; /* these paddings will be collapsed into `long: 56;` */ + short: 16; + char: 8; + char a; + int: 32; /* these paddings will be collapsed into `long: 56;` */ + short: 16; + char: 8; + char b; + char: 8; +}; + /* ------ END-EXPECTED-OUTPUT ------ */ int f(struct { @@ -117,6 +137,8 @@ int f(struct { struct padded_cache_line _4; struct zone _5; struct padding_wo_named_members _6; + struct padding_weird_1 _7; + struct padding_weird_2 _8; } *_) { return 0; From 7ad30ad8c684362364e629574ab02eec3b9bb1bc Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Mon, 12 Dec 2022 13:15:05 -0800 Subject: [PATCH 1011/1017] selftests/bpf: Add few corner cases to test padding handling of btf_dump [ Upstream commit b148c8b9b926e257a59c8eb2cd6fa3adfd443254 ] Add few hand-crafted cases and few randomized cases found using script from [0] that tests btf_dump's padding logic. [0] https://lore.kernel.org/bpf/85f83c333f5355c8ac026f835b18d15060725fcb.camel@ericsson.com/ Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20221212211505.558851-7-andrii@kernel.org Stable-dep-of: 4fb877aaa179 ("libbpf: Fix btf_dump's packed struct determination") Signed-off-by: Sasha Levin --- .../bpf/progs/btf_dump_test_case_packing.c | 61 +++++++++- .../bpf/progs/btf_dump_test_case_padding.c | 104 ++++++++++++++++++ 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c index 1cef3bec1dc7..3f7755247591 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c @@ -58,7 +58,64 @@ union jump_code_union { } __attribute__((packed)); }; -/*------ END-EXPECTED-OUTPUT ------ */ +/* ----- START-EXPECTED-OUTPUT ----- */ +/* + *struct nested_packed_but_aligned_struct { + * int x1; + * int x2; + *}; + * + *struct outer_implicitly_packed_struct { + * char y1; + * struct nested_packed_but_aligned_struct y2; + *} __attribute__((packed)); + * + */ +/* ------ END-EXPECTED-OUTPUT ------ */ + +struct nested_packed_but_aligned_struct { + int x1; + int x2; +} __attribute__((packed)); + +struct outer_implicitly_packed_struct { + char y1; + struct nested_packed_but_aligned_struct y2; +}; +/* ----- START-EXPECTED-OUTPUT ----- */ +/* + *struct usb_ss_ep_comp_descriptor { + * char: 8; + * char bDescriptorType; + * char bMaxBurst; + * short wBytesPerInterval; + *}; + * + *struct usb_host_endpoint { + * long: 64; + * char: 8; + * struct usb_ss_ep_comp_descriptor ss_ep_comp; + * long: 0; + *} __attribute__((packed)); + * + */ +/* ------ END-EXPECTED-OUTPUT ------ */ + +struct usb_ss_ep_comp_descriptor { + char: 8; + char bDescriptorType; + char bMaxBurst; + int: 0; + short wBytesPerInterval; +} __attribute__((packed)); + +struct usb_host_endpoint { + long: 64; + char: 8; + struct usb_ss_ep_comp_descriptor ss_ep_comp; + long: 0; +}; + int f(struct { struct packed_trailing_space _1; @@ -69,6 +126,8 @@ int f(struct { union union_is_never_packed _6; union union_does_not_need_packing _7; union jump_code_union _8; + struct outer_implicitly_packed_struct _9; + struct usb_host_endpoint _10; } *_) { return 0; diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c index 28833f2694e9..0b3cdffbfcf7 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_padding.c @@ -128,6 +128,98 @@ struct padding_weird_2 { char: 8; }; +/* ----- START-EXPECTED-OUTPUT ----- */ +struct exact_1byte { + char x; +}; + +struct padded_1byte { + char: 8; +}; + +struct exact_2bytes { + short x; +}; + +struct padded_2bytes { + short: 16; +}; + +struct exact_4bytes { + int x; +}; + +struct padded_4bytes { + int: 32; +}; + +struct exact_8bytes { + long x; +}; + +struct padded_8bytes { + long: 64; +}; + +struct ff_periodic_effect { + int: 32; + short magnitude; + long: 0; + short phase; + long: 0; + int: 32; + int custom_len; + short *custom_data; +}; + +struct ib_wc { + long: 64; + long: 64; + int: 32; + int byte_len; + void *qp; + union {} ex; + long: 64; + int slid; + int wc_flags; + long: 64; + char smac[6]; + long: 0; + char network_hdr_type; +}; + +struct acpi_object_method { + long: 64; + char: 8; + char type; + short reference_count; + char flags; + short: 0; + char: 8; + char sync_level; + long: 64; + void *node; + void *aml_start; + union {} dispatch; + long: 64; + int aml_length; +}; + +struct nested_unpacked { + int x; +}; + +struct nested_packed { + struct nested_unpacked a; + char c; +} __attribute__((packed)); + +struct outer_mixed_but_unpacked { + struct nested_packed b1; + short a1; + struct nested_packed b2; +}; + /* ------ END-EXPECTED-OUTPUT ------ */ int f(struct { @@ -139,6 +231,18 @@ int f(struct { struct padding_wo_named_members _6; struct padding_weird_1 _7; struct padding_weird_2 _8; + struct exact_1byte _100; + struct padded_1byte _101; + struct exact_2bytes _102; + struct padded_2bytes _103; + struct exact_4bytes _104; + struct padded_4bytes _105; + struct exact_8bytes _106; + struct padded_8bytes _107; + struct ff_periodic_effect _200; + struct ib_wc _201; + struct acpi_object_method _202; + struct outer_mixed_but_unpacked _203; } *_) { return 0; From b4781477f397a9e10f36d035ffc76bfb67aa1639 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Thu, 15 Dec 2022 10:36:05 -0800 Subject: [PATCH 1012/1017] libbpf: Fix btf_dump's packed struct determination [ Upstream commit 4fb877aaa179dcdb1676d55216482febaada457e ] Fix bug in btf_dump's logic of determining if a given struct type is packed or not. The notion of "natural alignment" is not needed and is even harmful in this case, so drop it altogether. The biggest difference in btf_is_struct_packed() compared to its original implementation is that we don't really use btf__align_of() to determine overall alignment of a struct type (because it could be 1 for both packed and non-packed struct, depending on specifci field definitions), and just use field's actual alignment to calculate whether any field is requiring packing or struct's size overall necessitates packing. Add two simple test cases that demonstrate the difference this change would make. Fixes: ea2ce1ba99aa ("libbpf: Fix BTF-to-C converter's padding logic") Reported-by: Eduard Zingerman Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Acked-by: Eduard Zingerman Link: https://lore.kernel.org/bpf/20221215183605.4149488-1-andrii@kernel.org Signed-off-by: Sasha Levin --- tools/lib/bpf/btf_dump.c | 33 ++++--------------- .../bpf/progs/btf_dump_test_case_packing.c | 19 +++++++++++ 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 4d27b08074a5..558d34fbd331 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -788,47 +788,26 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id) } } -static int btf_natural_align_of(const struct btf *btf, __u32 id) -{ - const struct btf_type *t = btf__type_by_id(btf, id); - int i, align, vlen; - const struct btf_member *m; - - if (!btf_is_composite(t)) - return btf__align_of(btf, id); - - align = 1; - m = btf_members(t); - vlen = btf_vlen(t); - for (i = 0; i < vlen; i++, m++) { - align = max(align, btf__align_of(btf, m->type)); - } - - return align; -} - static bool btf_is_struct_packed(const struct btf *btf, __u32 id, const struct btf_type *t) { const struct btf_member *m; - int align, i, bit_sz; + int max_align = 1, align, i, bit_sz; __u16 vlen; - align = btf_natural_align_of(btf, id); - /* size of a non-packed struct has to be a multiple of its alignment */ - if (align && (t->size % align) != 0) - return true; - m = btf_members(t); vlen = btf_vlen(t); /* all non-bitfield fields have to be naturally aligned */ for (i = 0; i < vlen; i++, m++) { - align = btf_natural_align_of(btf, m->type); + align = btf__align_of(btf, m->type); bit_sz = btf_member_bitfield_size(t, i); if (align && bit_sz == 0 && m->offset % (8 * align) != 0) return true; + max_align = max(align, max_align); } - + /* size of a non-packed struct has to be a multiple of its alignment */ + if (t->size % max_align != 0) + return true; /* * if original struct was marked as packed, but its layout is * naturally aligned, we'll detect that it's not packed diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c index 3f7755247591..22dbd1213434 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_packing.c @@ -116,6 +116,23 @@ struct usb_host_endpoint { long: 0; }; +/* ----- START-EXPECTED-OUTPUT ----- */ +struct nested_packed_struct { + int a; + char b; +} __attribute__((packed)); + +struct outer_nonpacked_struct { + short a; + struct nested_packed_struct b; +}; + +struct outer_packed_struct { + short a; + struct nested_packed_struct b; +} __attribute__((packed)); + +/* ------ END-EXPECTED-OUTPUT ------ */ int f(struct { struct packed_trailing_space _1; @@ -128,6 +145,8 @@ int f(struct { union jump_code_union _8; struct outer_implicitly_packed_struct _9; struct usb_host_endpoint _10; + struct outer_nonpacked_struct _11; + struct outer_packed_struct _12; } *_) { return 0; From 3392d67af0a4bf13e7f6ef0cddfc622bc2e8c95e Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Tue, 6 Dec 2022 22:41:34 +0800 Subject: [PATCH 1013/1017] ext4: fix kernel BUG in 'ext4_write_inline_data_end()' commit 5c099c4fdc438014d5893629e70a8ba934433ee8 upstream. Syzbot report follow issue: ------------[ cut here ]------------ kernel BUG at fs/ext4/inline.c:227! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 1 PID: 3629 Comm: syz-executor212 Not tainted 6.1.0-rc5-syzkaller-00018-g59d0d52c30d4 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:ext4_write_inline_data+0x344/0x3e0 fs/ext4/inline.c:227 RSP: 0018:ffffc90003b3f368 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff8880704e16c0 RCX: 0000000000000000 RDX: ffff888021763a80 RSI: ffffffff821e31a4 RDI: 0000000000000006 RBP: 000000000006818e R08: 0000000000000006 R09: 0000000000068199 R10: 0000000000000079 R11: 0000000000000000 R12: 000000000000000b R13: 0000000000068199 R14: ffffc90003b3f408 R15: ffff8880704e1c82 FS: 000055555723e3c0(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fffe8ac9080 CR3: 0000000079f81000 CR4: 0000000000350ee0 Call Trace: ext4_write_inline_data_end+0x2a3/0x12f0 fs/ext4/inline.c:768 ext4_write_end+0x242/0xdd0 fs/ext4/inode.c:1313 ext4_da_write_end+0x3ed/0xa30 fs/ext4/inode.c:3063 generic_perform_write+0x316/0x570 mm/filemap.c:3764 ext4_buffered_write_iter+0x15b/0x460 fs/ext4/file.c:285 ext4_file_write_iter+0x8bc/0x16e0 fs/ext4/file.c:700 call_write_iter include/linux/fs.h:2191 [inline] do_iter_readv_writev+0x20b/0x3b0 fs/read_write.c:735 do_iter_write+0x182/0x700 fs/read_write.c:861 vfs_iter_write+0x74/0xa0 fs/read_write.c:902 iter_file_splice_write+0x745/0xc90 fs/splice.c:686 do_splice_from fs/splice.c:764 [inline] direct_splice_actor+0x114/0x180 fs/splice.c:931 splice_direct_to_actor+0x335/0x8a0 fs/splice.c:886 do_splice_direct+0x1ab/0x280 fs/splice.c:974 do_sendfile+0xb19/0x1270 fs/read_write.c:1255 __do_sys_sendfile64 fs/read_write.c:1323 [inline] __se_sys_sendfile64 fs/read_write.c:1309 [inline] __x64_sys_sendfile64+0x1d0/0x210 fs/read_write.c:1309 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd ---[ end trace 0000000000000000 ]--- Above issue may happens as follows: ext4_da_write_begin ext4_da_write_inline_data_begin ext4_da_convert_inline_data_to_extent ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); ext4_da_write_end ext4_run_li_request ext4_mb_prefetch ext4_read_block_bitmap_nowait ext4_validate_block_bitmap ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT) percpu_counter_sub(&sbi->s_freeclusters_counter,grp->bb_free); -> sbi->s_freeclusters_counter become zero ext4_da_write_begin if (ext4_nonda_switch(inode->i_sb)) -> As freeclusters_counter is zero will return true *fsdata = (void *)FALL_BACK_TO_NONDELALLOC; ext4_write_begin ext4_da_write_end if (write_mode == FALL_BACK_TO_NONDELALLOC) ext4_write_end if (inline_data) ext4_write_inline_data_end ext4_write_inline_data BUG_ON(pos + len > EXT4_I(inode)->i_inline_size); -> As inode is already convert to extent, so 'pos + len' > inline_size -> then trigger BUG. To solve this issue, instead of checking ext4_has_inline_data() which is only cleared after data has been written back, check the EXT4_STATE_MAY_INLINE_DATA flag in ext4_write_end(). Fixes: f19d5870cbf7 ("ext4: add normal write support for inline data") Reported-by: syzbot+4faa160fa96bfba639f8@syzkaller.appspotmail.com Reported-by: Jun Nie Signed-off-by: Ye Bin Link: https://lore.kernel.org/r/20221206144134.1919987-1-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o Cc: stable@kernel.org [ta: Fix conflict in if expression and use the local variable inline_data as it is initialized with ext4_has_inline_data(inode) anyway.] Signed-off-by: Tudor Ambarus Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6ba185b46ba3..9bd5f8b0511b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1303,7 +1303,8 @@ static int ext4_write_end(struct file *file, bool verity = ext4_verity_in_progress(inode); trace_ext4_write_end(inode, pos, len, copied); - if (inline_data) { + if (inline_data && + ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { ret = ext4_write_inline_data_end(inode, pos, len, copied, page); if (ret < 0) { From 7c414f6f06e9a3934901b6edc3177ae5a1e07094 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Sun, 4 Dec 2022 17:00:04 +0100 Subject: [PATCH 1014/1017] gfs2: Always check inode size of inline inodes commit 70376c7ff31221f1d21db5611d8209e677781d3a upstream. Check if the inode size of stuffed (inline) inodes is within the allowed range when reading inodes from disk (gfs2_dinode_in()). This prevents us from on-disk corruption. The two checks in stuffed_readpage() and gfs2_unstuffer_page() that just truncate inline data to the maximum allowed size don't actually make sense, and they can be removed now as well. Reported-by: syzbot+7bb81dfa9cda07d9cd9d@syzkaller.appspotmail.com Signed-off-by: Andreas Gruenbacher [pchelkin@ispras.ru: adjust the inode variable inside gfs2_dinode_in with the format used before upstream commit 7db354444ad8 ("gfs2: Cosmetic gfs2_dinode_{in,out} cleanup")] Signed-off-by: Fedor Pchelkin Signed-off-by: Greg Kroah-Hartman --- fs/gfs2/aops.c | 2 -- fs/gfs2/bmap.c | 3 --- fs/gfs2/glops.c | 3 +++ 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 530659554870..a0430da033b3 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -451,8 +451,6 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) return error; kaddr = kmap_atomic(page); - if (dsize > gfs2_max_stuffed_size(ip)) - dsize = gfs2_max_stuffed_size(ip); memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize); memset(kaddr + dsize, 0, PAGE_SIZE - dsize); kunmap_atomic(kaddr); diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index b4fde3a8eeb4..eaee95d2ad14 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -69,9 +69,6 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, void *kaddr = kmap(page); u64 dsize = i_size_read(inode); - if (dsize > gfs2_max_stuffed_size(ip)) - dsize = gfs2_max_stuffed_size(ip); - memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize); memset(kaddr + dsize, 0, PAGE_SIZE - dsize); kunmap(page); diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index bf539eab92c6..db28c240dae3 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -454,6 +454,9 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) ip->i_depth = (u8)depth; ip->i_entries = be32_to_cpu(str->di_entries); + if (gfs2_is_stuffed(ip) && ip->i_inode.i_size > gfs2_max_stuffed_size(ip)) + goto corrupt; + if (S_ISREG(ip->i_inode.i_mode)) gfs2_set_aops(&ip->i_inode); From 34a02011c5d1b9de0085e6e004f20abf0a9cbf42 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Wed, 15 Mar 2023 21:25:17 +0100 Subject: [PATCH 1015/1017] hsr: ratelimit only when errors are printed commit 1b0120e4db0bf2838d1ce741195ce4b7cc100b91 upstream. Recently, when automatically merging -net and net-next in MPTCP devel tree, our CI reported [1] a conflict in hsr, the same as the one reported by Stephen in netdev [2]. When looking at the conflict, I noticed it is in fact the v1 [3] that has been applied in -net and the v2 [4] in net-next. Maybe the v1 was applied by accident. As mentioned by Jakub Kicinski [5], the new condition makes more sense before the net_ratelimit(), not to update net_ratelimit's state which is unnecessary if we're not going to print either way. Here, this modification applies the v2 but in -net. Link: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/4423171069 [1] Link: https://lore.kernel.org/netdev/20230315100914.53fc1760@canb.auug.org.au/ [2] Link: https://lore.kernel.org/netdev/20230307133229.127442-1-koverskeid@gmail.com/ [3] Link: https://lore.kernel.org/netdev/20230309092302.179586-1-koverskeid@gmail.com/ [4] Link: https://lore.kernel.org/netdev/20230308232001.2fb62013@kernel.org/ [5] Fixes: 28e8cabe80f3 ("net: hsr: Don't log netdev_err message on unknown prp dst node") Signed-off-by: Matthieu Baerts Reviewed-by: Steen Hegelund Link: https://lore.kernel.org/r/20230315-net-20230315-hsr_framereg-ratelimit-v1-1-61d2ef176d11@tessares.net Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/hsr/hsr_framereg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 08627c836884..afc97d65cf2d 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -380,7 +380,7 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb, node_dst = find_node_by_addr_A(&port->hsr->node_db, eth_hdr(skb)->h_dest); if (!node_dst) { - if (net_ratelimit() && port->hsr->prot_version != PRP_V1) + if (port->hsr->prot_version != PRP_V1 && net_ratelimit()) netdev_err(skb->dev, "%s: Unknown node\n", __func__); return; } From 387078f9030cf336cd9fef521540db75b61615e0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 Apr 2023 11:23:52 +0200 Subject: [PATCH 1016/1017] Linux 5.10.177 Link: https://lore.kernel.org/r/20230403140414.174516815@linuxfoundation.org Tested-by: Shuah Khan Tested-by: Florian Fainelli Tested-by: Linux Kernel Functional Testing Tested-by: Jon Hunter Tested-by: Chris Paterson (CIP) Tested-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 71caf5938361..ae202cc53158 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 176 +SUBLEVEL = 177 EXTRAVERSION = NAME = Dare mighty things From 0334ff98b9dd42b4dd73644f11c50f72871ac8c4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Apr 2023 11:36:33 +0000 Subject: [PATCH 1017/1017] Revert "net: mdio: fix owner field for mdio buses registered using device-tree" This reverts commit d04dac7fae7580dce0cd9b55db6e1ad4e8d26157. It removes of_mdiobus_register() from the symbol list, which Android drivers are using, and they don't care about module owners as kernel modules are not allowed to be removed on Android systems, so revert it to preserve the ABI. Bug: 161946584 Change-Id: I5bb5d4261bab07c3a4eeb7a41ae09d4a41d56e7e Signed-off-by: Greg Kroah-Hartman --- drivers/net/mdio/of_mdio.c | 12 +++++------- drivers/net/phy/mdio_devres.c | 11 +++++------ include/linux/of_mdio.h | 22 +++------------------- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index b254127cea50..5bae47f3da40 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -238,23 +238,21 @@ bool of_mdiobus_child_is_phy(struct device_node *child) EXPORT_SYMBOL(of_mdiobus_child_is_phy); /** - * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree + * of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure * @np: pointer to device_node of MDIO bus. - * @owner: module owning the @mdio object. * * This function registers the mii_bus structure and registers a phy_device * for each child node of @np. */ -int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, - struct module *owner) +int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) { struct device_node *child; bool scanphys = false; int addr, rc; if (!np) - return __mdiobus_register(mdio, owner); + return mdiobus_register(mdio); /* Do not continue if the node is disabled */ if (!of_device_is_available(np)) @@ -274,7 +272,7 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us); /* Register the MDIO bus */ - rc = __mdiobus_register(mdio, owner); + rc = mdiobus_register(mdio); if (rc) return rc; @@ -338,7 +336,7 @@ unregister: mdiobus_unregister(mdio); return rc; } -EXPORT_SYMBOL(__of_mdiobus_register); +EXPORT_SYMBOL(of_mdiobus_register); /** * of_mdio_find_device - Given a device tree node, find the mdio_device diff --git a/drivers/net/phy/mdio_devres.c b/drivers/net/phy/mdio_devres.c index 69b829e6ab35..b560e99695df 100644 --- a/drivers/net/phy/mdio_devres.c +++ b/drivers/net/phy/mdio_devres.c @@ -98,14 +98,13 @@ EXPORT_SYMBOL(__devm_mdiobus_register); #if IS_ENABLED(CONFIG_OF_MDIO) /** - * __devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register() + * devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register() * @dev: Device to register mii_bus for * @mdio: MII bus structure to register * @np: Device node to parse - * @owner: Owning module */ -int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, - struct device_node *np, struct module *owner) +int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, + struct device_node *np) { struct mdiobus_devres *dr; int ret; @@ -118,7 +117,7 @@ int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, if (!dr) return -ENOMEM; - ret = __of_mdiobus_register(mdio, np, owner); + ret = of_mdiobus_register(mdio, np); if (ret) { devres_free(dr); return ret; @@ -128,7 +127,7 @@ int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, devres_add(dev, dr); return 0; } -EXPORT_SYMBOL(__devm_of_mdiobus_register); +EXPORT_SYMBOL(devm_of_mdiobus_register); #endif /* CONFIG_OF_MDIO */ MODULE_LICENSE("GPL"); diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index 8cc6522ee43a..f56c6a9230ac 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h @@ -14,25 +14,9 @@ #if IS_ENABLED(CONFIG_OF_MDIO) bool of_mdiobus_child_is_phy(struct device_node *child); -int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, - struct module *owner); - -static inline int of_mdiobus_register(struct mii_bus *mdio, - struct device_node *np) -{ - return __of_mdiobus_register(mdio, np, THIS_MODULE); -} - -int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, - struct device_node *np, struct module *owner); - -static inline int devm_of_mdiobus_register(struct device *dev, - struct mii_bus *mdio, - struct device_node *np) -{ - return __devm_of_mdiobus_register(dev, mdio, np, THIS_MODULE); -} - +int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np); +int devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio, + struct device_node *np); struct mdio_device *of_mdio_find_device(struct device_node *np); struct phy_device *of_phy_find_device(struct device_node *phy_np); struct phy_device *