From 5ca155aa79e9b5ac14cecd0d062f1edc9fde3fbe Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 15 Oct 2022 07:18:38 -0400 Subject: [PATCH 001/610] Revert "fs: check FMODE_LSEEK to control internal pipe splicing" This reverts commit fd0a6e99b61e6c08fa5cf585d54fd956f70c73a6. Which was upstream commit 97ef77c52b789ec1411d360ed99dca1efe4b2c81. The commit is missing dependencies and breaks NFS tests, remove it for now. Reported-by: Saeed Mirzamohammadi Signed-off-by: Sasha Levin --- fs/splice.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index 3abcd7fbc9f2..5dbce4dcc1a7 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -814,15 +814,17 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, { struct pipe_inode_info *pipe; long ret, bytes; + umode_t i_mode; size_t len; int i, flags, more; /* - * We require the input to be seekable, as we don't want to randomly - * drop data for eg socket -> socket splicing. Use the piped splicing - * for that! + * We require the input being a regular file, as we don't want to + * randomly drop data for eg socket -> socket splicing. Use the + * piped splicing for that! */ - if (unlikely(!(in->f_mode & FMODE_LSEEK))) + i_mode = file_inode(in)->i_mode; + if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode))) return -EINVAL; /* From 45899fae65e53445d6ca3213ff6c59681fe45174 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Oct 2022 09:01:47 +0200 Subject: [PATCH 002/610] ALSA: oss: Fix potential deadlock at unregistration commit 97d917879d7f92df09c3f21fd54609a8bcd654b2 upstream. We took sound_oss_mutex around the calls of unregister_sound_special() at unregistering OSS devices. This may, however, lead to a deadlock, because we manage the card release via the card's device object, and the release may happen at unregister_sound_special() call -- which will take sound_oss_mutex again in turn. Although the deadlock might be fixed by relaxing the rawmidi mutex in the previous commit, it's safer to move unregister_sound_special() calls themselves out of the sound_oss_mutex, too. The call is race-safe as the function has a spinlock protection by itself. Link: https://lore.kernel.org/r/CAB7eexJP7w1B0mVgDF0dQ+gWor7UdkiwPczmL7pn91xx8xpzOA@mail.gmail.com Cc: Link: https://lore.kernel.org/r/20221011070147.7611-2-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/sound_oss.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index 7ed0a2a91035..2751bf2ff61b 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -162,7 +162,6 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) mutex_unlock(&sound_oss_mutex); return -ENOENT; } - unregister_sound_special(minor); switch (SNDRV_MINOR_OSS_DEVICE(minor)) { case SNDRV_MINOR_OSS_PCM: track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO); @@ -174,12 +173,18 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); break; } - if (track2 >= 0) { - unregister_sound_special(track2); + if (track2 >= 0) snd_oss_minors[track2] = NULL; - } snd_oss_minors[minor] = NULL; mutex_unlock(&sound_oss_mutex); + + /* call unregister_sound_special() outside sound_oss_mutex; + * otherwise may deadlock, as it can trigger the release of a card + */ + unregister_sound_special(minor); + if (track2 >= 0) + unregister_sound_special(track2); + kfree(mptr); return 0; } From 550ca3082ebd93e5b61719a1e22528ee27775c5e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Oct 2022 09:01:46 +0200 Subject: [PATCH 003/610] ALSA: rawmidi: Drop register_mutex in snd_rawmidi_free() commit a70aef7982b012e86dfd39fbb235e76a21ae778a upstream. The register_mutex taken around the dev_unregister callback call in snd_rawmidi_free() may potentially lead to a mutex deadlock, when OSS emulation and a hot unplug are involved. Since the mutex doesn't protect the actual race (as the registration itself is already protected by another means), let's drop it. Link: https://lore.kernel.org/r/CAB7eexJP7w1B0mVgDF0dQ+gWor7UdkiwPczmL7pn91xx8xpzOA@mail.gmail.com Cc: Link: https://lore.kernel.org/r/20221011070147.7611-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/rawmidi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index befa9809ff00..b1632ab432cf 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1835,10 +1835,8 @@ static int snd_rawmidi_free(struct snd_rawmidi *rmidi) snd_info_free_entry(rmidi->proc_entry); rmidi->proc_entry = NULL; - mutex_lock(®ister_mutex); if (rmidi->ops && rmidi->ops->dev_unregister) rmidi->ops->dev_unregister(rmidi); - mutex_unlock(®ister_mutex); snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); From 0672215994e2347a9b4f145e2bc1709b1e01cee3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 Sep 2022 12:01:51 +0200 Subject: [PATCH 004/610] ALSA: usb-audio: Fix potential memory leaks commit 6382da0828995af87aa8b8bef28cc61aceb4aff3 upstream. When the driver hits -ENOMEM at allocating a URB or a buffer, it aborts and goes to the error path that releases the all previously allocated resources. However, when -ENOMEM hits at the middle of the sync EP URB allocation loop, the partially allocated URBs might be left without released, because ep->nurbs is still zero at that point. Fix it by setting ep->nurbs at first, so that the error handler loops over the full URB list. Cc: Link: https://lore.kernel.org/r/20220930100151.19461-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/endpoint.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 743b8287cfcd..4196c3eec7bb 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -1223,6 +1223,7 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep) if (!ep->syncbuf) return -ENOMEM; + ep->nurbs = SYNC_URBS; for (i = 0; i < SYNC_URBS; i++) { struct snd_urb_ctx *u = &ep->urb[i]; u->index = i; @@ -1242,8 +1243,6 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep) u->urb->complete = snd_complete_urb; } - ep->nurbs = SYNC_URBS; - return 0; out_of_memory: From ec439b97d98376afbe2836b449ae8d1515dfe34e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 Sep 2022 12:01:29 +0200 Subject: [PATCH 005/610] ALSA: usb-audio: Fix NULL dererence at error path commit 568be8aaf8a535f79c4db76cabe17b035aa2584d upstream. At an error path to release URB buffers and contexts, the driver might hit a NULL dererence for u->urb pointer, when u->buffer_size has been already set but the actual URB allocation failed. Fix it by adding the NULL check of urb. Also, make sure that buffer_size is cleared after the error path or the close. Cc: Reported-by: Sabri N. Ferreiro Link: https://lore.kernel.org/r/CAKG+3NRjTey+fFfUEGwuxL-pi_=T4cUskYG9OzpzHytF+tzYng@mail.gmail.com Link: https://lore.kernel.org/r/20220930100129.19445-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/endpoint.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 4196c3eec7bb..3bbc227769d0 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -85,12 +85,13 @@ static inline unsigned get_usb_high_speed_rate(unsigned int rate) */ static void release_urb_ctx(struct snd_urb_ctx *u) { - if (u->buffer_size) + if (u->urb && u->buffer_size) usb_free_coherent(u->ep->chip->dev, u->buffer_size, u->urb->transfer_buffer, u->urb->transfer_dma); usb_free_urb(u->urb); u->urb = NULL; + u->buffer_size = 0; } static const char *usb_error_string(int err) From 0d50e05ecc2c4bb134c2b3f03ae3e5749e78ea18 Mon Sep 17 00:00:00 2001 From: Callum Osmotherly Date: Wed, 5 Oct 2022 17:44:16 +1030 Subject: [PATCH 006/610] ALSA: hda/realtek: remove ALC289_FIXUP_DUAL_SPK for Dell 5530 commit 417b9c51f59734d852e47252476fadc293ad994a upstream. After some feedback from users with Dell Precision 5530 machines, this patch reverts the previous change to add ALC289_FIXUP_DUAL_SPK. While it improved the speaker output quality, it caused the headphone jack to have an audible "pop" sound when power saving was toggled. Fixes: 1885ff13d4c4 ("ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop") Signed-off-by: Callum Osmotherly Cc: Link: https://lore.kernel.org/r/Yz0uyN1zwZhnyRD6@piranha Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f7b6a516439d..bbc06234c749 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8847,7 +8847,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), - SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), From c01f385c70dbf2d8cbad7639f272242d0f9d2210 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Mon, 10 Oct 2022 19:57:02 +1300 Subject: [PATCH 007/610] ALSA: hda/realtek: Correct pin configs for ASUS G533Z commit 66ba7c88507344dee68ad1acbdb630473ab36114 upstream. The initial fix for ASUS G533Z was based on faulty information. This fixes the pincfg to values that have been verified with no existing module options or other hacks enabled. Enables headphone jack, and 5.1 surround. [ corrected the indent level by tiwai ] Fixes: bc2c23549ccd ("ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack") Signed-off-by: Luke D. Jones Cc: Link: https://lore.kernel.org/r/20221010065702.35190-1-luke@ljones.dev Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bbc06234c749..c8965c2aaea1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8221,11 +8221,13 @@ static const struct hda_fixup alc269_fixups[] = { [ALC285_FIXUP_ASUS_G533Z_PINS] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { - { 0x14, 0x90170120 }, + { 0x14, 0x90170152 }, /* Speaker Surround Playback Switch */ + { 0x19, 0x03a19020 }, /* Mic Boost Volume */ + { 0x1a, 0x03a11c30 }, /* Mic Boost Volume */ + { 0x1e, 0x90170151 }, /* Rear jack, IN OUT EAPD Detect */ + { 0x21, 0x03211420 }, { } }, - .chained = true, - .chain_id = ALC294_FIXUP_ASUS_G513_PINS, }, [ALC294_FIXUP_ASUS_COEF_1B] = { .type = HDA_FIXUP_VERBS, From 41e83faf036cb244b5ebe1a0e1d277336e0a6895 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Mon, 10 Oct 2022 20:03:47 +1300 Subject: [PATCH 008/610] ALSA: hda/realtek: Add quirk for ASUS GV601R laptop commit 2ea8e1297801f7b0220ebf6ae61a5b74ca83981e upstream. The ASUS ROG X16 (GV601R) series laptop has the same node-to-DAC pairs as early models and the G14, this includes bass speakers which are by default mapped incorrectly to the 0x06 node. Add a quirk to use the same DAC pairs as the G14. Signed-off-by: Luke D. Jones Cc: Link: https://lore.kernel.org/r/20221010070347.36883-1-luke@ljones.dev 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 c8965c2aaea1..b57146e20074 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9047,6 +9047,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), + SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), From 3e4d2375d1542bc772b09ea97e24559bd4977695 Mon Sep 17 00:00:00 2001 From: Saranya Gopal Date: Tue, 11 Oct 2022 10:19:16 +0530 Subject: [PATCH 009/610] ALSA: hda/realtek: Add Intel Reference SSID to support headset keys commit 4f2e56a59b9947b3e698d3cabcb858765c12b1e8 upstream. This patch fixes the issue with 3.5mm headset keys on RPL-P platform. [ Rearranged the entry in SSID order by tiwai ] Signed-off-by: Saranya Gopal Signed-off-by: Ninad Naik Cc: Link: https://lore.kernel.org/r/20221011044916.2278867-1-saranya.gopal@intel.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 b57146e20074..0de1dcd3b946 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9069,6 +9069,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE), SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE), From a1bd289c10ac457247aaf9cd674bba1cc60e24a1 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 28 Jul 2022 10:40:14 +0300 Subject: [PATCH 010/610] mtd: rawnand: atmel: Unmap streaming DMA mappings commit 1161703c9bd664da5e3b2eb1a3bb40c210e026ea upstream. Every dma_map_single() call should have its dma_unmap_single() counterpart, because the DMA address space is a shared resource and one could render the machine unusable by consuming all DMA addresses. Link: https://lore.kernel.org/lkml/13c6c9a2-6db5-c3bf-349b-4c127ad3496a@axentia.se/ Cc: stable@vger.kernel.org Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Signed-off-by: Tudor Ambarus Acked-by: Alexander Dahl Reported-by: Peter Rosin Tested-by: Alexander Dahl Reviewed-by: Boris Brezillon Tested-by: Peter Rosin Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220728074014.145406-1-tudor.ambarus@microchip.com Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/raw/atmel/nand-controller.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index ddd93bc38ea6..73956a9f5449 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -405,6 +405,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc, dma_async_issue_pending(nc->dmac); wait_for_completion(&finished); + dma_unmap_single(nc->dev, buf_dma, len, dir); return 0; From f9dc33f231531f0e3ae6c0d7c9977b729d9291bd Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 29 Sep 2022 22:23:18 +0100 Subject: [PATCH 011/610] io_uring/net: don't update msg_name if not provided commit 6f10ae8a155446248055c7ddd480ef40139af788 upstream. io_sendmsg_copy_hdr() may clear msg->msg_name if the userspace didn't provide it, we should retain NULL in this case. Cc: stable@vger.kernel.org Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/97d49f61b5ec76d0900df658cfde3aa59ff22121.1664486545.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index ed6abd74f386..af856a8ce5ff 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4762,7 +4762,8 @@ static int io_setup_async_msg(struct io_kiocb *req, async_msg = req->async_data; req->flags |= REQ_F_NEED_CLEANUP; memcpy(async_msg, kmsg, sizeof(*kmsg)); - async_msg->msg.msg_name = &async_msg->addr; + if (async_msg->msg.msg_name) + async_msg->msg.msg_name = &async_msg->addr; /* if were using fast_iov, set it to the new one */ if (!async_msg->free_iov) async_msg->msg.msg_iter.iov = async_msg->fast_iov; From 15993e9a9b12487192cbf7eebf838676e05895d5 Mon Sep 17 00:00:00 2001 From: Gaurav Kohli Date: Wed, 5 Oct 2022 22:52:59 -0700 Subject: [PATCH 012/610] hv_netvsc: Fix race between VF offering and VF association message from host commit 365e1ececb2905f94cc10a5817c5b644a32a3ae2 upstream. During vm boot, there might be possibility that vf registration call comes before the vf association from host to vm. And this might break netvsc vf path, To prevent the same block vf registration until vf bind message comes from host. Cc: stable@vger.kernel.org Fixes: 00d7ddba11436 ("hv_netvsc: pair VF based on serial number") Reviewed-by: Haiyang Zhang Signed-off-by: Gaurav Kohli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/hyperv/hyperv_net.h | 3 ++- drivers/net/hyperv/netvsc.c | 4 ++++ drivers/net/hyperv/netvsc_drv.c | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index bc48855dff10..aab6cb5163fe 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -1037,7 +1037,8 @@ struct net_device_context { u32 vf_alloc; /* Serial number of the VF to team with */ u32 vf_serial; - + /* completion variable to confirm vf association */ + struct completion vf_add; /* Is the current data path through the VF NIC? */ bool data_path_is_vf; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 7bd935412853..fb2448f9a8b1 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -1450,6 +1450,10 @@ static void netvsc_send_vf(struct net_device *ndev, net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated; net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial; + + if (net_device_ctx->vf_alloc) + complete(&net_device_ctx->vf_add); + netdev_info(ndev, "VF slot %u %s\n", net_device_ctx->vf_serial, net_device_ctx->vf_alloc ? "added" : "removed"); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index ae4577731e3e..ec622e909a68 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2336,6 +2336,18 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev) } + /* Fallback path to check synthetic vf with + * help of mac addr + */ + list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) { + ndev = hv_get_drvdata(ndev_ctx->device_ctx); + if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr)) { + netdev_notice(vf_netdev, + "falling back to mac addr based matching\n"); + return ndev; + } + } + netdev_notice(vf_netdev, "no netdev found for vf serial:%u\n", serial); return NULL; @@ -2432,6 +2444,11 @@ static int netvsc_vf_changed(struct net_device *vf_netdev, unsigned long event) if (net_device_ctx->data_path_is_vf == vf_is_up) return NOTIFY_OK; + if (vf_is_up && !net_device_ctx->vf_alloc) { + netdev_info(ndev, "Waiting for the VF association from host\n"); + wait_for_completion(&net_device_ctx->vf_add); + } + ret = netvsc_switch_datapath(ndev, vf_is_up); if (ret) { @@ -2463,6 +2480,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) netvsc_vf_setxdp(vf_netdev, NULL); + reinit_completion(&net_device_ctx->vf_add); netdev_rx_handler_unregister(vf_netdev); netdev_upper_dev_unlink(vf_netdev, ndev); RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL); @@ -2502,6 +2520,7 @@ static int netvsc_probe(struct hv_device *dev, INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); + init_completion(&net_device_ctx->vf_add); spin_lock_init(&net_device_ctx->lock); INIT_LIST_HEAD(&net_device_ctx->reconfig_events); INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup); From 0d814a2199cf226d6c48fe8523ae146bed820d08 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 20 Sep 2022 14:32:02 +1000 Subject: [PATCH 013/610] cifs: destage dirty pages before re-reading them for cache=none commit bb44c31cdcac107344dd2fcc3bd0504a53575c51 upstream. This is the opposite case of kernel bugzilla 216301. If we mmap a file using cache=none and then proceed to update the mmapped area these updates are not reflected in a later pread() of that part of the file. To fix this we must first destage any dirty pages in the range before we allow the pread() to proceed. Cc: stable@vger.kernel.org Reviewed-by: Paulo Alcantara (SUSE) Reviewed-by: Enzo Matsumiya Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/file.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 2ef57bc054d2..ffec3a2f995d 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4015,6 +4015,15 @@ static ssize_t __cifs_readv( len = ctx->len; } + if (direct) { + rc = filemap_write_and_wait_range(file->f_inode->i_mapping, + offset, offset + len - 1); + if (rc) { + kref_put(&ctx->refcount, cifs_aio_ctx_release); + return -EAGAIN; + } + } + /* grab a lock here due to read response handlers can access ctx */ mutex_lock(&ctx->aio_mutex); From 60480291c1fcafad8425d93f771b5bcc2bd398b4 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 26 Sep 2022 11:36:29 +0800 Subject: [PATCH 014/610] cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message commit e98ecc6e94f4e6d21c06660b0f336df02836694f upstream. Commit d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") extend the dialects from 3 to 4, but forget to decrease the extended length when specific the dialect, then the message length is larger than expected. This maybe leak some info through network because not initialize the message body. After apply this patch, the VALIDATE_NEGOTIATE_INFO message length is reduced from 28 bytes to 26 bytes. Fixes: d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") Signed-off-by: Zhang Xiaoxu Cc: Acked-by: Paulo Alcantara (SUSE) Reviewed-by: Tom Talpey Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2pdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a423d1403539..cf8e85d8f488 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1137,9 +1137,9 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) pneg_inbuf->Dialects[0] = cpu_to_le16(server->vals->protocol_id); pneg_inbuf->DialectCount = cpu_to_le16(1); - /* structure is big enough for 3 dialects, sending only 1 */ + /* structure is big enough for 4 dialects, sending only 1 */ inbuflen = sizeof(*pneg_inbuf) - - sizeof(pneg_inbuf->Dialects[0]) * 2; + sizeof(pneg_inbuf->Dialects[0]) * 3; } rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, From ef4018707df8475043dafc810ead78e37d648212 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 13 Sep 2022 09:34:12 +0200 Subject: [PATCH 015/610] iio: dac: ad5593r: Fix i2c read protocol requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 558a25f903b4af6361b7fbeea08a6446a0745653 upstream. For reliable operation across the full range of supported interface rates, the AD5593R needs a STOP condition between address write, and data read (like show in the datasheet Figure 40) so in turn i2c_smbus_read_word_swapped cannot be used. While at it, a simple helper was added to make the code simpler. Fixes: 56ca9db862bf ("iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs") Signed-off-by: Michael Hennerich Signed-off-by: Nuno Sá Cc: Link: https://lore.kernel.org/r/20220913073413.140475-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/ad5593r.c | 46 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index 5b4df36fdc2a..4cc855c78121 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -13,6 +13,8 @@ #include #include +#include + #define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4) #define AD5593R_MODE_ADC_READBACK (4 << 4) @@ -20,6 +22,24 @@ #define AD5593R_MODE_GPIO_READBACK (6 << 4) #define AD5593R_MODE_REG_READBACK (7 << 4) +static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value) +{ + int ret; + u8 buf[2]; + + ret = i2c_smbus_write_byte(i2c, reg); + if (ret < 0) + return ret; + + ret = i2c_master_recv(i2c, buf, sizeof(buf)); + if (ret < 0) + return ret; + + *value = get_unaligned_be16(buf); + + return 0; +} + static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value) { struct i2c_client *i2c = to_i2c_client(st->dev); @@ -38,13 +58,7 @@ static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value) if (val < 0) return (int) val; - val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK); - if (val < 0) - return (int) val; - - *value = (u16) val; - - return 0; + return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value); } static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) @@ -58,25 +72,19 @@ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); - s32 val; - val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg); - if (val < 0) - return (int) val; - - *value = (u16) val; - - return 0; + return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value); } static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); - s32 val; + u16 val; + int ret; - val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK); - if (val < 0) - return (int) val; + ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val); + if (ret) + return ret; *value = (u8) val; From 1be580ed8403cc0e170a117bbd43b77102bd804c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 15 Aug 2022 09:16:47 +0000 Subject: [PATCH 016/610] iio: ltc2497: Fix reading conversion results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7f4f1096d5921f5d90547596f9ce80e0b924f887 upstream. After the result of the previous conversion is read the chip automatically starts a new conversion and doesn't accept new i2c transfers until this conversion is completed which makes the function return failure. So add an early return iff the programming of the new address isn't needed. Note this will not fix the problem in general, but all cases that are currently used. Once this changes we get the failure back, but this can be addressed when the need arises. Fixes: 69548b7c2c4f ("iio: adc: ltc2497: split protocol independent part in a separate module ") Reported-by: Meng Li Signed-off-by: Uwe Kleine-König Tested-by: Denys Zagorui Cc: Link: https://lore.kernel.org/r/20220815091647.1523532-1-dzagorui@cisco.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/ltc2497.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c index 1adddf5a88a9..61f373fab9a1 100644 --- a/drivers/iio/adc/ltc2497.c +++ b/drivers/iio/adc/ltc2497.c @@ -41,6 +41,19 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata, } *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17); + + /* + * The part started a new conversion at the end of the above i2c + * transfer, so if the address didn't change since the last call + * everything is fine and we can return early. + * If not (which should only happen when some sort of bulk + * conversion is implemented) we have to program the new + * address. Note that this probably fails as the conversion that + * was triggered above is like not complete yet and the two + * operations have to be done in a single transfer. + */ + if (ddata->addr_prev == address) + return 0; } ret = i2c_smbus_write_byte(st->client, From 5f6bfc1926bb9fd932267b11a07e13304d77d680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Mon, 12 Sep 2022 10:12:21 +0200 Subject: [PATCH 017/610] iio: adc: ad7923: fix channel readings for some variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f4f43f01cff2f29779343ade755191afd2581c77 upstream. Some of the supported devices have 4 or 2 LSB trailing bits that should not be taken into account. Hence we need to shift these bits out which fits perfectly on the scan type shift property. This change fixes both raw and buffered reads. Fixes: f2f7a449707e ("iio:adc:ad7923: Add support for the ad7904/ad7914/ad7924") Fixes: 851644a60d20 ("iio: adc: ad7923: Add support for the ad7908/ad7918/ad7928") Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20220912081223.173584-2-nuno.sa@analog.com Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/ad7923.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c index 069b561ee768..b8cc94b7dd80 100644 --- a/drivers/iio/adc/ad7923.c +++ b/drivers/iio/adc/ad7923.c @@ -93,6 +93,7 @@ enum ad7923_id { .sign = 'u', \ .realbits = (bits), \ .storagebits = 16, \ + .shift = 12 - (bits), \ .endianness = IIO_BE, \ }, \ } @@ -268,7 +269,8 @@ static int ad7923_read_raw(struct iio_dev *indio_dev, return ret; if (chan->address == EXTRACT(ret, 12, 4)) - *val = EXTRACT(ret, 0, 12); + *val = EXTRACT(ret, chan->scan_type.shift, + chan->scan_type.realbits); else return -EIO; From bc493cd75466e4e04b3a2e65d2cef13d275c4d1d Mon Sep 17 00:00:00 2001 From: Eddie James Date: Thu, 15 Sep 2022 14:57:18 -0500 Subject: [PATCH 018/610] iio: pressure: dps310: Refactor startup procedure commit c2329717bdd3fa62f8a2f3d8d85ad0bee4556bd7 upstream. Move the startup procedure into a function, and correct a missing check on the return code for writing the PRS_CFG register. Cc: Signed-off-by: Eddie James Reviewed-by: Joel Stanley Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220915195719.136812-2-eajames@linux.ibm.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/pressure/dps310.c | 188 ++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 89 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 0730380ceb69..9b787caaf67c 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -159,6 +159,102 @@ static int dps310_get_coefs(struct dps310_data *data) return 0; } +/* + * Some versions of the chip will read temperatures in the ~60C range when + * it's actually ~20C. This is the manufacturer recommended workaround + * to correct the issue. The registers used below are undocumented. + */ +static int dps310_temp_workaround(struct dps310_data *data) +{ + int rc; + int reg; + + rc = regmap_read(data->regmap, 0x32, ®); + if (rc) + return rc; + + /* + * If bit 1 is set then the device is okay, and the workaround does not + * need to be applied + */ + if (reg & BIT(1)) + return 0; + + rc = regmap_write(data->regmap, 0x0e, 0xA5); + if (rc) + return rc; + + rc = regmap_write(data->regmap, 0x0f, 0x96); + if (rc) + return rc; + + rc = regmap_write(data->regmap, 0x62, 0x02); + if (rc) + return rc; + + rc = regmap_write(data->regmap, 0x0e, 0x00); + if (rc) + return rc; + + return regmap_write(data->regmap, 0x0f, 0x00); +} + +static int dps310_startup(struct dps310_data *data) +{ + int rc; + int ready; + + /* + * Set up pressure sensor in single sample, one measurement per second + * mode + */ + rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); + if (rc) + return rc; + + /* + * Set up external (MEMS) temperature sensor in single sample, one + * measurement per second mode + */ + rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); + if (rc) + return rc; + + /* Temp and pressure shifts are disabled when PRC <= 8 */ + rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, + DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); + if (rc) + return rc; + + /* MEAS_CFG doesn't update correctly unless first written with 0 */ + rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, + DPS310_MEAS_CTRL_BITS, 0); + if (rc) + return rc; + + /* Turn on temperature and pressure measurement in the background */ + rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, + DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | + DPS310_TEMP_EN | DPS310_BACKGROUND); + if (rc) + return rc; + + /* + * Calibration coefficients required for reporting temperature. + * They are available 40ms after the device has started + */ + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, + ready & DPS310_COEF_RDY, 10000, 40000); + if (rc) + return rc; + + rc = dps310_get_coefs(data); + if (rc) + return rc; + + return dps310_temp_workaround(data); +} + static int dps310_get_pres_precision(struct dps310_data *data) { int rc; @@ -677,52 +773,12 @@ static const struct iio_info dps310_info = { .write_raw = dps310_write_raw, }; -/* - * Some verions of chip will read temperatures in the ~60C range when - * its actually ~20C. This is the manufacturer recommended workaround - * to correct the issue. The registers used below are undocumented. - */ -static int dps310_temp_workaround(struct dps310_data *data) -{ - int rc; - int reg; - - rc = regmap_read(data->regmap, 0x32, ®); - if (rc < 0) - return rc; - - /* - * If bit 1 is set then the device is okay, and the workaround does not - * need to be applied - */ - if (reg & BIT(1)) - return 0; - - rc = regmap_write(data->regmap, 0x0e, 0xA5); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x0f, 0x96); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x62, 0x02); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x0e, 0x00); - if (rc < 0) - return rc; - - return regmap_write(data->regmap, 0x0f, 0x00); -} - static int dps310_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct dps310_data *data; struct iio_dev *iio; - int rc, ready; + int rc; iio = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!iio) @@ -747,54 +803,8 @@ static int dps310_probe(struct i2c_client *client, if (rc) return rc; - /* - * Set up pressure sensor in single sample, one measurement per second - * mode - */ - rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); - - /* - * Set up external (MEMS) temperature sensor in single sample, one - * measurement per second mode - */ - rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); - if (rc < 0) - return rc; - - /* Temp and pressure shifts are disabled when PRC <= 8 */ - rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, - DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); - if (rc < 0) - return rc; - - /* MEAS_CFG doesn't update correctly unless first written with 0 */ - rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, - DPS310_MEAS_CTRL_BITS, 0); - if (rc < 0) - return rc; - - /* Turn on temperature and pressure measurement in the background */ - rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, - DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | - DPS310_TEMP_EN | DPS310_BACKGROUND); - if (rc < 0) - return rc; - - /* - * Calibration coefficients required for reporting temperature. - * They are available 40ms after the device has started - */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_COEF_RDY, 10000, 40000); - if (rc < 0) - return rc; - - rc = dps310_get_coefs(data); - if (rc < 0) - return rc; - - rc = dps310_temp_workaround(data); - if (rc < 0) + rc = dps310_startup(data); + if (rc) return rc; rc = devm_iio_device_register(&client->dev, iio); From 39f4c90b99956e7f7fdf54f0014ba1deaa425cbc Mon Sep 17 00:00:00 2001 From: Eddie James Date: Thu, 15 Sep 2022 14:57:19 -0500 Subject: [PATCH 019/610] iio: pressure: dps310: Reset chip after timeout commit 7b4ab4abcea4c0c10b25187bf2569e5a07e9a20c upstream. The DPS310 chip has been observed to get "stuck" such that pressure and temperature measurements are never indicated as "ready" in the MEAS_CFG register. The only solution is to reset the device and try again. In order to avoid continual failures, use a boolean flag to only try the reset after timeout once if errors persist. Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310") Cc: Signed-off-by: Eddie James Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220915195719.136812-3-eajames@linux.ibm.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/pressure/dps310.c | 74 ++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 9b787caaf67c..cf8b92fae1b3 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -89,6 +89,7 @@ struct dps310_data { s32 c00, c10, c20, c30, c01, c11, c21; s32 pressure_raw; s32 temp_raw; + bool timeout_recovery_failed; }; static const struct iio_chan_spec dps310_channels[] = { @@ -393,11 +394,69 @@ static int dps310_get_temp_k(struct dps310_data *data) return scale_factors[ilog2(rc)]; } +static int dps310_reset_wait(struct dps310_data *data) +{ + int rc; + + rc = regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); + if (rc) + return rc; + + /* Wait for device chip access: 2.5ms in specification */ + usleep_range(2500, 12000); + return 0; +} + +static int dps310_reset_reinit(struct dps310_data *data) +{ + int rc; + + rc = dps310_reset_wait(data); + if (rc) + return rc; + + return dps310_startup(data); +} + +static int dps310_ready_status(struct dps310_data *data, int ready_bit, int timeout) +{ + int sleep = DPS310_POLL_SLEEP_US(timeout); + int ready; + + return regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, ready & ready_bit, + sleep, timeout); +} + +static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout) +{ + int rc; + + rc = dps310_ready_status(data, ready_bit, timeout); + if (rc) { + if (rc == -ETIMEDOUT && !data->timeout_recovery_failed) { + /* Reset and reinitialize the chip. */ + if (dps310_reset_reinit(data)) { + data->timeout_recovery_failed = true; + } else { + /* Try again to get sensor ready status. */ + if (dps310_ready_status(data, ready_bit, timeout)) + data->timeout_recovery_failed = true; + else + return 0; + } + } + + return rc; + } + + data->timeout_recovery_failed = false; + return 0; +} + static int dps310_read_pres_raw(struct dps310_data *data) { int rc; int rate; - int ready; int timeout; s32 raw; u8 val[3]; @@ -409,9 +468,7 @@ static int dps310_read_pres_raw(struct dps310_data *data) timeout = DPS310_POLL_TIMEOUT_US(rate); /* Poll for sensor readiness; base the timeout upon the sample rate. */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_PRS_RDY, - DPS310_POLL_SLEEP_US(timeout), timeout); + rc = dps310_ready(data, DPS310_PRS_RDY, timeout); if (rc) goto done; @@ -448,7 +505,6 @@ static int dps310_read_temp_raw(struct dps310_data *data) { int rc; int rate; - int ready; int timeout; if (mutex_lock_interruptible(&data->lock)) @@ -458,10 +514,8 @@ static int dps310_read_temp_raw(struct dps310_data *data) timeout = DPS310_POLL_TIMEOUT_US(rate); /* Poll for sensor readiness; base the timeout upon the sample rate. */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_TMP_RDY, - DPS310_POLL_SLEEP_US(timeout), timeout); - if (rc < 0) + rc = dps310_ready(data, DPS310_TMP_RDY, timeout); + if (rc) goto done; rc = dps310_read_temp_ready(data); @@ -756,7 +810,7 @@ static void dps310_reset(void *action_data) { struct dps310_data *data = action_data; - regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); + dps310_reset_wait(data); } static const struct regmap_config dps310_regmap_config = { From 103b459590e1eb4d80b02761eb36c7cae1d9b58e Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Wed, 21 Sep 2022 15:34:46 +0300 Subject: [PATCH 020/610] xhci: dbc: Fix memory leak in xhci_alloc_dbc() commit d591b32e519603524a35b172156db71df9116902 upstream. If DbC is already in use, then the allocated memory for the xhci_dbc struct doesn't get freed before returning NULL, which leads to a memleak. Fixes: 534675942e90 ("xhci: dbc: refactor xhci_dbc_init()") Cc: stable@vger.kernel.org Signed-off-by: Rafael Mendonca Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20220921123450.671459-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-dbgcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index 46c8f3c187f7..f297f1f8edc7 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -988,7 +988,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver * dbc->driver = driver; if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE) - return NULL; + goto err; INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events); spin_lock_init(&dbc->lock); From 354d768e315db24c2b26a2b00510fdc25285440e Mon Sep 17 00:00:00 2001 From: Jean-Francois Le Fillatre Date: Tue, 27 Sep 2022 09:34:07 +0200 Subject: [PATCH 021/610] usb: add quirks for Lenovo OneLink+ Dock commit 37d49519b41405b08748392c6a7f193d9f77ecd2 upstream. The Lenovo OneLink+ Dock contains two VL812 USB3.0 controllers: 17ef:1018 upstream 17ef:1019 downstream These hubs suffer from two separate problems: 1) After the host system was suspended and woken up, the hubs appear to be in a random state. Some downstream ports (both internal to the built-in audio and network controllers, and external to USB sockets) may no longer be functional. The exact list of disabled ports (if any) changes from wakeup to wakeup. Ports remain in that state until the dock is power-cycled, or until the laptop is rebooted. Wakeup sources connected to the hubs (keyboard, WoL on the integrated gigabit controller) will wake the system up from suspend, but they may no longer work after wakeup (and in that case will no longer work as wakeup source in a subsequent suspend-wakeup cycle). This issue appears in the logs with messages such as: usb 1-6.1-port4: cannot disable (err = -71) usb 1-6-port2: cannot disable (err = -71) usb 1-6.1: clear tt 1 (80c0) error -71 usb 1-6-port4: cannot disable (err = -71) usb 1-6.4: PM: dpm_run_callback(): usb_dev_resume+0x0/0x10 [usbcore] returns -71 usb 1-6.4: PM: failed to resume async: error -71 usb 1-7: reset full-speed USB device number 5 using xhci_hcd usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: Cannot enable. Maybe the USB cable is bad? usb 1-6.1-port1: cannot disable (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: cannot reset (err = -71) usb 1-6.1-port1: Cannot enable. Maybe the USB cable is bad? usb 1-6.1-port1: cannot disable (err = -71) 2) Some USB devices cannot be enumerated properly. So far I have only seen the issue with USB 3.0 devices. The same devices work without problem directly connected to the host system, to other systems or to other hubs (even when those hubs are connected to the OneLink+ dock). One very reliable reproducer is this USB 3.0 HDD enclosure: 152d:9561 JMicron Technology Corp. / JMicron USA Technology Corp. Mobius I have seen it happen sporadically with other USB 3.0 enclosures, with controllers from different manufacturers, all self-powered. Typical messages in the logs: xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command usb 2-1.4: device not accepting address 6, error -62 xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command usb 2-1.4: device not accepting address 7, error -62 usb 2-1-port4: attempt power cycle xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command usb 2-1.4: device not accepting address 8, error -62 xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command usb 2-1.4: device not accepting address 9, error -62 usb 2-1-port4: unable to enumerate USB device Through trial and error, I found that the USB_QUIRK_RESET_RESUME solved the second issue. Further testing then uncovered the first issue. Test results are summarized in this table: ======================================================================================= Settings USB2 hotplug USB3 hotplug State after waking up --------------------------------------------------------------------------------------- power/control=auto works fails broken usbcore.autosuspend=-1 works works broken OR power/control=on power/control=auto works (1) works (1) works and USB_QUIRK_RESET_RESUME power/control=on works works works and USB_QUIRK_RESET_RESUME HUB_QUIRK_DISABLE_AUTOSUSPEND works works works and USB_QUIRK_RESET_RESUME ======================================================================================= In those results, the power/control settings are applied to both hubs, both on the USB2 and USB3 side, before each test. From those results, USB_QUIRK_RESET_RESUME is required to reset the hubs properly after a suspend-wakeup cycle, and the hubs must not autosuspend to work around the USB3 issue. A secondary effect of USB_QUIRK_RESET_RESUME is to prevent the hubs' upstream links from suspending (the downstream ports can still suspend). This secondary effect is used in results (1). It is enough to solve the USB3 problem. Setting USB_QUIRK_RESET_RESUME on those hubs is the smallest patch that solves both issues. Prior to creating this patch, I have used the USB_QUIRK_RESET_RESUME via the kernel command line for over a year without noticing any side effect. Thanks to Oliver Neukum @Suse for explanations of the operations of USB_QUIRK_RESET_RESUME, and requesting more testing. Signed-off-by: Jean-Francois Le Fillatre Cc: stable Link: https://lore.kernel.org/r/20220927073407.5672-1-jflf_kernel@gmx.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f99a65a64588..999b7c9697fc 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x1532, 0x0116), .driver_info = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */ + { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME }, + { USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Lenovo USB-C to Ethernet Adapter RTL8153-04 */ { USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM }, From de4434d6823c85c193f4cbf656449764ee6e0eeb Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Mon, 10 Oct 2022 17:08:27 +0200 Subject: [PATCH 022/610] can: kvaser_usb: Fix use of uninitialized completion commit cd7f30e174d09a02ca2afa5ef093fb0f0352e0d8 upstream. flush_comp is initialized when CMD_FLUSH_QUEUE is sent to the device and completed when the device sends CMD_FLUSH_QUEUE_RESP. This causes completion of uninitialized completion if the device sends CMD_FLUSH_QUEUE_RESP before CMD_FLUSH_QUEUE is ever sent (e.g. as a response to a flush by a previously bound driver, or a misbehaving device). Fix that by initializing flush_comp in kvaser_usb_init_one() like the other completions. This issue is only triggerable after RX URBs have been set up, i.e. the interface has been opened at least once. Cc: stable@vger.kernel.org Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family") Tested-by: Jimmy Assarsson Signed-off-by: Anssi Hannula Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/all/20221010150829.199676-3-extja@kvaser.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 1 + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index e570f5a76bbf..b6ba524dc5bd 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -717,6 +717,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) init_usb_anchor(&priv->tx_submitted); init_completion(&priv->start_comp); init_completion(&priv->stop_comp); + init_completion(&priv->flush_comp); priv->can.ctrlmode_supported = 0; priv->dev = dev; 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 93d7ee6d17b6..45eb7e462ce9 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -1914,7 +1914,7 @@ static int kvaser_usb_hydra_flush_queue(struct kvaser_usb_net_priv *priv) { int err; - init_completion(&priv->flush_comp); + reinit_completion(&priv->flush_comp); err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE, priv->channel); From b8c4f6345e0edeaf97ebcecb85435c6499008f19 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Mon, 10 Oct 2022 17:08:26 +0200 Subject: [PATCH 023/610] can: kvaser_usb_leaf: Fix overread with an invalid command commit 1499ecaea9d2ba68d5e18d80573b4561a8dc4ee7 upstream. For command events read from the device, kvaser_usb_leaf_read_bulk_callback() verifies that cmd->len does not exceed the size of the received data, but the actual kvaser_cmd handlers will happily read any kvaser_cmd fields without checking for cmd->len. This can cause an overread if the last cmd in the buffer is shorter than expected for the command type (with cmd->len showing the actual short size). Maximum overread seems to be 22 bytes (CMD_LEAF_LOG_MESSAGE), some of which are delivered to userspace as-is. Fix that by verifying the length of command before handling it. This issue can only occur after RX URBs have been set up, i.e. the interface has been opened at least once. Cc: stable@vger.kernel.org Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") Tested-by: Jimmy Assarsson Signed-off-by: Anssi Hannula Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/all/20221010150829.199676-2-extja@kvaser.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index 05d54c4f929f..b065f24f962f 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -309,6 +309,38 @@ struct kvaser_cmd { } u; } __packed; +#define CMD_SIZE_ANY 0xff +#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field) + +static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), + [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), + [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.leaf.softinfo), + [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.leaf.rx_can), + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), + [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, +}; + +static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { + [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), + [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), + [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.usbcan.softinfo), + [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, +}; + /* Summary of a kvaser error event, for a unified Leaf/Usbcan error * handling. Some discrepancies between the two families exist: * @@ -396,6 +428,43 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = { .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; +static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + /* buffer size >= cmd->len ensured by caller */ + u8 min_size = 0; + + switch (dev->driver_info->family) { + case KVASER_LEAF: + if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf)) + min_size = kvaser_usb_leaf_cmd_sizes_leaf[cmd->id]; + break; + case KVASER_USBCAN: + if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan)) + min_size = kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id]; + break; + } + + if (min_size == CMD_SIZE_ANY) + return 0; + + if (min_size) { + min_size += CMD_HEADER_LEN; + if (cmd->len >= min_size) + return 0; + + dev_err_ratelimited(&dev->intf->dev, + "Received command %u too short (size %u, needed %u)", + cmd->id, cmd->len, min_size); + return -EIO; + } + + dev_warn_ratelimited(&dev->intf->dev, + "Unhandled command (%d, size %d)\n", + cmd->id, cmd->len); + return -EINVAL; +} + static void * kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, const struct sk_buff *skb, int *frame_len, @@ -503,6 +572,9 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id, end: kfree(buf); + if (err == 0) + err = kvaser_usb_leaf_verify_size(dev, cmd); + return err; } @@ -1137,6 +1209,9 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev, static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { + if (kvaser_usb_leaf_verify_size(dev, cmd) < 0) + return; + switch (cmd->id) { case CMD_START_CHIP_REPLY: kvaser_usb_leaf_start_chip_reply(dev, cmd); From 0c28c2c0cfa2c0f7eb2f6d9237fa48357254cee5 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Mon, 10 Oct 2022 17:08:28 +0200 Subject: [PATCH 024/610] can: kvaser_usb_leaf: Fix TX queue out of sync after restart commit 455561fb618fde40558776b5b8435f9420f335db upstream. The TX queue seems to be implicitly flushed by the hardware during bus-off or bus-off recovery, but the driver does not reset the TX bookkeeping. Despite not resetting TX bookkeeping the driver still re-enables TX queue unconditionally, leading to "cannot find free context" / NETDEV_TX_BUSY errors if the TX queue was full at bus-off time. Fix that by resetting TX bookkeeping on CAN restart. Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778. Cc: stable@vger.kernel.org Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") Tested-by: Jimmy Assarsson Signed-off-by: Anssi Hannula Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/all/20221010150829.199676-4-extja@kvaser.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 ++ drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h index 61e67986b625..62958f04a2f2 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -178,6 +178,8 @@ struct kvaser_usb_dev_cfg { extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); + int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, int *actual_len); diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index b6ba524dc5bd..bdcaccf8e2b2 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -480,7 +480,7 @@ static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) /* This method might sleep. Do not call it in the atomic context * of URB completions. */ -static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) { usb_kill_anchored_urbs(&priv->tx_submitted); kvaser_usb_reset_tx_urb_contexts(priv); diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index b065f24f962f..ab999e5ba8e9 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -1430,6 +1430,8 @@ static int kvaser_usb_leaf_set_mode(struct net_device *netdev, switch (mode) { case CAN_MODE_START: + kvaser_usb_unlink_tx_urbs(priv); + err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); if (err) return err; From a4df91a88c3fb06663e7fa34a0bcf014df2ad19e Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Mon, 10 Oct 2022 17:08:29 +0200 Subject: [PATCH 025/610] can: kvaser_usb_leaf: Fix CAN state after restart commit 0be1a655fe68c8e6dcadbcbddb69cf2fb29881f5 upstream. can_restart() expects CMD_START_CHIP to set the error state to ERROR_ACTIVE as it calls netif_carrier_on() immediately afterwards. Otherwise the user may immediately trigger restart again and hit a BUG_ON() in can_restart(). Fix kvaser_usb_leaf set_mode(CMD_START_CHIP) to set the expected state. Cc: stable@vger.kernel.org Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") Tested-by: Jimmy Assarsson Signed-off-by: Anssi Hannula Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/all/20221010150829.199676-5-extja@kvaser.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index ab999e5ba8e9..4312be05fc5b 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -1435,6 +1435,8 @@ static int kvaser_usb_leaf_set_mode(struct net_device *netdev, err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); if (err) return err; + + priv->can.state = CAN_STATE_ERROR_ACTIVE; break; default: return -EOPNOTSUPP; From f9effcefa8bee10def7e3e3dda2ef337df8ffc16 Mon Sep 17 00:00:00 2001 From: Wenchao Chen Date: Tue, 11 Oct 2022 18:49:35 +0800 Subject: [PATCH 026/610] mmc: sdhci-sprd: Fix minimum clock limit commit 6e141772e6465f937458b35ddcfd0a981b6f5280 upstream. The Spreadtrum controller supports 100KHz minimal clock rate, which means that the current value 400KHz is wrong. Unfortunately this has also lead to fail to initialize some cards, which are allowed to require 100KHz to work. So, let's fix the problem by changing the minimal supported clock rate to 100KHz. Signed-off-by: Wenchao Chen Acked-by: Adrian Hunter Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20221011104935.10980-1-wenchao.chen666@gmail.com [Ulf: Clarified to commit-message] Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci-sprd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c index 11e375579cfb..f5c519026b52 100644 --- a/drivers/mmc/host/sdhci-sprd.c +++ b/drivers/mmc/host/sdhci-sprd.c @@ -296,7 +296,7 @@ static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host) static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host) { - return 400000; + return 100000; } static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host, From 7fa5304c4b5b425d4a0b3acf10139a7f6108a85f Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 27 Sep 2022 16:56:44 +0300 Subject: [PATCH 027/610] i2c: designware: Fix handling of real but unexpected device interrupts commit 301c8f5c32c8fb79c67539bc23972dc3ef48024c upstream. Commit c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI IDs") caused a regression on certain Gigabyte motherboards for Intel Alder Lake-S where system crashes to NULL pointer dereference in i2c_dw_xfer_msg() when system resumes from S3 sleep state ("deep"). I was able to debug the issue on Gigabyte Z690 AORUS ELITE and made following notes: - Issue happens when resuming from S3 but not when resuming from "s2idle" - PCI device 00:15.0 == i2c_designware.0 is already in D0 state when system enters into pci_pm_resume_noirq() while all other i2c_designware PCI devices are in D3. Devices were runtime suspended and in D3 prior entering into suspend - Interrupt comes after pci_pm_resume_noirq() when device interrupts are re-enabled - According to register dump the interrupt really comes from the i2c_designware.0. Controller is enabled, I2C target address register points to a one detectable I2C device address 0x60 and the DW_IC_RAW_INTR_STAT register START_DET, STOP_DET, ACTIVITY and TX_EMPTY bits are set indicating completed I2C transaction. My guess is that the firmware uses this controller to communicate with an on-board I2C device during resume but does not disable the controller before giving control to an operating system. I was told the UEFI update fixes this but never the less it revealed the driver is not ready to handle TX_EMPTY (or RX_FULL) interrupt when device is supposed to be idle and state variables are not set (especially the dev->msgs pointer which may point to NULL or stale old data). Introduce a new software status flag STATUS_ACTIVE indicating when the controller is active in driver point of view. Now treat all interrupts that occur when is not set as unexpected and mask all interrupts from the controller. Fixes: c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI IDs") Reported-by: Samuel Clark Link: https://bugzilla.kernel.org/show_bug.cgi?id=215907 Cc: stable@vger.kernel.org # v5.12+ Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-designware-core.h | 7 +++++-- drivers/i2c/busses/i2c-designware-master.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 60a2e750cee9..9be81dbebede 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -126,8 +126,9 @@ * status codes */ #define STATUS_IDLE 0x0 -#define STATUS_WRITE_IN_PROGRESS 0x1 -#define STATUS_READ_IN_PROGRESS 0x2 +#define STATUS_ACTIVE 0x1 +#define STATUS_WRITE_IN_PROGRESS 0x2 +#define STATUS_READ_IN_PROGRESS 0x4 /* * operation modes @@ -322,12 +323,14 @@ void i2c_dw_disable_int(struct dw_i2c_dev *dev); static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) { + dev->status |= STATUS_ACTIVE; regmap_write(dev->map, DW_IC_ENABLE, 1); } static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev) { regmap_write(dev->map, DW_IC_ENABLE, 0); + dev->status &= ~STATUS_ACTIVE; } void __i2c_dw_disable(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 9b08bb5df38d..e0559eff8928 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -720,6 +720,19 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) u32 stat; stat = i2c_dw_read_clear_intrbits(dev); + + if (!(dev->status & STATUS_ACTIVE)) { + /* + * Unexpected interrupt in driver point of view. State + * variables are either unset or stale so acknowledge and + * disable interrupts for suppressing further interrupts if + * interrupt really came from this HW (E.g. firmware has left + * the HW active). + */ + regmap_write(dev->map, DW_IC_INTR_MASK, 0); + return 0; + } + if (stat & DW_IC_INTR_TX_ABRT) { dev->cmd_err |= DW_IC_ERR_TX_ABRT; dev->status = STATUS_IDLE; From 34ed22dd286073651dd114249bf54bed2802d3a5 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 15 Aug 2022 15:43:14 -0400 Subject: [PATCH 028/610] fs: dlm: fix race between test_bit() and queue_work() commit eef6ec9bf390e836a6c4029f3620fe49528aa1fe upstream. This patch fixes a race by using ls_cb_mutex around the bit operations and conditional code blocks for LSFL_CB_DELAY. The function dlm_callback_stop() expects to stop all callbacks and flush all currently queued onces. The set_bit() is not enough because there can still be queue_work() after the workqueue was flushed. To avoid queue_work() after set_bit(), surround both by ls_cb_mutex. Cc: stable@vger.kernel.org Signed-off-by: Alexander Aring Signed-off-by: David Teigland Signed-off-by: Greg Kroah-Hartman --- fs/dlm/ast.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 283c7b94edda..ca06069e95c8 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c @@ -198,13 +198,13 @@ void dlm_add_cb(struct dlm_lkb *lkb, uint32_t flags, int mode, int status, if (!prev_seq) { kref_get(&lkb->lkb_ref); + mutex_lock(&ls->ls_cb_mutex); if (test_bit(LSFL_CB_DELAY, &ls->ls_flags)) { - mutex_lock(&ls->ls_cb_mutex); list_add(&lkb->lkb_cb_list, &ls->ls_cb_delay); - mutex_unlock(&ls->ls_cb_mutex); } else { queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work); } + mutex_unlock(&ls->ls_cb_mutex); } out: mutex_unlock(&lkb->lkb_cb_mutex); @@ -284,7 +284,9 @@ void dlm_callback_stop(struct dlm_ls *ls) void dlm_callback_suspend(struct dlm_ls *ls) { + mutex_lock(&ls->ls_cb_mutex); set_bit(LSFL_CB_DELAY, &ls->ls_flags); + mutex_unlock(&ls->ls_cb_mutex); if (ls->ls_callback_wq) flush_workqueue(ls->ls_callback_wq); From 219e4a0f9d68592988ed3a98cb4d9f1e1d436cd9 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 15 Aug 2022 15:43:15 -0400 Subject: [PATCH 029/610] fs: dlm: handle -EBUSY first in lock arg validation commit 44637ca41d551d409a481117b07fa209b330fca9 upstream. During lock arg validation, first check for -EBUSY cases, then for -EINVAL cases. The -EINVAL checks look at lkb state variables which are not stable when an lkb is busy and would cause an -EBUSY result, e.g. lkb->lkb_grmode. Cc: stable@vger.kernel.org Signed-off-by: Alexander Aring Signed-off-by: David Teigland Signed-off-by: Greg Kroah-Hartman --- fs/dlm/lock.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 9f93496d2cc9..bcc7127c4c0a 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -2888,17 +2888,9 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args) static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, struct dlm_args *args) { - int rv = -EINVAL; + int rv = -EBUSY; if (args->flags & DLM_LKF_CONVERT) { - if (lkb->lkb_flags & DLM_IFL_MSTCPY) - goto out; - - if (args->flags & DLM_LKF_QUECVT && - !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1]) - goto out; - - rv = -EBUSY; if (lkb->lkb_status != DLM_LKSTS_GRANTED) goto out; @@ -2907,6 +2899,14 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, if (is_overlap(lkb)) goto out; + + rv = -EINVAL; + if (lkb->lkb_flags & DLM_IFL_MSTCPY) + goto out; + + if (args->flags & DLM_LKF_QUECVT && + !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1]) + goto out; } lkb->lkb_exflags = args->flags; From 17214cfab73b47049f7e6d273480d221f5fcd62b Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Wed, 7 Sep 2022 15:01:59 +0000 Subject: [PATCH 030/610] HID: multitouch: Add memory barriers commit be6e2b5734a425941fcdcdbd2a9337be498ce2cf upstream. This fixes broken atomic checks which cause a race between the release-timer and processing of hid input. I noticed that contacts were sometimes sticking, even with the "sticky fingers" quirk enabled. This fixes that problem. Cc: stable@vger.kernel.org Fixes: 9609827458c3 ("HID: multitouch: optimize the sticky fingers timer") Signed-off-by: Andri Yngvason Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20220907150159.2285460-1-andri@yngvason.is Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-multitouch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index a14c48de4446..08462ac72b89 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1186,7 +1186,7 @@ static void mt_touch_report(struct hid_device *hid, int contact_count = -1; /* sticky fingers release in progress, abort */ - if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) return; scantime = *app->scantime; @@ -1267,7 +1267,7 @@ static void mt_touch_report(struct hid_device *hid, del_timer(&td->release_timer); } - clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); } static int mt_touch_input_configured(struct hid_device *hdev, @@ -1702,11 +1702,11 @@ static void mt_expired_timeout(struct timer_list *t) * An input report came in just before we release the sticky fingers, * it will take care of the sticky fingers. */ - if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) return; if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) mt_release_contacts(hdev); - clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); } static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) From fcfeecca153d08d22b62a0052b364af7276c5701 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Fri, 23 Sep 2022 21:45:52 +0800 Subject: [PATCH 031/610] quota: Check next/prev free block number after reading from quota file commit 6c8ea8b8cd4722efd419f91ca46a2dc81b7d89a3 upstream. Following process: Init: v2_read_file_info: <3> dqi_free_blk 0 dqi_free_entry 5 dqi_blks 6 Step 1. chown bin f_a -> dquot_acquire -> v2_write_dquot: qtree_write_dquot do_insert_tree find_free_dqentry get_free_dqblk write_blk(info->dqi_blocks) // info->dqi_blocks = 6, failure. The content in physical block (corresponding to blk 6) is random. Step 2. chown root f_a -> dquot_transfer -> dqput_all -> dqput -> ext4_release_dquot -> v2_release_dquot -> qtree_delete_dquot: dquot_release remove_tree free_dqentry put_free_dqblk(6) info->dqi_free_blk = blk // info->dqi_free_blk = 6 Step 3. drop cache (buffer head for block 6 is released) Step 4. chown bin f_b -> dquot_acquire -> commit_dqblk -> v2_write_dquot: qtree_write_dquot do_insert_tree find_free_dqentry get_free_dqblk dh = (struct qt_disk_dqdbheader *)buf blk = info->dqi_free_blk // 6 ret = read_blk(info, blk, buf) // The content of buf is random info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free) // random blk Step 5. chown bin f_c -> notify_change -> ext4_setattr -> dquot_transfer: dquot = dqget -> acquire_dquot -> ext4_acquire_dquot -> dquot_acquire -> commit_dqblk -> v2_write_dquot -> dq_insert_tree: do_insert_tree find_free_dqentry get_free_dqblk blk = info->dqi_free_blk // If blk < 0 and blk is not an error code, it will be returned as dquot transfer_to[USRQUOTA] = dquot // A random negative value __dquot_transfer(transfer_to) dquot_add_inodes(transfer_to[cnt]) spin_lock(&dquot->dq_dqb_lock) // page fault , which will lead to kernel page fault: Quota error (device sda): qtree_write_dquot: Error -8000 occurred while creating quota BUG: unable to handle page fault for address: ffffffffffffe120 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page Oops: 0002 [#1] PREEMPT SMP CPU: 0 PID: 5974 Comm: chown Not tainted 6.0.0-rc1-00004 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) RIP: 0010:_raw_spin_lock+0x3a/0x90 Call Trace: dquot_add_inodes+0x28/0x270 __dquot_transfer+0x377/0x840 dquot_transfer+0xde/0x540 ext4_setattr+0x405/0x14d0 notify_change+0x68e/0x9f0 chown_common+0x300/0x430 __x64_sys_fchownat+0x29/0x40 In order to avoid accessing invalid quota memory address, this patch adds block number checking of next/prev free block read from quota file. Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216372 Fixes: 1da177e4c3f4152 ("Linux-2.6.12-rc2") CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220923134555.2623931-2-chengzhihao1@huawei.com Signed-off-by: Zhihao Cheng Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman --- fs/quota/quota_tree.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index 5f2405994280..7e65d67de9f3 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c @@ -71,6 +71,35 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) return ret; } +static inline int do_check_range(struct super_block *sb, const char *val_name, + uint val, uint min_val, uint max_val) +{ + if (val < min_val || val > max_val) { + quota_error(sb, "Getting %s %u out of range %u-%u", + val_name, val, min_val, max_val); + return -EUCLEAN; + } + + return 0; +} + +static int check_dquot_block_header(struct qtree_mem_dqinfo *info, + struct qt_disk_dqdbheader *dh) +{ + int err = 0; + + err = do_check_range(info->dqi_sb, "dqdh_next_free", + le32_to_cpu(dh->dqdh_next_free), 0, + info->dqi_blocks - 1); + if (err) + return err; + err = do_check_range(info->dqi_sb, "dqdh_prev_free", + le32_to_cpu(dh->dqdh_prev_free), 0, + info->dqi_blocks - 1); + + return err; +} + /* Remove empty block from list and return it */ static int get_free_dqblk(struct qtree_mem_dqinfo *info) { @@ -85,6 +114,9 @@ static int get_free_dqblk(struct qtree_mem_dqinfo *info) ret = read_blk(info, blk, buf); if (ret < 0) goto out_buf; + ret = check_dquot_block_header(info, dh); + if (ret) + goto out_buf; info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free); } else { @@ -232,6 +264,9 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, *err = read_blk(info, blk, buf); if (*err < 0) goto out_buf; + *err = check_dquot_block_header(info, dh); + if (*err) + goto out_buf; } else { blk = get_free_dqblk(info); if ((int)blk < 0) { @@ -424,6 +459,9 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, goto out_buf; } dh = (struct qt_disk_dqdbheader *)buf; + ret = check_dquot_block_header(info, dh); + if (ret) + goto out_buf; le16_add_cpu(&dh->dqdh_entries, -1); if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ ret = remove_free_dqentry(info, buf, blk); From d0507b36da9fc50925fe9b2a89ab6c507d449194 Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Tue, 2 Aug 2022 17:41:28 +0200 Subject: [PATCH 032/610] platform/chrome: cros_ec_proto: Update version on GET_NEXT_EVENT failure commit f74c7557ed0d321947e8bb4e9d47c1013f8b2227 upstream. Some EC based devices (e.g. Fingerpint MCU) can jump to RO part of the firmware (intentionally or due to device reboot). The RO part doesn't change during the device lifecycle, so it won't support newer version of EC_CMD_GET_NEXT_EVENT command. Function cros_ec_query_all() is responsible for finding maximum supported MKBP event version. It's usually called when the device is running RW part of the firmware, so the command version can be potentially higher than version supported by the RO. The problem was fixed by updating maximum supported version when the device returns EC_RES_INVALID_VERSION (mapped to -ENOPROTOOPT). That way the kernel will use highest common version supported by RO and RW. Fixes: 3300fdd630d4 ("platform/chrome: cros_ec: handle MKBP more events flag") Cc: # 5.10+ Reviewed-by: Guenter Roeck Signed-off-by: Patryk Duda Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20220802154128.21175-1-pdk@semihalf.com Signed-off-by: Greg Kroah-Hartman --- drivers/platform/chrome/cros_ec_proto.c | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 1575d603d3ff..9d1f431bdc24 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -748,6 +748,7 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, u8 event_type; u32 host_event; int ret; + u32 ver_mask; /* * Default value for wake_event. @@ -769,6 +770,37 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, return get_keyboard_state_event(ec_dev); ret = get_next_event(ec_dev); + /* + * -ENOPROTOOPT is returned when EC returns EC_RES_INVALID_VERSION. + * This can occur when EC based device (e.g. Fingerprint MCU) jumps to + * the RO image which doesn't support newer version of the command. In + * this case we will attempt to update maximum supported version of the + * EC_CMD_GET_NEXT_EVENT. + */ + if (ret == -ENOPROTOOPT) { + dev_dbg(ec_dev->dev, + "GET_NEXT_EVENT returned invalid version error.\n"); + ret = cros_ec_get_host_command_version_mask(ec_dev, + EC_CMD_GET_NEXT_EVENT, + &ver_mask); + if (ret < 0 || ver_mask == 0) + /* + * Do not change the MKBP supported version if we can't + * obtain supported version correctly. Please note that + * calling EC_CMD_GET_NEXT_EVENT returned + * EC_RES_INVALID_VERSION which means that the command + * is present. + */ + return -ENOPROTOOPT; + + ec_dev->mkbp_event_supported = fls(ver_mask); + dev_dbg(ec_dev->dev, "MKBP support version changed to %u\n", + ec_dev->mkbp_event_supported - 1); + + /* Try to get next event with new MKBP support version set. */ + ret = get_next_event(ec_dev); + } + if (ret <= 0) return ret; From a2140a9922d1bf88e9d9bd1fa8d438f1c2e2f178 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 21 Sep 2022 16:53:53 +0200 Subject: [PATCH 033/610] ASoC: wcd9335: fix order of Slimbus unprepare/disable commit ea8ef003aa53ad23e7705c5cab1c4e664faa6c79 upstream. Slimbus streams are first prepared and then enabled, so the cleanup path should reverse it. The unprepare sets stream->num_ports to 0 and frees the stream->ports. Calling disable after unprepare was not really effective (channels was not deactivated) and could lead to further issues due to making transfers on unprepared stream. Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") Cc: Signed-off-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220921145354.1683791-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wcd9335.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 3a13afbfb74b..075ed20e9fad 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1971,8 +1971,8 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - slim_stream_unprepare(dai_data->sruntime); slim_stream_disable(dai_data->sruntime); + slim_stream_unprepare(dai_data->sruntime); break; default: break; From e1ab98ec2bc9dc83c9ad086e2a8cdb4ba6a55038 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 21 Sep 2022 16:53:54 +0200 Subject: [PATCH 034/610] ASoC: wcd934x: fix order of Slimbus unprepare/disable commit e96bca7eaa5747633ec638b065630ff83728982a upstream. Slimbus streams are first prepared and then enabled, so the cleanup path should reverse it. The unprepare sets stream->num_ports to 0 and frees the stream->ports. Calling disable after unprepare was not really effective (channels was not deactivated) and could lead to further issues due to making transfers on unprepared stream. Fixes: a61f3b4f476e ("ASoC: wcd934x: add support to wcd9340/wcd9341 codec") Cc: Signed-off-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220921145354.1683791-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/codecs/wcd934x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index 144046864d15..4ca52d9db23a 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -1913,8 +1913,8 @@ static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - slim_stream_unprepare(dai_data->sruntime); slim_stream_disable(dai_data->sruntime); + slim_stream_unprepare(dai_data->sruntime); break; default: break; From 3281e81ce90cbf1a6723d9c29477fd24fdc1981e Mon Sep 17 00:00:00 2001 From: Liang He Date: Fri, 16 Sep 2022 23:47:08 +0800 Subject: [PATCH 035/610] hwmon: (gsc-hwmon) Call of_node_get() before of_find_xxx API commit 7f62cf781e6567d59c8935dc8c6068ce2bb904b7 upstream. In gsc_hwmon_get_devtree_pdata(), we should call of_node_get() before the of_find_compatible_node() which will automatically call of_node_put() for the 'from' argument. Fixes: 3bce5377ef66 ("hwmon: Add Gateworks System Controller support") Signed-off-by: Liang He Co-developed-by: Mengda Chen Signed-off-by: Mengda Chen Link: https://lore.kernel.org/r/20220916154708.3084515-1-chenmengda2009@163.com Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/gsc-hwmon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c index 1fe37418ff46..f29ce49294da 100644 --- a/drivers/hwmon/gsc-hwmon.c +++ b/drivers/hwmon/gsc-hwmon.c @@ -267,6 +267,7 @@ gsc_hwmon_get_devtree_pdata(struct device *dev) pdata->nchannels = nchannels; /* fan controller base address */ + of_node_get(dev->parent->of_node); fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan"); if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) { dev_err(dev, "fan node without base\n"); From 78d81a8a8ce10321be202a909f565677fdafdd56 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 30 Aug 2022 18:32:46 +0300 Subject: [PATCH 036/610] net: thunderbolt: Enable DMA paths only after rings are enabled commit ff7cd07f306406493f7b78890475e85b6d0811ed upstream. If the other host starts sending packets early on it is possible that we are still in the middle of populating the initial Rx ring packets to the ring. This causes the tbnet_poll() to mess over the queue and causes list corruption. This happens specifically when connected with macOS as it seems start sending various IP discovery packets as soon as its side of the paths are configured. To prevent this we move the DMA path enabling to happen after we have primed the Rx ring. This makes sure no incoming packets can arrive before we are ready to handle them. Fixes: e69b6c02b4c3 ("net: Add support for networking over Thunderbolt cable") Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/thunderbolt.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c index 9a6a8353e192..ae2211998ded 100644 --- a/drivers/net/thunderbolt.c +++ b/drivers/net/thunderbolt.c @@ -612,18 +612,13 @@ static void tbnet_connected_work(struct work_struct *work) return; } - /* Both logins successful so enable the high-speed DMA paths and - * start the network device queue. + /* Both logins successful so enable the rings, high-speed DMA + * paths and start the network device queue. + * + * Note we enable the DMA paths last to make sure we have primed + * the Rx ring before any incoming packets are allowed to + * arrive. */ - ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path, - net->rx_ring.ring->hop, - net->remote_transmit_path, - net->tx_ring.ring->hop); - if (ret) { - netdev_err(net->dev, "failed to enable DMA paths\n"); - return; - } - tb_ring_start(net->tx_ring.ring); tb_ring_start(net->rx_ring.ring); @@ -635,10 +630,21 @@ static void tbnet_connected_work(struct work_struct *work) if (ret) goto err_free_rx_buffers; + ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path, + net->rx_ring.ring->hop, + net->remote_transmit_path, + net->tx_ring.ring->hop); + if (ret) { + netdev_err(net->dev, "failed to enable DMA paths\n"); + goto err_free_tx_buffers; + } + netif_carrier_on(net->dev); netif_start_queue(net->dev); return; +err_free_tx_buffers: + tbnet_free_buffers(&net->tx_ring); err_free_rx_buffers: tbnet_free_buffers(&net->rx_ring); err_stop_rings: From fcf0f6cbb65379ba437c66ef0ec78a360cc483bd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 9 Sep 2022 13:25:29 +0200 Subject: [PATCH 037/610] regulator: qcom_rpm: Fix circular deferral regression commit 8478ed5844588703a1a4c96a004b1525fbdbdd5e upstream. On recent kernels, the PM8058 L16 (or any other PM8058 LDO-regulator) does not come up if they are supplied by an SMPS-regulator. This is not very strange since the regulators are registered in a long array and the L-regulators are registered before the S-regulators, and if an L-regulator defers, it will never get around to registering the S-regulator that it needs. See arch/arm/boot/dts/qcom-apq8060-dragonboard.dts: pm8058-regulators { (...) vdd_l13_l16-supply = <&pm8058_s4>; (...) Ooops. Fix this by moving the PM8058 S-regulators first in the array. Do the same for the PM8901 S-regulators (though this is currently not causing any problems with out device trees) so that the pattern of registration order is the same on all PMnnnn chips. Fixes: 087a1b5cdd55 ("regulator: qcom: Rework to single platform device") Cc: stable@vger.kernel.org Cc: Andy Gross Cc: Bjorn Andersson Cc: Konrad Dybcio Cc: linux-arm-msm@vger.kernel.org Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20220909112529.239143-1-linus.walleij@linaro.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/regulator/qcom_rpm-regulator.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 7f9d66ac37ff..3c41b71a1f52 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -802,6 +802,12 @@ static const struct rpm_regulator_data rpm_pm8018_regulators[] = { }; static const struct rpm_regulator_data rpm_pm8058_regulators[] = { + { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" }, + { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" }, + { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" }, + { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" }, + { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" }, + { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, { "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" }, @@ -829,12 +835,6 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = { { "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" }, { "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" }, - { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" }, - { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" }, - { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" }, - { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" }, - { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" }, - { "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" }, { "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" }, @@ -843,6 +843,12 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = { }; static const struct rpm_regulator_data rpm_pm8901_regulators[] = { + { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" }, + { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" }, + { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" }, + { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" }, + { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" }, + { "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" }, { "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" }, { "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" }, @@ -851,12 +857,6 @@ static const struct rpm_regulator_data rpm_pm8901_regulators[] = { { "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" }, { "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" }, - { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" }, - { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" }, - { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" }, - { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" }, - { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" }, - { "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" }, { "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" }, { "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" }, From d46c24f307fbc491980d4170071dc6d79b8b9b3e Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Fri, 15 Jul 2022 18:51:55 +0100 Subject: [PATCH 038/610] arm64: topology: move store_cpu_topology() to shared code commit 456797da792fa7cbf6698febf275fe9b36691f78 upstream. arm64's method of defining a default cpu topology requires only minimal changes to apply to RISC-V also. The current arm64 implementation exits early in a uniprocessor configuration by reading MPIDR & claiming that uniprocessor can rely on the default values. This is appears to be a hangover from prior to '3102bc0e6ac7 ("arm64: topology: Stop using MPIDR for topology information")', because the current code just assigns default values for multiprocessor systems. With the MPIDR references removed, store_cpu_topolgy() can be moved to the common arch_topology code. Reviewed-by: Sudeep Holla Acked-by: Catalin Marinas Reviewed-by: Atish Patra Signed-off-by: Conor Dooley Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kernel/topology.c | 40 ------------------------------------ drivers/base/arch_topology.c | 19 +++++++++++++++++ 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index d844b5317d2d..877c68f47282 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -22,46 +22,6 @@ #include #include -void store_cpu_topology(unsigned int cpuid) -{ - struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; - u64 mpidr; - - if (cpuid_topo->package_id != -1) - goto topology_populated; - - mpidr = read_cpuid_mpidr(); - - /* Uniprocessor systems can rely on default topology values */ - if (mpidr & MPIDR_UP_BITMASK) - return; - - /* - * This would be the place to create cpu topology based on MPIDR. - * - * However, it cannot be trusted to depict the actual topology; some - * pieces of the architecture enforce an artificial cap on Aff0 values - * (e.g. GICv3's ICC_SGI1R_EL1 limits it to 15), leading to an - * artificial cycling of Aff1, Aff2 and Aff3 values. IOW, these end up - * having absolutely no relationship to the actual underlying system - * topology, and cannot be reasonably used as core / package ID. - * - * If the MT bit is set, Aff0 *could* be used to define a thread ID, but - * we still wouldn't be able to obtain a sane core ID. This means we - * need to entirely ignore MPIDR for any topology deduction. - */ - cpuid_topo->thread_id = -1; - cpuid_topo->core_id = cpuid; - cpuid_topo->package_id = cpu_to_node(cpuid); - - pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n", - cpuid, cpuid_topo->package_id, cpuid_topo->core_id, - cpuid_topo->thread_id, mpidr); - -topology_populated: - update_siblings_masks(cpuid); -} - #ifdef CONFIG_ACPI static bool __init acpi_cpu_is_threaded(int cpu) { diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index ef4fc89f085d..31bd6f4e5dc4 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -690,4 +690,23 @@ void __init init_cpu_topology(void) else if (of_have_populated_dt() && parse_dt_topology()) reset_cpu_topology(); } + +void store_cpu_topology(unsigned int cpuid) +{ + struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; + + if (cpuid_topo->package_id != -1) + goto topology_populated; + + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = cpuid; + cpuid_topo->package_id = cpu_to_node(cpuid); + + pr_debug("CPU%u: package %d core %d thread %d\n", + cpuid, cpuid_topo->package_id, cpuid_topo->core_id, + cpuid_topo->thread_id); + +topology_populated: + update_siblings_masks(cpuid); +} #endif From 8c487db000fd7634e4791ac34245a8e18a224b29 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Fri, 15 Jul 2022 18:51:56 +0100 Subject: [PATCH 039/610] riscv: topology: fix default topology reporting commit fbd92809997a391f28075f1c8b5ee314c225557c upstream. RISC-V has no sane defaults to fall back on where there is no cpu-map in the devicetree. Without sane defaults, the package, core and thread IDs are all set to -1. This causes user-visible inaccuracies for tools like hwloc/lstopo which rely on the sysfs cpu topology files to detect a system's topology. On a PolarFire SoC, which should have 4 harts with a thread each, lstopo currently reports: Machine (793MB total) Package L#0 NUMANode L#0 (P#0 793MB) Core L#0 L1d L#0 (32KB) + L1i L#0 (32KB) + PU L#0 (P#0) L1d L#1 (32KB) + L1i L#1 (32KB) + PU L#1 (P#1) L1d L#2 (32KB) + L1i L#2 (32KB) + PU L#2 (P#2) L1d L#3 (32KB) + L1i L#3 (32KB) + PU L#3 (P#3) Adding calls to store_cpu_topology() in {boot,smp} hart bringup code results in the correct topolgy being reported: Machine (793MB total) Package L#0 NUMANode L#0 (P#0 793MB) L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0) L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#1) L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#2) L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#3) CC: stable@vger.kernel.org # 456797da792f: arm64: topology: move store_cpu_topology() to shared code Fixes: 03f11f03dbfe ("RISC-V: Parse cpu topology during boot.") Reported-by: Brice Goglin Link: https://github.com/open-mpi/hwloc/issues/536 Reviewed-by: Sudeep Holla Reviewed-by: Atish Patra Signed-off-by: Conor Dooley Signed-off-by: Greg Kroah-Hartman --- arch/riscv/Kconfig | 2 +- arch/riscv/kernel/smpboot.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 20bc4b8c13b9..1b21f332f58c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -46,7 +46,7 @@ config RISCV select CLINT_TIMER if !MMU select COMMON_CLK select EDAC_SUPPORT - select GENERIC_ARCH_TOPOLOGY if SMP + select GENERIC_ARCH_TOPOLOGY select GENERIC_ATOMIC64 if !64BIT select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_EARLY_IOREMAP diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index bd82375db51a..0f323e935dd8 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -53,6 +53,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) unsigned int curr_cpuid; curr_cpuid = smp_processor_id(); + store_cpu_topology(curr_cpuid); numa_store_cpu_info(curr_cpuid); numa_add_cpu(curr_cpuid); @@ -165,9 +166,9 @@ asmlinkage __visible void smp_callin(void) mmgrab(mm); current->active_mm = mm; + store_cpu_topology(curr_cpuid); notify_cpu_starting(curr_cpuid); numa_add_cpu(curr_cpuid); - update_siblings_masks(curr_cpuid); set_cpu_online(curr_cpuid, 1); /* From dc235db7b79a352d07d62e8757ad856dbf1564c1 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 22 Sep 2022 22:56:06 +0100 Subject: [PATCH 040/610] RISC-V: Make port I/O string accessors actually work commit 9cc205e3c17d5716da7ebb7fa0c985555e95d009 upstream. Fix port I/O string accessors such as `insb', `outsb', etc. which use the physical PCI port I/O address rather than the corresponding memory mapping to get at the requested location, which in turn breaks at least accesses made by our parport driver to a PCIe parallel port such as: PCI parallel port detected: 1415:c118, I/O at 0x1000(0x1008), IRQ 20 parport0: PC-style at 0x1000 (0x1008), irq 20, using FIFO [PCSPP,TRISTATE,COMPAT,EPP,ECP] causing a memory access fault: Unable to handle kernel access to user memory without uaccess routines at virtual address 0000000000001008 Oops [#1] Modules linked in: CPU: 1 PID: 350 Comm: cat Not tainted 6.0.0-rc2-00283-g10d4879f9ef0-dirty #23 Hardware name: SiFive HiFive Unmatched A00 (DT) epc : parport_pc_fifo_write_block_pio+0x266/0x416 ra : parport_pc_fifo_write_block_pio+0xb4/0x416 epc : ffffffff80542c3e ra : ffffffff80542a8c sp : ffffffd88899fc60 gp : ffffffff80fa2700 tp : ffffffd882b1e900 t0 : ffffffd883d0b000 t1 : ffffffffff000002 t2 : 4646393043330a38 s0 : ffffffd88899fcf0 s1 : 0000000000001000 a0 : 0000000000000010 a1 : 0000000000000000 a2 : ffffffd883d0a010 a3 : 0000000000000023 a4 : 00000000ffff8fbb a5 : ffffffd883d0a001 a6 : 0000000100000000 a7 : ffffffc800000000 s2 : ffffffffff000002 s3 : ffffffff80d28880 s4 : ffffffff80fa1f50 s5 : 0000000000001008 s6 : 0000000000000008 s7 : ffffffd883d0a000 s8 : 0004000000000000 s9 : ffffffff80dc1d80 s10: ffffffd8807e4000 s11: 0000000000000000 t3 : 00000000000000ff t4 : 393044410a303930 t5 : 0000000000001000 t6 : 0000000000040000 status: 0000000200000120 badaddr: 0000000000001008 cause: 000000000000000f [] parport_pc_compat_write_block_pio+0xfe/0x200 [] parport_write+0x46/0xf8 [] lp_write+0x158/0x2d2 [] vfs_write+0x8e/0x2c2 [] ksys_write+0x52/0xc2 [] sys_write+0xe/0x16 [] ret_from_syscall+0x0/0x2 ---[ end trace 0000000000000000 ]--- For simplicity address the problem by adding PCI_IOBASE to the physical address requested in the respective wrapper macros only, observing that the raw accessors such as `__insb', `__outsb', etc. are not supposed to be used other than by said macros. Remove the cast to `long' that is no longer needed on `addr' now that it is used as an offset from PCI_IOBASE and add parentheses around `addr' needed for predictable evaluation in macro expansion. No need to make said adjustments in separate changes given that current code is gravely broken and does not ever work. Signed-off-by: Maciej W. Rozycki Fixes: fab957c11efe2 ("RISC-V: Atomic and Locking Code") Cc: stable@vger.kernel.org # v4.15+ Reviewed-by: Arnd Bergmann Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209220223080.29493@angie.orcam.me.uk Signed-off-by: Palmer Dabbelt Signed-off-by: Greg Kroah-Hartman --- arch/riscv/include/asm/io.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index 69605a474270..92080a227937 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -101,9 +101,9 @@ __io_reads_ins(reads, u32, l, __io_br(), __io_ar(addr)) __io_reads_ins(ins, u8, b, __io_pbr(), __io_par(addr)) __io_reads_ins(ins, u16, w, __io_pbr(), __io_par(addr)) __io_reads_ins(ins, u32, l, __io_pbr(), __io_par(addr)) -#define insb(addr, buffer, count) __insb((void __iomem *)(long)addr, buffer, count) -#define insw(addr, buffer, count) __insw((void __iomem *)(long)addr, buffer, count) -#define insl(addr, buffer, count) __insl((void __iomem *)(long)addr, buffer, count) +#define insb(addr, buffer, count) __insb(PCI_IOBASE + (addr), buffer, count) +#define insw(addr, buffer, count) __insw(PCI_IOBASE + (addr), buffer, count) +#define insl(addr, buffer, count) __insl(PCI_IOBASE + (addr), buffer, count) __io_writes_outs(writes, u8, b, __io_bw(), __io_aw()) __io_writes_outs(writes, u16, w, __io_bw(), __io_aw()) @@ -115,22 +115,22 @@ __io_writes_outs(writes, u32, l, __io_bw(), __io_aw()) __io_writes_outs(outs, u8, b, __io_pbw(), __io_paw()) __io_writes_outs(outs, u16, w, __io_pbw(), __io_paw()) __io_writes_outs(outs, u32, l, __io_pbw(), __io_paw()) -#define outsb(addr, buffer, count) __outsb((void __iomem *)(long)addr, buffer, count) -#define outsw(addr, buffer, count) __outsw((void __iomem *)(long)addr, buffer, count) -#define outsl(addr, buffer, count) __outsl((void __iomem *)(long)addr, buffer, count) +#define outsb(addr, buffer, count) __outsb(PCI_IOBASE + (addr), buffer, count) +#define outsw(addr, buffer, count) __outsw(PCI_IOBASE + (addr), buffer, count) +#define outsl(addr, buffer, count) __outsl(PCI_IOBASE + (addr), buffer, count) #ifdef CONFIG_64BIT __io_reads_ins(reads, u64, q, __io_br(), __io_ar(addr)) #define readsq(addr, buffer, count) __readsq(addr, buffer, count) __io_reads_ins(ins, u64, q, __io_pbr(), __io_par(addr)) -#define insq(addr, buffer, count) __insq((void __iomem *)addr, buffer, count) +#define insq(addr, buffer, count) __insq(PCI_IOBASE + (addr), buffer, count) __io_writes_outs(writes, u64, q, __io_bw(), __io_aw()) #define writesq(addr, buffer, count) __writesq(addr, buffer, count) __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw()) -#define outsq(addr, buffer, count) __outsq((void __iomem *)addr, buffer, count) +#define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count) #endif #include From af3aaee08df8127422e03e5e1291f91cbb5d4f09 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 14 Oct 2022 10:13:55 +0200 Subject: [PATCH 041/610] parisc: fbdev/stifb: Align graphics memory size to 4MB commit aca7c13d3bee81a968337a5515411409ae9d095d upstream. Independend of the current graphics resolution, adjust the reported graphics card memory size to the next 4MB boundary. This fixes the fbtest program which expects a naturally aligned size. Signed-off-by: Helge Deller Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/stifb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index 002f265d8db5..b0470f4f595e 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -1257,7 +1257,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) /* limit fbsize to max visible screen size */ if (fix->smem_len > yres*fix->line_length) - fix->smem_len = yres*fix->line_length; + fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024); fix->accel = FB_ACCEL_NONE; From 3c3c4fa118a44d554c2eafd56bb99a529720234c Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 15 Sep 2022 15:37:02 -0400 Subject: [PATCH 042/610] riscv: Allow PROT_WRITE-only mmap() commit 9e2e6042a7ec6504fe8e366717afa2f40cf16488 upstream. Commit 2139619bcad7 ("riscv: mmap with PROT_WRITE but no PROT_READ is invalid") made mmap() return EINVAL if PROT_WRITE was set wihtout PROT_READ with the justification that a write-only PTE is considered a reserved PTE permission bit pattern in the privileged spec. This check is unnecessary since we let VM_WRITE imply VM_READ on RISC-V, and it is inconsistent with other architectures that don't support write-only PTEs, creating a potential software portability issue. Just remove the check altogether and let PROT_WRITE imply PROT_READ as is the case on other architectures. Note that this also allows PROT_WRITE|PROT_EXEC mappings which were disallowed prior to the aforementioned commit; PROT_READ is implied in such mappings as well. Fixes: 2139619bcad7 ("riscv: mmap with PROT_WRITE but no PROT_READ is invalid") Reviewed-by: Atish Patra Signed-off-by: Andrew Bresticker Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220915193702.2201018-3-abrestic@rivosinc.com/ Signed-off-by: Palmer Dabbelt Signed-off-by: Greg Kroah-Hartman --- arch/riscv/kernel/sys_riscv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c index 8a7880b9c433..bb402685057a 100644 --- a/arch/riscv/kernel/sys_riscv.c +++ b/arch/riscv/kernel/sys_riscv.c @@ -18,9 +18,6 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) return -EINVAL; - if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ))) - return -EINVAL; - return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - page_shift_offset)); } From c657b70e80745d969ad88de5981ba4e595a52a4e Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Thu, 15 Sep 2022 15:37:01 -0400 Subject: [PATCH 043/610] riscv: Make VM_WRITE imply VM_READ commit 7ab72c597356be1e7f0f3d856e54ce78527f43c8 upstream. RISC-V does not presently have write-only mappings as that PTE bit pattern is considered reserved in the privileged spec, so allow handling of read faults in VMAs that have VM_WRITE without VM_READ in order to be consistent with other architectures that have similar limitations. Fixes: 2139619bcad7 ("riscv: mmap with PROT_WRITE but no PROT_READ is invalid") Reviewed-by: Atish Patra Signed-off-by: Andrew Bresticker Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220915193702.2201018-2-abrestic@rivosinc.com/ Signed-off-by: Palmer Dabbelt Signed-off-by: Greg Kroah-Hartman --- arch/riscv/mm/fault.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index aa08dd2f8fae..7cfaf366463f 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -188,7 +188,8 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) } break; case EXC_LOAD_PAGE_FAULT: - if (!(vma->vm_flags & VM_READ)) { + /* Write implies read */ + if (!(vma->vm_flags & (VM_READ | VM_WRITE))) { return true; } break; From 7780bb02a06970f8304c652859b6736ea79853f9 Mon Sep 17 00:00:00 2001 From: Wenting Zhang Date: Fri, 8 Jul 2022 16:38:22 -0400 Subject: [PATCH 044/610] riscv: always honor the CONFIG_CMDLINE_FORCE when parsing dtb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 10f6913c548b32ecb73801a16b120e761c6957ea upstream. When CONFIG_CMDLINE_FORCE is enabled, cmdline provided by CONFIG_CMDLINE are always used. This allows CONFIG_CMDLINE to be used regardless of the result of device tree scanning. This especially fixes the case where a device tree without the chosen node is supplied to the kernel. In such cases, early_init_dt_scan would return true. But inside early_init_dt_scan_chosen, the cmdline won't be updated as there is no chosen node in the device tree. As a result, CONFIG_CMDLINE is not copied into boot_command_line even if CONFIG_CMDLINE_FORCE is enabled. This commit allows properly update boot_command_line in this situation. Fixes: 8fd6e05c7463 ("arch: riscv: support kernel command line forcing when no DTB passed") Signed-off-by: Wenting Zhang Reviewed-by: Björn Töpel Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/PSBPR04MB399135DFC54928AB958D0638B1829@PSBPR04MB3991.apcprd04.prod.outlook.com Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Greg Kroah-Hartman --- arch/riscv/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 50c089730e57..7bdbf3f608a4 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -260,10 +260,10 @@ static void __init parse_dtb(void) pr_info("Machine model: %s\n", name); dump_stack_set_arch_desc("%s (DT)", name); } - return; + } else { + pr_err("No DTB passed to the kernel\n"); } - pr_err("No DTB passed to the kernel\n"); #ifdef CONFIG_CMDLINE_FORCE strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); pr_info("Forcing kernel command line to: %s\n", boot_command_line); From 81ab826a285df3d0252b0b36142a17e98d132f8d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 18 Sep 2022 02:29:34 -0700 Subject: [PATCH 045/610] riscv: Pass -mno-relax only on lld < 15.0.0 commit 3cebf80e9a0d3adcb174053be32c88a640b3344b upstream. lld since llvm:6611d58f5bbc ("[ELF] Relax R_RISCV_ALIGN"), which will be included in the 15.0.0 release, has implemented some RISC-V linker relaxation. -mno-relax is no longer needed in KBUILD_CFLAGS/KBUILD_AFLAGS to suppress R_RISCV_ALIGN which older lld can not handle: ld.lld: error: capability.c:(.fixup+0x0): relocation R_RISCV_ALIGN requires unimplemented linker relaxation; recompile with -mno-relax but the .o is already compiled with -mno-relax Signed-off-by: Fangrui Song Link: https://lore.kernel.org/r/20220710071117.446112-1-maskray@google.com/ Link: https://lore.kernel.org/r/20220918092933.19943-1-palmer@rivosinc.com Reviewed-by: Nick Desaulniers Tested-by: Nick Desaulniers Tested-by: Nathan Chancellor Tested-by: Conor Dooley Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Greg Kroah-Hartman --- arch/riscv/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 583e1ff0c0bf..dc77857ca27d 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -39,6 +39,7 @@ else endif ifeq ($(CONFIG_LD_IS_LLD),y) +ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0) KBUILD_CFLAGS += -mno-relax KBUILD_AFLAGS += -mno-relax ifndef CONFIG_AS_IS_LLVM @@ -46,6 +47,7 @@ ifndef CONFIG_AS_IS_LLVM KBUILD_AFLAGS += -Wa,-mno-relax endif endif +endif # ISA string setting riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima From 7efe61dc6aa45aab8a40e304fa2dae21e33b0db4 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 12 Jul 2022 15:52:55 +0800 Subject: [PATCH 046/610] UM: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK commit 16c546e148fa6d14a019431436a6f7b4087dbccd upstream. When CONFIG_CPUMASK_OFFSTACK and CONFIG_DEBUG_PER_CPU_MAPS is selected, cpu_max_bits_warn() generates a runtime warning similar as below while we show /proc/cpuinfo. Fix this by using nr_cpu_ids (the runtime limit) instead of NR_CPUS to iterate CPUs. [ 3.052463] ------------[ cut here ]------------ [ 3.059679] WARNING: CPU: 3 PID: 1 at include/linux/cpumask.h:108 show_cpuinfo+0x5e8/0x5f0 [ 3.070072] Modules linked in: efivarfs autofs4 [ 3.076257] CPU: 0 PID: 1 Comm: systemd Not tainted 5.19-rc5+ #1052 [ 3.099465] Stack : 9000000100157b08 9000000000f18530 9000000000cf846c 9000000100154000 [ 3.109127] 9000000100157a50 0000000000000000 9000000100157a58 9000000000ef7430 [ 3.118774] 90000001001578e8 0000000000000040 0000000000000020 ffffffffffffffff [ 3.128412] 0000000000aaaaaa 1ab25f00eec96a37 900000010021de80 900000000101c890 [ 3.138056] 0000000000000000 0000000000000000 0000000000000000 0000000000aaaaaa [ 3.147711] ffff8000339dc220 0000000000000001 0000000006ab4000 0000000000000000 [ 3.157364] 900000000101c998 0000000000000004 9000000000ef7430 0000000000000000 [ 3.167012] 0000000000000009 000000000000006c 0000000000000000 0000000000000000 [ 3.176641] 9000000000d3de08 9000000001639390 90000000002086d8 00007ffff0080286 [ 3.186260] 00000000000000b0 0000000000000004 0000000000000000 0000000000071c1c [ 3.195868] ... [ 3.199917] Call Trace: [ 3.203941] [<90000000002086d8>] show_stack+0x38/0x14c [ 3.210666] [<9000000000cf846c>] dump_stack_lvl+0x60/0x88 [ 3.217625] [<900000000023d268>] __warn+0xd0/0x100 [ 3.223958] [<9000000000cf3c90>] warn_slowpath_fmt+0x7c/0xcc [ 3.231150] [<9000000000210220>] show_cpuinfo+0x5e8/0x5f0 [ 3.238080] [<90000000004f578c>] seq_read_iter+0x354/0x4b4 [ 3.245098] [<90000000004c2e90>] new_sync_read+0x17c/0x1c4 [ 3.252114] [<90000000004c5174>] vfs_read+0x138/0x1d0 [ 3.258694] [<90000000004c55f8>] ksys_read+0x70/0x100 [ 3.265265] [<9000000000cfde9c>] do_syscall+0x7c/0x94 [ 3.271820] [<9000000000202fe4>] handle_syscall+0xc4/0x160 [ 3.281824] ---[ end trace 8b484262b4b8c24c ]--- Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- arch/um/kernel/um_arch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8dc7ab1f3cd4..4c8d2dc27084 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -94,7 +94,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < NR_CPUS ? cpu_data + *pos : NULL; + return *pos < nr_cpu_ids ? cpu_data + *pos : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) From 9391cc3a787a58aa224a6440d7f244d780ba2896 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Fri, 16 Sep 2022 13:04:02 +0100 Subject: [PATCH 047/610] nvmem: core: Fix memleak in nvmem_register() commit bd1244561fa2a4531ded40dbf09c9599084f8b29 upstream. dev_set_name will alloc memory for nvmem->dev.kobj.name in nvmem_register, when nvmem_validate_keepouts failed, nvmem's memory will be freed and return, but nobody will free memory for nvmem->dev.kobj.name, there will be memleak, so moving nvmem_validate_keepouts() after device_register() and let the device core deal with cleaning name in error cases. Fixes: de0534df9347 ("nvmem: core: fix error handling while validating keepout regions") Cc: stable@vger.kernel.org Signed-off-by: Gaosheng Cui Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220916120402.38753-1-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/core.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index fb7840c73765..38bab84f3c8a 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -824,21 +824,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->dev.groups = nvmem_dev_groups; #endif - if (nvmem->nkeepout) { - rval = nvmem_validate_keepouts(nvmem); - if (rval) { - ida_free(&nvmem_ida, nvmem->id); - kfree(nvmem); - return ERR_PTR(rval); - } - } - dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); rval = device_register(&nvmem->dev); if (rval) goto err_put_device; + if (nvmem->nkeepout) { + rval = nvmem_validate_keepouts(nvmem); + if (rval) + goto err_device_del; + } + if (config->compat) { rval = nvmem_sysfs_setup_compat(nvmem, config); if (rval) From 32aa0b3f0c06451cbedb00c268c836e441446d22 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Thu, 29 Sep 2022 10:36:47 +0300 Subject: [PATCH 048/610] nvme-multipath: fix possible hang in live ns resize with ANA access commit 72e3b8883a36e80ebfa41015c7b6926ce31ace05 upstream. When we revalidate paths as part of ns size change (as of commit e7d65803e2bb), it is possible that during the path revalidation, the only paths that is IO capable (i.e. optimized/non-optimized) are the ones that ns resize was not yet informed to the host, which will cause inflight requests to be requeued (as we have available paths but none are IO capable). These requests on the requeue list are waiting for someone to resubmit them at some point. The IO capable paths will eventually notify the ns resize change to the host, but there is nothing that will kick the requeue list to resubmit the queued requests. Fix this by always kicking the requeue list, and if no IO capable path exists, these requests will be queued again. A typical log that indicates that IOs are requeued: -- nvme nvme1: creating 4 I/O queues. nvme nvme1: new ctrl: "testnqn1" nvme nvme2: creating 4 I/O queues. nvme nvme2: mapped 4/0/0 default/read/poll queues. nvme nvme2: new ctrl: NQN "testnqn1", addr 127.0.0.1:8009 nvme nvme1: rescanning namespaces. nvme1n1: detected capacity change from 2097152 to 4194304 block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O block nvme1n1: no usable path - requeuing I/O nvme nvme2: rescanning namespaces. -- Reported-by: Yogev Cohen Fixes: e7d65803e2bb ("nvme-multipath: revalidate paths during rescan") Signed-off-by: Sagi Grimberg Cc: # v5.15+ Signed-off-by: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/multipath.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 04fa276701d1..36b48e2ff642 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -159,6 +159,7 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns) for_each_node(node) rcu_assign_pointer(head->current_path[node], NULL); + kblockd_schedule_work(&head->requeue_work); } static bool nvme_path_is_disabled(struct nvme_ns *ns) From 4bdedc3b53417a86eb6d736e3331c845901e80b0 Mon Sep 17 00:00:00 2001 From: Rishabh Bhatnagar Date: Tue, 20 Sep 2022 19:19:32 +0000 Subject: [PATCH 049/610] nvme-pci: set min_align_mask before calculating max_hw_sectors commit 61ce339f19fabbc3e51237148a7ef6f2270e44fa upstream. If swiotlb is force enabled dma_max_mapping_size ends up calling swiotlb_max_mapping_size which takes into account the min align mask for the device. Set the min align mask for nvme driver before calling dma_max_mapping_size while calculating max hw sectors. Signed-off-by: Rishabh Bhatnagar Signed-off-by: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index d820131d39b2..e9f3701dda3f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2732,6 +2732,8 @@ static void nvme_reset_work(struct work_struct *work) if (result) goto out_unlock; + dma_set_min_align_mask(dev->dev, NVME_CTRL_PAGE_SIZE - 1); + /* * Limit the max command size to prevent iod->sg allocations going * over a single page. @@ -2744,7 +2746,6 @@ static void nvme_reset_work(struct work_struct *work) * Don't limit the IOMMU merged segment size. */ dma_set_max_seg_size(dev->dev, 0xffffffff); - dma_set_min_align_mask(dev->dev, NVME_CTRL_PAGE_SIZE - 1); mutex_unlock(&dev->shutdown_lock); From e7a3334e83f969e63997f738e2c688c6363f1a1f Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Wed, 5 Oct 2022 11:30:38 -0400 Subject: [PATCH 050/610] Revert "drm/amdgpu: use dirty framebuffer helper" commit 17d819e2828cacca2e4c909044eb9798ed379cd2 upstream. This reverts commit 66f99628eb24409cb8feb5061f78283c8b65f820. Unfortunately, that commit causes performance regressions on non-PSR setups. So, just revert it until FB_DAMAGE_CLIPS support can be added. Cc: stable@vger.kernel.org Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2189 Link: https://bugzilla.kernel.org/show_bug.cgi?id=216554 Fixes: 66f99628eb2440 ("drm/amdgpu: use dirty framebuffer helper") Fixes: abbc7a3dafb91b ("drm/amdgpu: don't register a dirty callback for non-atomic") Signed-off-by: Hamza Mahfooz Acked-by: Alex Deucher Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index d3d2c214554e..d2286a83e302 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -35,8 +35,6 @@ #include #include #include -#include -#include #include #include #include @@ -494,12 +492,6 @@ static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { .create_handle = drm_gem_fb_create_handle, }; -static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = { - .destroy = drm_gem_fb_destroy, - .create_handle = drm_gem_fb_create_handle, - .dirty = drm_atomic_helper_dirtyfb, -}; - uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, uint64_t bo_flags) { @@ -1117,10 +1109,8 @@ int amdgpu_display_gem_fb_verify_and_init( if (ret) goto err; - if (drm_drv_uses_atomic_modeset(dev)) - ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs_atomic); - else - ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); + ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); + if (ret) goto err; From a95fb5d55af0bf7efcfe6818a5fef37d21d86d9d Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Wed, 21 Sep 2022 19:05:56 +0200 Subject: [PATCH 051/610] dmaengine: mxs: use platform_driver_register commit 26696d4657167112a1079f86cba1739765c1360e upstream. Driver registration fails on SOC imx8mn as its supplier, the clock control module, is probed later than subsys initcall level. This driver uses platform_driver_probe which is not compatible with deferred probing and won't be probed again later if probe function fails due to clock not being available at that time. This patch replaces the use of platform_driver_probe with platform_driver_register which will allow probing the driver later again when the clock control module will be available. The __init annotation has been dropped because it is not compatible with deferred probing. The code is not executed once and its memory cannot be freed. Fixes: a580b8c5429a ("dmaengine: mxs-dma: add dma support for i.MX23/28") Co-developed-by: Michael Trimarchi Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi Acked-by: Sascha Hauer Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20220921170556.1055962-1-dario.binacchi@amarulasolutions.com Signed-off-by: Vinod Koul --- drivers/dma/mxs-dma.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index 994fc4d2aca4..dc147cc2436e 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c @@ -670,7 +670,7 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan, return mxs_chan->status; } -static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma) +static int mxs_dma_init(struct mxs_dma_engine *mxs_dma) { int ret; @@ -741,7 +741,7 @@ static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec, ofdma->of_node); } -static int __init mxs_dma_probe(struct platform_device *pdev) +static int mxs_dma_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; const struct mxs_dma_type *dma_type; @@ -839,10 +839,7 @@ static struct platform_driver mxs_dma_driver = { .name = "mxs-dma", .of_match_table = mxs_dma_dt_ids, }, + .probe = mxs_dma_probe, }; -static int __init mxs_dma_module_init(void) -{ - return platform_driver_probe(&mxs_dma_driver, mxs_dma_probe); -} -subsys_initcall(mxs_dma_module_init); +builtin_platform_driver(mxs_dma_driver); From f122bcb34f1a4b02ef3d95058d8fd1316ea03785 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 30 Jun 2022 23:07:19 +0300 Subject: [PATCH 052/610] drm/virtio: Check whether transferred 2D BO is shmem commit e473216b42aa1fd9fc6b94b608b42c210c655908 upstream. Transferred 2D BO always must be a shmem BO. Add check for that to prevent NULL dereference if userspace passes a VRAM BO. Cc: stable@vger.kernel.org Reviewed-by: Emil Velikov Signed-off-by: Dmitry Osipenko Link: http://patchwork.freedesktop.org/patch/msgid/20220630200726.1884320-3-dmitry.osipenko@collabora.com Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/virtio/virtgpu_vq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 93a41d018dca..19a196b48a38 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -604,7 +604,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev); struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo); - if (use_dma_api) + if (virtio_gpu_is_shmem(bo) && use_dma_api) dma_sync_sgtable_for_device(vgdev->vdev->dev.parent, shmem->pages, DMA_TO_DEVICE); From fb3910436be47219f7ca35a72d8fcc6b79d76d89 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 30 Jun 2022 23:07:20 +0300 Subject: [PATCH 053/610] drm/virtio: Unlock reservations on virtio_gpu_object_shmem_init() error commit fdf0ff4d12cbcd76b53f27c96ce51ddca400884a upstream. Unlock reservations in the error code path of virtio_gpu_object_create() to silence debug warning splat produced by ww_mutex_destroy(&obj->lock) when GEM is released with the held lock. Cc: stable@vger.kernel.org Fixes: 30172efbfb84 ("drm/virtio: blob prep: refactor getting pages and attaching backing") Reviewed-by: Emil Velikov Signed-off-by: Dmitry Osipenko Link: http://patchwork.freedesktop.org/patch/msgid/20220630200726.1884320-4-dmitry.osipenko@collabora.com Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/virtio/virtgpu_object.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 9af9f355e0a7..248ecd3006c3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -247,6 +247,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents); if (ret != 0) { + if (fence) + virtio_gpu_array_unlock_resv(objs); virtio_gpu_array_put_free(objs); virtio_gpu_free_object(&shmem_obj->base); return ret; From 06409347252458ad535135d422ad0f2859af7ece Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 30 Jun 2022 23:07:22 +0300 Subject: [PATCH 054/610] drm/virtio: Use appropriate atomic state in virtio_gpu_plane_cleanup_fb() commit 4656b3a26a9e9fe5f04bfd2ab55b066266ba7f4d upstream. Make virtio_gpu_plane_cleanup_fb() to clean the state which DRM core wants to clean up and not the current plane's state. Normally the older atomic state is cleaned up, but the newer state could also be cleaned up in case of aborted commits. Cc: stable@vger.kernel.org Signed-off-by: Dmitry Osipenko Link: http://patchwork.freedesktop.org/patch/msgid/20220630200726.1884320-6-dmitry.osipenko@collabora.com Signed-off-by: Gerd Hoffmann Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/virtio/virtgpu_plane.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index a49fd9480381..7e8cbcee1722 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -265,14 +265,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane, } static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_plane_state *state) { struct virtio_gpu_framebuffer *vgfb; - if (!plane->state->fb) + if (!state->fb) return; - vgfb = to_virtio_gpu_framebuffer(plane->state->fb); + vgfb = to_virtio_gpu_framebuffer(state->fb); if (vgfb->fence) { dma_fence_put(&vgfb->fence->f); vgfb->fence = NULL; From fc0f921b7e6efff34f31df8ccd4de5ee27078841 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 8 Sep 2022 11:51:04 +0200 Subject: [PATCH 055/610] drm/udl: Restore display mode on resume commit 6d6e732835db92e66c28dbcf258a7e3d3c71420d upstream. Restore the display mode whne resuming from suspend. Currently, the display remains dark. On resume, the CRTC's mode does not change, but the 'active' flag changes to 'true'. Taking this into account when considering a mode switch restores the display mode. The bug is reproducable by using Gnome with udl and observing the adapter's suspend/resume behavior. Actually, the whole check added in udl_simple_display_pipe_enable() about the crtc_state->mode_changed was bogus. We should drop the whole check and always apply the mode change in this function. [ tiwai -- Drop the mode_changed check entirely instead, per Daniel's suggestion ] Fixes: 997d33c35618 ("drm/udl: Inline DPMS code into CRTC enable and disable functions") Cc: Suggested-by: Daniel Vetter Reviewed-by: Daniel Vetter Signed-off-by: Takashi Iwai Signed-off-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20220908095115.23396-2-tiwai@suse.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/udl/udl_modeset.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 32232228dae9..50753d83fbdd 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -381,9 +381,6 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, udl_handle_damage(fb, &shadow_plane_state->data[0], 0, 0, fb->width, fb->height); - if (!crtc_state->mode_changed) - return; - /* enable display */ udl_crtc_write_mode_to_hw(crtc); } From 91c4eb16e804c3cfb6efcaca602556e62cb025a1 Mon Sep 17 00:00:00 2001 From: James Morse Date: Fri, 30 Sep 2022 14:19:59 +0100 Subject: [PATCH 056/610] arm64: errata: Add Cortex-A55 to the repeat tlbi list commit 171df58028bf4649460fb146a56a58dcb0c8f75a upstream. Cortex-A55 is affected by an erratum where in rare circumstances the CPUs may not handle a race between a break-before-make sequence on one CPU, and another CPU accessing the same page. This could allow a store to a page that has been unmapped. Work around this by adding the affected CPUs to the list that needs TLB sequences to be done twice. Signed-off-by: James Morse Cc: Link: https://lore.kernel.org/r/20220930131959.3082594-1-james.morse@arm.com Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman --- Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 17 +++++++++++++++++ arch/arm64/kernel/cpu_errata.c | 5 +++++ 3 files changed, 24 insertions(+) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 663001f69773..21715d1e538d 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -68,6 +68,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A55 | #1530923 | ARM64_ERRATUM_1530923 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A55 | #2441007 | ARM64_ERRATUM_2441007 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A57 | #832075 | ARM64_ERRATUM_832075 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A57 | #852523 | N/A | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 24cce3b9ff1a..1e5a03d51d46 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -596,6 +596,23 @@ config ARM64_ERRATUM_1530923 config ARM64_WORKAROUND_REPEAT_TLBI bool +config ARM64_ERRATUM_2441007 + bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI" + default y + select ARM64_WORKAROUND_REPEAT_TLBI + help + This option adds a workaround for ARM Cortex-A55 erratum #2441007. + + Under very rare circumstances, affected Cortex-A55 CPUs + may not handle a race between a break-before-make sequence on one + CPU, and another CPU accessing the same page. This could allow a + store to a page that has been unmapped. + + Work around this by adding the affected CPUs to the list that needs + TLB sequences to be done twice. + + If unsure, say Y. + config ARM64_ERRATUM_1286807 bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation" default y diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 25c495f58f67..a3a9b1537329 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -214,6 +214,11 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = { ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe), }, #endif +#ifdef CONFIG_ARM64_ERRATUM_2441007 + { + ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), + }, +#endif #ifdef CONFIG_ARM64_ERRATUM_2441009 { /* Cortex-A510 r0p0 -> r1p1. Fixed in r1p2 */ From 2b0072d33eb69f950d1fac620db49259968346a6 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 18 Aug 2022 15:37:43 +0800 Subject: [PATCH 057/610] mm/damon: validate if the pmd entry is present before accessing commit c8b9aff419303e4d4219b5ff64b1c7e062dee48e upstream. pmd_huge() is used to validate if the pmd entry is mapped by a huge page, also including the case of non-present (migration or hwpoisoned) pmd entry on arm64 or x86 architectures. This means that pmd_pfn() can not get the correct pfn number for a non-present pmd entry, which will cause damon_get_page() to get an incorrect page struct (also may be NULL by pfn_to_online_page()), making the access statistics incorrect. This means that the DAMON may make incorrect decision according to the incorrect statistics, for example, DAMON may can not reclaim cold page in time due to this cold page was regarded as accessed mistakenly if DAMOS_PAGEOUT operation is specified. Moreover it does not make sense that we still waste time to get the page of the non-present entry. Just treat it as not-accessed and skip it, which maintains consistency with non-present pte level entries. So add pmd entry present validation to fix the above issues. Link: https://lkml.kernel.org/r/58b1d1f5fbda7db49ca886d9ef6783e3dcbbbc98.1660805030.git.baolin.wang@linux.alibaba.com Fixes: 3f49584b262c ("mm/damon: implement primitives for the virtual memory address spaces") Signed-off-by: Baolin Wang Reviewed-by: SeongJae Park Reviewed-by: Muchun Song Cc: Mike Kravetz Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/damon/vaddr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c index 58c1fb2aafa9..1945196fd743 100644 --- a/mm/damon/vaddr.c +++ b/mm/damon/vaddr.c @@ -456,6 +456,11 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr, if (pmd_huge(*pmd)) { ptl = pmd_lock(walk->mm, pmd); + if (!pmd_present(*pmd)) { + spin_unlock(ptl); + return 0; + } + if (pmd_huge(*pmd)) { damon_pmdp_mkold(pmd, walk->mm, addr); spin_unlock(ptl); @@ -530,6 +535,11 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr, #ifdef CONFIG_TRANSPARENT_HUGEPAGE if (pmd_huge(*pmd)) { ptl = pmd_lock(walk->mm, pmd); + if (!pmd_present(*pmd)) { + spin_unlock(ptl); + return 0; + } + if (!pmd_huge(*pmd)) { spin_unlock(ptl); goto regular_page; From 43bed0a13a5cdbb314d14f28c2bf2c60eb4e6e1e Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Fri, 30 Sep 2022 00:38:43 +0000 Subject: [PATCH 058/610] mm/mmap: undo ->mmap() when arch_validate_flags() fails commit deb0f6562884b5b4beb883d73e66a7d3a1b96d99 upstream. Commit c462ac288f2c ("mm: Introduce arch_validate_flags()") added a late check in mmap_region() to let architectures validate vm_flags. The check needs to happen after calling ->mmap() as the flags can potentially be modified during this callback. If arch_validate_flags() check fails we unmap and free the vma. However, the error path fails to undo the ->mmap() call that previously succeeded and depending on the specific ->mmap() implementation this translates to reference increments, memory allocations and other operations what will not be cleaned up. There are several places (mainly device drivers) where this is an issue. However, one specific example is bpf_map_mmap() which keeps count of the mappings in map->writecnt. The count is incremented on ->mmap() and then decremented on vm_ops->close(). When arch_validate_flags() fails this count is off since bpf_map_mmap_close() is never called. One can reproduce this issue in arm64 devices with MTE support. Here the vm_flags are checked to only allow VM_MTE if VM_MTE_ALLOWED has been set previously. From userspace then is enough to pass the PROT_MTE flag to mmap() syscall to trigger the arch_validate_flags() failure. The following program reproduces this issue: #include #include #include #include #include int main(void) { union bpf_attr attr = { .map_type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), .value_size = sizeof(long long), .max_entries = 256, .map_flags = BPF_F_MMAPABLE, }; int fd; fd = syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); mmap(NULL, 4096, PROT_WRITE | PROT_MTE, MAP_SHARED, fd, 0); return 0; } By manually adding some log statements to the vm_ops callbacks we can confirm that when passing PROT_MTE to mmap() the map->writecnt is off upon ->release(): With PROT_MTE flag: root@debian:~# ./bpf-test [ 111.263874] bpf_map_write_active_inc: map=9 writecnt=1 [ 111.288763] bpf_map_release: map=9 writecnt=1 Without PROT_MTE flag: root@debian:~# ./bpf-test [ 157.816912] bpf_map_write_active_inc: map=10 writecnt=1 [ 157.830442] bpf_map_write_active_dec: map=10 writecnt=0 [ 157.832396] bpf_map_release: map=10 writecnt=0 This patch fixes the above issue by calling vm_ops->close() when the arch_validate_flags() check fails, after this we can proceed to unmap and free the vma on the error path. Link: https://lkml.kernel.org/r/20220930003844.1210987-1-cmllamas@google.com Fixes: c462ac288f2c ("mm: Introduce arch_validate_flags()") Signed-off-by: Carlos Llamas Reviewed-by: Catalin Marinas Acked-by: Andrii Nakryiko Reviewed-by: Liam Howlett Cc: Christian Brauner (Microsoft) Cc: Michal Hocko Cc: Suren Baghdasaryan Cc: [5.10+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/mmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/mmap.c b/mm/mmap.c index 5c2c7651ca29..a0a4eadc8779 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1836,7 +1836,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (!arch_validate_flags(vma->vm_flags)) { error = -EINVAL; if (file) - goto unmap_and_free_vma; + goto close_and_free_vma; else goto free_vma; } @@ -1876,6 +1876,9 @@ out: return addr; +close_and_free_vma: + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); unmap_and_free_vma: fput(vma->vm_file); vma->vm_file = NULL; From 1cb73704cb4778299609634a790a80daba582f7d Mon Sep 17 00:00:00 2001 From: "M. Vefa Bicakci" Date: Sun, 2 Oct 2022 18:20:05 -0400 Subject: [PATCH 059/610] xen/gntdev: Prevent leaking grants commit 0991028cd49567d7016d1b224fe0117c35059f86 upstream. Prior to this commit, if a grant mapping operation failed partially, some of the entries in the map_ops array would be invalid, whereas all of the entries in the kmap_ops array would be valid. This in turn would cause the following logic in gntdev_map_grant_pages to become invalid: for (i = 0; i < map->count; i++) { if (map->map_ops[i].status == GNTST_okay) { map->unmap_ops[i].handle = map->map_ops[i].handle; if (!use_ptemod) alloced++; } if (use_ptemod) { if (map->kmap_ops[i].status == GNTST_okay) { if (map->map_ops[i].status == GNTST_okay) alloced++; map->kunmap_ops[i].handle = map->kmap_ops[i].handle; } } } ... atomic_add(alloced, &map->live_grants); Assume that use_ptemod is true (i.e., the domain mapping the granted pages is a paravirtualized domain). In the code excerpt above, note that the "alloced" variable is only incremented when both kmap_ops[i].status and map_ops[i].status are set to GNTST_okay (i.e., both mapping operations are successful). However, as also noted above, there are cases where a grant mapping operation fails partially, breaking the assumption of the code excerpt above. The aforementioned causes map->live_grants to be incorrectly set. In some cases, all of the map_ops mappings fail, but all of the kmap_ops mappings succeed, meaning that live_grants may remain zero. This in turn makes it impossible to unmap the successfully grant-mapped pages pointed to by kmap_ops, because unmap_grant_pages has the following snippet of code at its beginning: if (atomic_read(&map->live_grants) == 0) return; /* Nothing to do */ In other cases where only some of the map_ops mappings fail but all kmap_ops mappings succeed, live_grants is made positive, but when the user requests unmapping the grant-mapped pages, __unmap_grant_pages_done will then make map->live_grants negative, because the latter function does not check if all of the pages that were requested to be unmapped were actually unmapped, and the same function unconditionally subtracts "data->count" (i.e., a value that can be greater than map->live_grants) from map->live_grants. The side effects of a negative live_grants value have not been studied. The net effect of all of this is that grant references are leaked in one of the above conditions. In Qubes OS v4.1 (which uses Xen's grant mechanism extensively for X11 GUI isolation), this issue manifests itself with warning messages like the following to be printed out by the Linux kernel in the VM that had granted pages (that contain X11 GUI window data) to dom0: "g.e. 0x1234 still pending", especially after the user rapidly resizes GUI VM windows (causing some grant-mapping operations to partially or completely fail, due to the fact that the VM unshares some of the pages as part of the window resizing, making the pages impossible to grant-map from dom0). The fix for this issue involves counting all successful map_ops and kmap_ops mappings separately, and then adding the sum to live_grants. During unmapping, only the number of successfully unmapped grants is subtracted from live_grants. The code is also modified to check for negative live_grants values after the subtraction and warn the user. Link: https://github.com/QubesOS/qubes-issues/issues/7631 Fixes: dbe97cff7dd9 ("xen/gntdev: Avoid blocking in unmap_grant_pages()") Cc: stable@vger.kernel.org Signed-off-by: M. Vefa Bicakci Acked-by: Demi Marie Obenour Reviewed-by: Juergen Gross Link: https://lore.kernel.org/r/20221002222006.2077-2-m.v.b@runbox.com Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- drivers/xen/gntdev.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 84b143eef395..eb0586b9767d 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -367,8 +367,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) for (i = 0; i < map->count; i++) { if (map->map_ops[i].status == GNTST_okay) { map->unmap_ops[i].handle = map->map_ops[i].handle; - if (!use_ptemod) - alloced++; + alloced++; } else if (!err) err = -EINVAL; @@ -377,8 +376,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map) if (use_ptemod) { if (map->kmap_ops[i].status == GNTST_okay) { - if (map->map_ops[i].status == GNTST_okay) - alloced++; + alloced++; map->kunmap_ops[i].handle = map->kmap_ops[i].handle; } else if (!err) err = -EINVAL; @@ -394,8 +392,14 @@ static void __unmap_grant_pages_done(int result, unsigned int i; struct gntdev_grant_map *map = data->data; unsigned int offset = data->unmap_ops - map->unmap_ops; + int successful_unmaps = 0; + int live_grants; for (i = 0; i < data->count; i++) { + if (map->unmap_ops[offset + i].status == GNTST_okay && + map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE) + successful_unmaps++; + WARN_ON(map->unmap_ops[offset + i].status != GNTST_okay && map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE); pr_debug("unmap handle=%d st=%d\n", @@ -403,6 +407,10 @@ static void __unmap_grant_pages_done(int result, map->unmap_ops[offset+i].status); map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; if (use_ptemod) { + if (map->kunmap_ops[offset + i].status == GNTST_okay && + map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE) + successful_unmaps++; + WARN_ON(map->kunmap_ops[offset + i].status != GNTST_okay && map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE); pr_debug("kunmap handle=%u st=%d\n", @@ -411,11 +419,15 @@ static void __unmap_grant_pages_done(int result, map->kunmap_ops[offset+i].handle = INVALID_GRANT_HANDLE; } } + /* * Decrease the live-grant counter. This must happen after the loop to * prevent premature reuse of the grants by gnttab_mmap(). */ - atomic_sub(data->count, &map->live_grants); + live_grants = atomic_sub_return(successful_unmaps, &map->live_grants); + if (WARN_ON(live_grants < 0)) + pr_err("%s: live_grants became negative (%d) after unmapping %d pages!\n", + __func__, live_grants, successful_unmaps); /* Release reference taken by __unmap_grant_pages */ gntdev_put_map(NULL, map); From 7c16d0a4e6a436b4e7c92bead3fab55aaa4c1141 Mon Sep 17 00:00:00 2001 From: "M. Vefa Bicakci" Date: Sun, 2 Oct 2022 18:20:06 -0400 Subject: [PATCH 060/610] xen/gntdev: Accommodate VMA splitting commit 5c13a4a0291b30191eff9ead8d010e1ca43a4d0c upstream. Prior to this commit, the gntdev driver code did not handle the following scenario correctly with paravirtualized (PV) Xen domains: * User process sets up a gntdev mapping composed of two grant mappings (i.e., two pages shared by another Xen domain). * User process munmap()s one of the pages. * User process munmap()s the remaining page. * User process exits. In the scenario above, the user process would cause the kernel to log the following messages in dmesg for the first munmap(), and the second munmap() call would result in similar log messages: BUG: Bad page map in process doublemap.test pte:... pmd:... page:0000000057c97bff refcount:1 mapcount:-1 \ mapping:0000000000000000 index:0x0 pfn:... ... page dumped because: bad pte ... file:gntdev fault:0x0 mmap:gntdev_mmap [xen_gntdev] readpage:0x0 ... Call Trace: dump_stack_lvl+0x46/0x5e print_bad_pte.cold+0x66/0xb6 unmap_page_range+0x7e5/0xdc0 unmap_vmas+0x78/0xf0 unmap_region+0xa8/0x110 __do_munmap+0x1ea/0x4e0 __vm_munmap+0x75/0x120 __x64_sys_munmap+0x28/0x40 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x61/0xcb ... For each munmap() call, the Xen hypervisor (if built with CONFIG_DEBUG) would print out the following and trigger a general protection fault in the affected Xen PV domain: (XEN) d0v... Attempt to implicitly unmap d0's grant PTE ... (XEN) d0v... Attempt to implicitly unmap d0's grant PTE ... As of this writing, gntdev_grant_map structure's vma field (referred to as map->vma below) is mainly used for checking the start and end addresses of mappings. However, with split VMAs, these may change, and there could be more than one VMA associated with a gntdev mapping. Hence, remove the use of map->vma and rely on map->pages_vm_start for the original start address and on (map->count << PAGE_SHIFT) for the original mapping size. Let the invalidate() and find_special_page() hooks use these. Also, given that there can be multiple VMAs associated with a gntdev mapping, move the "mmu_interval_notifier_remove(&map->notifier)" call to the end of gntdev_put_map, so that the MMU notifier is only removed after the closing of the last remaining VMA. Finally, use an atomic to prevent inadvertent gntdev mapping re-use, instead of using the map->live_grants atomic counter and/or the map->vma pointer (the latter of which is now removed). This prevents the userspace from mmap()'ing (with MAP_FIXED) a gntdev mapping over the same address range as a previously set up gntdev mapping. This scenario can be summarized with the following call-trace, which was valid prior to this commit: mmap gntdev_mmap mmap (repeat mmap with MAP_FIXED over the same address range) gntdev_invalidate unmap_grant_pages (sets 'being_removed' entries to true) gnttab_unmap_refs_async unmap_single_vma gntdev_mmap (maps the shared pages again) munmap gntdev_invalidate unmap_grant_pages (no-op because 'being_removed' entries are true) unmap_single_vma (For PV domains, Xen reports that a granted page is being unmapped and triggers a general protection fault in the affected domain, if Xen was built with CONFIG_DEBUG) The fix for this last scenario could be worth its own commit, but we opted for a single commit, because removing the gntdev_grant_map structure's vma field requires guarding the entry to gntdev_mmap(), and the live_grants atomic counter is not sufficient on its own to prevent the mmap() over a pre-existing mapping. Link: https://github.com/QubesOS/qubes-issues/issues/7631 Fixes: ab31523c2fca ("xen/gntdev: allow usermode to map granted pages") Cc: stable@vger.kernel.org Signed-off-by: M. Vefa Bicakci Reviewed-by: Juergen Gross Link: https://lore.kernel.org/r/20221002222006.2077-3-m.v.b@runbox.com Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- drivers/xen/gntdev-common.h | 3 +- drivers/xen/gntdev.c | 58 ++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/xen/gntdev-common.h b/drivers/xen/gntdev-common.h index 40ef379c28ab..9c286b2a1900 100644 --- a/drivers/xen/gntdev-common.h +++ b/drivers/xen/gntdev-common.h @@ -44,9 +44,10 @@ struct gntdev_unmap_notify { }; struct gntdev_grant_map { + atomic_t in_use; struct mmu_interval_notifier notifier; + bool notifier_init; struct list_head next; - struct vm_area_struct *vma; int index; int count; int flags; diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index eb0586b9767d..4d9a3050de6a 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -286,6 +286,9 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map) */ } + if (use_ptemod && map->notifier_init) + mmu_interval_notifier_remove(&map->notifier); + if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { notify_remote_via_evtchn(map->notify.event); evtchn_put(map->notify.event); @@ -298,7 +301,7 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map) static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data) { struct gntdev_grant_map *map = data; - unsigned int pgnr = (addr - map->vma->vm_start) >> PAGE_SHIFT; + unsigned int pgnr = (addr - map->pages_vm_start) >> PAGE_SHIFT; int flags = map->flags | GNTMAP_application_map | GNTMAP_contains_pte | (1 << _GNTMAP_guest_avail0); u64 pte_maddr; @@ -508,11 +511,7 @@ static void gntdev_vma_close(struct vm_area_struct *vma) struct gntdev_priv *priv = file->private_data; pr_debug("gntdev_vma_close %p\n", vma); - if (use_ptemod) { - WARN_ON(map->vma != vma); - mmu_interval_notifier_remove(&map->notifier); - map->vma = NULL; - } + vma->vm_private_data = NULL; gntdev_put_map(priv, map); } @@ -540,29 +539,30 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn, struct gntdev_grant_map *map = container_of(mn, struct gntdev_grant_map, notifier); unsigned long mstart, mend; + unsigned long map_start, map_end; if (!mmu_notifier_range_blockable(range)) return false; + map_start = map->pages_vm_start; + map_end = map->pages_vm_start + (map->count << PAGE_SHIFT); + /* * If the VMA is split or otherwise changed the notifier is not * updated, but we don't want to process VA's outside the modified * VMA. FIXME: It would be much more understandable to just prevent * modifying the VMA in the first place. */ - if (map->vma->vm_start >= range->end || - map->vma->vm_end <= range->start) + if (map_start >= range->end || map_end <= range->start) return true; - mstart = max(range->start, map->vma->vm_start); - mend = min(range->end, map->vma->vm_end); + mstart = max(range->start, map_start); + mend = min(range->end, map_end); pr_debug("map %d+%d (%lx %lx), range %lx %lx, mrange %lx %lx\n", - map->index, map->count, - map->vma->vm_start, map->vma->vm_end, - range->start, range->end, mstart, mend); - unmap_grant_pages(map, - (mstart - map->vma->vm_start) >> PAGE_SHIFT, - (mend - mstart) >> PAGE_SHIFT); + map->index, map->count, map_start, map_end, + range->start, range->end, mstart, mend); + unmap_grant_pages(map, (mstart - map_start) >> PAGE_SHIFT, + (mend - mstart) >> PAGE_SHIFT); return true; } @@ -1042,18 +1042,15 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) return -EINVAL; pr_debug("map %d+%d at %lx (pgoff %lx)\n", - index, count, vma->vm_start, vma->vm_pgoff); + index, count, vma->vm_start, vma->vm_pgoff); mutex_lock(&priv->lock); map = gntdev_find_map_index(priv, index, count); if (!map) goto unlock_out; - if (use_ptemod && map->vma) + if (!atomic_add_unless(&map->in_use, 1, 1)) goto unlock_out; - if (atomic_read(&map->live_grants)) { - err = -EAGAIN; - goto unlock_out; - } + refcount_inc(&map->users); vma->vm_ops = &gntdev_vmops; @@ -1074,15 +1071,16 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) map->flags |= GNTMAP_readonly; } + map->pages_vm_start = vma->vm_start; + if (use_ptemod) { - map->vma = vma; err = mmu_interval_notifier_insert_locked( &map->notifier, vma->vm_mm, vma->vm_start, vma->vm_end - vma->vm_start, &gntdev_mmu_ops); - if (err) { - map->vma = NULL; + if (err) goto out_unlock_put; - } + + map->notifier_init = true; } mutex_unlock(&priv->lock); @@ -1099,7 +1097,6 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) */ mmu_interval_read_begin(&map->notifier); - map->pages_vm_start = vma->vm_start; err = apply_to_page_range(vma->vm_mm, vma->vm_start, vma->vm_end - vma->vm_start, find_grant_ptes, map); @@ -1128,13 +1125,8 @@ unlock_out: out_unlock_put: mutex_unlock(&priv->lock); out_put_map: - if (use_ptemod) { + if (use_ptemod) unmap_grant_pages(map, 0, map->count); - if (map->vma) { - mmu_interval_notifier_remove(&map->notifier); - map->vma = NULL; - } - } gntdev_put_map(priv, map); return err; } From 26e5c79e673c594e1c43114935382e150dc00fdf Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 21 Sep 2022 20:49:16 +0100 Subject: [PATCH 061/610] PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge commit 0e32818397426a688f598f35d3bc762eca6d7592 upstream. When pci_assign_resource() is unable to assign resources to a BAR, it uses pci_revert_fw_address() to fall back to a firmware assignment (if any). Previously pci_revert_fw_address() assumed all addresses could reach the device, but this is not true if the device is below a bridge that only forwards addresses within its windows. This problem was observed on a Tyan Tomcat IV S1564D system where the BIOS did not assign valid addresses to several bridges and USB devices: pci 0000:00:11.0: PCI-to-PCIe bridge to [bus 01-ff] pci 0000:00:11.0: bridge window [io 0xe000-0xefff] pci 0000:01:00.0: PCIe Upstream Port to [bus 02-ff] pci 0000:01:00.0: bridge window [io 0x0000-0x0fff] # unreachable pci 0000:02:02.0: PCIe Downstream Port to [bus 05-ff] pci 0000:02:02.0: bridge window [io 0x0000-0x0fff] # unreachable pci 0000:05:00.0: PCIe-to-PCI bridge to [bus 06-ff] pci 0000:05:00.0: bridge window [io 0x0000-0x0fff] # unreachable pci 0000:06:08.0: USB UHCI 1.1 pci 0000:06:08.0: BAR 4: [io 0xfce0-0xfcff] # unreachable pci 0000:06:08.1: USB UHCI 1.1 pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] # unreachable pci 0000:06:08.0: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window pci 0000:06:08.1: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window During the first pass of assigning unassigned resources, there was not enough I/O space available, so we couldn't assign the 06:08.0 BAR and reverted to the firmware assignment (still unreachable). Reverting the 06:08.1 assignment failed because it conflicted with 06:08.0: pci 0000:00:11.0: bridge window [io 0xe000-0xefff] pci 0000:01:00.0: no space for bridge window [io size 0x2000] pci 0000:02:02.0: no space for bridge window [io size 0x1000] pci 0000:05:00.0: no space for bridge window [io size 0x1000] pci 0000:06:08.0: BAR 4: no space for [io size 0x0020] pci 0000:06:08.0: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] pci 0000:06:08.1: BAR 4: no space for [io size 0x0020] pci 0000:06:08.1: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] conflicts with 0000:06:08.0 [io 0xfce0-0xfcff] A subsequent pass assigned valid bridge windows and a valid 06:08.1 BAR, but left the 06:08.0 BAR alone, so the UHCI device was still unusable: pci 0000:00:11.0: bridge window [io 0xe000-0xefff] released pci 0000:00:11.0: bridge window [io 0x1000-0x2fff] # reassigned pci 0000:01:00.0: bridge window [io 0x1000-0x2fff] # reassigned pci 0000:02:02.0: bridge window [io 0x2000-0x2fff] # reassigned pci 0000:05:00.0: bridge window [io 0x2000-0x2fff] # reassigned pci 0000:06:08.0: BAR 4: assigned [io 0xfce0-0xfcff] # left alone pci 0000:06:08.1: BAR 4: assigned [io 0x2000-0x201f] ... uhci_hcd 0000:06:08.0: host system error, PCI problems? uhci_hcd 0000:06:08.0: host controller process error, something bad happened! uhci_hcd 0000:06:08.0: host controller halted, very bad! uhci_hcd 0000:06:08.0: HCRESET not completed yet! uhci_hcd 0000:06:08.0: HC died; cleaning up If the address assigned by firmware is not reachable because it's not within upstream bridge windows, fail instead of assigning the unusable address from firmware. [bhelgaas: commit log, use pci_upstream_bridge()] Link: https://bugzilla.kernel.org/show_bug.cgi?id=16263 Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203012338460.46819@angie.orcam.me.uk Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209211921250.29493@angie.orcam.me.uk Fixes: 58c84eda0756 ("PCI: fall back to original BIOS BAR addresses") Signed-off-by: Maciej W. Rozycki Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v2.6.35+ Signed-off-by: Greg Kroah-Hartman --- drivers/pci/setup-res.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 7f1acb3918d0..875d50c16f19 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -210,6 +210,17 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, root = pci_find_parent_resource(dev, res); if (!root) { + /* + * If dev is behind a bridge, accesses will only reach it + * if res is inside the relevant bridge window. + */ + if (pci_upstream_bridge(dev)) + return -ENXIO; + + /* + * On the root bus, assume the host bridge will forward + * everything. + */ if (res->flags & IORESOURCE_IO) root = &ioport_resource; else From 63a3d75cf18c83473ab26f6e0447417660919e3e Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 21 Sep 2022 00:35:32 +0100 Subject: [PATCH 062/610] serial: 8250: Let drivers request full 16550A feature probing commit 9906890c89e4dbd900ed87ad3040080339a7f411 upstream. A SERIAL_8250_16550A_VARIANTS configuration option has been recently defined that lets one request the 8250 driver not to probe for 16550A device features so as to reduce the driver's device startup time in virtual machines. Some actual hardware devices require these features to have been fully determined however for their driver to work correctly, so define a flag to let drivers request full 16550A feature probing on a device-by-device basis if required regardless of the SERIAL_8250_16550A_VARIANTS option setting chosen. Fixes: dc56ecb81a0a ("serial: 8250: Support disabling mdelay-filled probes of 16550A variants") Cc: stable@vger.kernel.org # v5.6+ Reported-by: Anders Blomdell Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209202357520.41633@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 3 ++- include/linux/serial_core.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index a5496bd1b650..b07326b71834 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1029,7 +1029,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) up->port.type = PORT_16550A; up->capabilities |= UART_CAP_FIFO; - if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS)) + if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS) && + !(up->port.flags & UPF_FULL_PROBE)) return; /* diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 8757b4a6be31..86fa187f6d65 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -100,7 +100,7 @@ struct uart_icount { __u32 buf_overrun; }; -typedef unsigned int __bitwise upf_t; +typedef u64 __bitwise upf_t; typedef unsigned int __bitwise upstat_t; struct uart_port { @@ -207,6 +207,7 @@ struct uart_port { #define UPF_FIXED_PORT ((__force upf_t) (1 << 29)) #define UPF_DEAD ((__force upf_t) (1 << 30)) #define UPF_IOREMAP ((__force upf_t) (1 << 31)) +#define UPF_FULL_PROBE ((__force upf_t) (1ULL << 32)) #define __UPF_CHANGE_MASK 0x17fff #define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK) From 209a94c5192b047dafd909da0efa9b32a9d53858 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 21 Sep 2022 00:35:37 +0100 Subject: [PATCH 063/610] serial: 8250: Request full 16550A feature probing for OxSemi PCIe devices commit 00b7a4d4ee42be1c515e56cb1e8ba0f25e271d8e upstream. Oxford Semiconductor PCIe (Tornado) 950 serial port devices need to operate in the enhanced mode via the EFR register for the Divide-by-M N/8 baud rate generator prescaler to be used in their native UART mode. Otherwise the prescaler is fixed at 1 causing grossly incorrect baud rates to be programmed. Accessing the EFR register requires 16550A features to have been probed for, so request this to happen regardless of SERIAL_8250_16550A_VARIANTS by setting UPF_FULL_PROBE in port flags. Fixes: 366f6c955d4d ("serial: 8250: Add proper clock handling for OxSemi PCIe devices") Cc: stable@vger.kernel.org # v5.19+ Reported-by: Anders Blomdell Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209210005040.41633@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index a16743856fc7..1d37ff0ec85a 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1232,6 +1232,10 @@ static void pci_oxsemi_tornado_set_mctrl(struct uart_port *port, serial8250_do_set_mctrl(port, mctrl); } +/* + * We require EFR features for clock programming, so set UPF_FULL_PROBE + * for full probing regardless of CONFIG_SERIAL_8250_16550A_VARIANTS setting. + */ static int pci_oxsemi_tornado_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *up, int idx) @@ -1239,6 +1243,7 @@ static int pci_oxsemi_tornado_setup(struct serial_private *priv, struct pci_dev *dev = priv->dev; if (pci_oxsemi_tornado_p(dev)) { + up->port.flags |= UPF_FULL_PROBE; up->port.get_divisor = pci_oxsemi_tornado_get_divisor; up->port.set_divisor = pci_oxsemi_tornado_set_divisor; up->port.set_mctrl = pci_oxsemi_tornado_set_mctrl; From 071a076fd1b763aa6fe478efa047e0a549ba9c22 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 1 Sep 2022 15:10:12 -0400 Subject: [PATCH 064/610] NFSD: Protect against send buffer overflow in NFSv3 READDIR commit 640f87c190e0d1b2a0fcb2ecf6d2cd53b1c41991 upstream. Since before the git era, NFSD has conserved the number of pages held by each nfsd thread by combining the RPC receive and send buffers into a single array of pages. This works because there are no cases where an operation needs a large RPC Call message and a large RPC Reply message at the same time. Once an RPC Call has been received, svc_process() updates svc_rqst::rq_res to describe the part of rq_pages that can be used for constructing the Reply. This means that the send buffer (rq_res) shrinks when the received RPC record containing the RPC Call is large. A client can force this shrinkage on TCP by sending a correctly- formed RPC Call header contained in an RPC record that is excessively large. The full maximum payload size cannot be constructed in that case. Thanks to Aleksi Illikainen and Kari Hulkko for uncovering this issue. Reported-by: Ben Ronallo Cc: Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs3proc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 936eebd4c56d..4218a0a8ffef 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -447,13 +447,14 @@ static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp, { struct xdr_buf *buf = &resp->dirlist; struct xdr_stream *xdr = &resp->xdr; - - count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp)); + unsigned int sendbuf = min_t(unsigned int, rqstp->rq_res.buflen, + svc_max_payload(rqstp)); memset(buf, 0, sizeof(*buf)); /* Reserve room for the NULL ptr & eof flag (-2 words) */ - buf->buflen = count - XDR_UNIT * 2; + buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), sendbuf); + buf->buflen -= XDR_UNIT * 2; buf->pages = rqstp->rq_next_page; rqstp->rq_next_page += (buf->buflen + PAGE_SIZE - 1) >> PAGE_SHIFT; From 2be9331ca6061bc6ea32247266f45b8b21030244 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 1 Sep 2022 15:10:18 -0400 Subject: [PATCH 065/610] NFSD: Protect against send buffer overflow in NFSv2 READ commit 401bc1f90874280a80b93f23be33a0e7e2d1f912 upstream. Since before the git era, NFSD has conserved the number of pages held by each nfsd thread by combining the RPC receive and send buffers into a single array of pages. This works because there are no cases where an operation needs a large RPC Call message and a large RPC Reply at the same time. Once an RPC Call has been received, svc_process() updates svc_rqst::rq_res to describe the part of rq_pages that can be used for constructing the Reply. This means that the send buffer (rq_res) shrinks when the received RPC record containing the RPC Call is large. A client can force this shrinkage on TCP by sending a correctly- formed RPC Call header contained in an RPC record that is excessively large. The full maximum payload size cannot be constructed in that case. Cc: Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfsproc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 9700ad433b49..081cca405983 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -182,6 +182,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) argp->count, argp->offset); argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2); + argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen); v = 0; len = argp->count; From 75d9de25a6f833dd0701ca546ac926cabff2b5af Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 1 Sep 2022 15:10:24 -0400 Subject: [PATCH 066/610] NFSD: Protect against send buffer overflow in NFSv3 READ commit fa6be9cc6e80ec79892ddf08a8c10cabab9baf38 upstream. Since before the git era, NFSD has conserved the number of pages held by each nfsd thread by combining the RPC receive and send buffers into a single array of pages. This works because there are no cases where an operation needs a large RPC Call message and a large RPC Reply at the same time. Once an RPC Call has been received, svc_process() updates svc_rqst::rq_res to describe the part of rq_pages that can be used for constructing the Reply. This means that the send buffer (rq_res) shrinks when the received RPC record containing the RPC Call is large. A client can force this shrinkage on TCP by sending a correctly- formed RPC Call header contained in an RPC record that is excessively large. The full maximum payload size cannot be constructed in that case. Cc: Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs3proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 4218a0a8ffef..eaf785aec070 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -146,7 +146,6 @@ nfsd3_proc_read(struct svc_rqst *rqstp) { struct nfsd3_readargs *argp = rqstp->rq_argp; struct nfsd3_readres *resp = rqstp->rq_resp; - u32 max_blocksize = svc_max_payload(rqstp); unsigned int len; int v; @@ -155,7 +154,8 @@ nfsd3_proc_read(struct svc_rqst *rqstp) (unsigned long) argp->count, (unsigned long long) argp->offset); - argp->count = min_t(u32, argp->count, max_blocksize); + argp->count = min_t(u32, argp->count, svc_max_payload(rqstp)); + argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen); if (argp->offset > (u64)OFFSET_MAX) argp->offset = (u64)OFFSET_MAX; if (argp->offset + argp->count > (u64)OFFSET_MAX) From 9df2a9cdad5bf843aa20bdcf2ce9987130e87afb Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 24 Sep 2022 13:47:36 +0800 Subject: [PATCH 067/610] powercap: intel_rapl: Use standard Energy Unit for SPR Dram RAPL domain commit 4c081324df5608b73428662ca54d5221ea03a6bd upstream. Intel Xeon servers used to use a fixed energy resolution (15.3uj) for Dram RAPL domain. But on SPR, Dram RAPL domain follows the standard energy resolution as described in MSR_RAPL_POWER_UNIT. Remove the SPR dram_domain_energy_unit quirk. Fixes: 2d798d9f5967 ("powercap: intel_rapl: add support for Sapphire Rapids") Signed-off-by: Zhang Rui Tested-by: Wang Wendy Cc: 5.9+ # 5.9+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/powercap/intel_rapl_common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index 7c0099e7a6d7..c87d4687aa67 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -979,7 +979,6 @@ static const struct rapl_defaults rapl_defaults_spr_server = { .check_unit = rapl_check_unit_core, .set_floor_freq = set_floor_freq_default, .compute_time_window = rapl_compute_time_window_core, - .dram_domain_energy_unit = 15300, .psys_domain_energy_unit = 1000000000, }; From ba2159df18066045b6db1a44d502071e1c52b230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 27 Aug 2022 15:44:54 +0200 Subject: [PATCH 068/610] powerpc/boot: Explicitly disable usage of SPE instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 110a58b9f91c66f743c01a2c217243d94c899c23 upstream. uImage boot wrapper should not use SPE instructions, like kernel itself. Boot wrapper has already disabled Altivec and VSX instructions but not SPE. Options -mno-spe and -mspe=no already set when compilation of kernel, but not when compiling uImage wrapper yet. Fix it. Cc: stable@vger.kernel.org Signed-off-by: Pali Rohár Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220827134454.17365-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/boot/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 089ee3ea55c8..1d51b9e21172 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -34,6 +34,7 @@ endif BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ + $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ $(LINUXINCLUDE) From fa0aab2e45f08e577cb1846560b42abcd03b7193 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 16 Sep 2022 13:29:07 +0100 Subject: [PATCH 069/610] slimbus: qcom-ngd: use correct error in message of pdr_add_lookup() failure commit 5038d21dde818fe74ba1fcb6f2cee35b8c2ebbf2 upstream. Use correct error code, instead of previous 'ret' value, when printing error from pdr_add_lookup() failure. Fixes: e1ae85e1830e ("slimbus: qcom-ngd-ctrl: add Protection Domain Restart Support") Cc: Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220916122910.170730-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 7040293c2ee8..4a7fc44b56a2 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1572,8 +1572,9 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd"); if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) { + ret = PTR_ERR(pds); dev_err(dev, "pdr add lookup failed: %d\n", ret); - return PTR_ERR(pds); + return ret; } platform_driver_register(&qcom_slim_ngd_driver); From 1d567179f27788925dc90fe5e905cdabfce7d190 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 16 Sep 2022 13:29:08 +0100 Subject: [PATCH 070/610] slimbus: qcom-ngd: cleanup in probe error path commit 16f14551d0df9e7cd283545d7d748829594d912f upstream. Add proper error path in probe() to cleanup resources previously acquired/allocated to fix warnings visible during probe deferral: notifier callback qcom_slim_ngd_ssr_notify already registered WARNING: CPU: 6 PID: 70 at kernel/notifier.c:28 notifier_chain_register+0x5c/0x90 Modules linked in: CPU: 6 PID: 70 Comm: kworker/u16:1 Not tainted 6.0.0-rc3-next-20220830 #380 Call trace: notifier_chain_register+0x5c/0x90 srcu_notifier_chain_register+0x44/0x90 qcom_register_ssr_notifier+0x38/0x4c qcom_slim_ngd_ctrl_probe+0xd8/0x400 platform_probe+0x6c/0xe0 really_probe+0xbc/0x2d4 __driver_probe_device+0x78/0xe0 driver_probe_device+0x3c/0x12c __device_attach_driver+0xb8/0x120 bus_for_each_drv+0x78/0xd0 __device_attach+0xa8/0x1c0 device_initial_probe+0x18/0x24 bus_probe_device+0xa0/0xac deferred_probe_work_func+0x88/0xc0 process_one_work+0x1d4/0x320 worker_thread+0x2cc/0x44c kthread+0x110/0x114 ret_from_fork+0x10/0x20 Fixes: e1ae85e1830e ("slimbus: qcom-ngd-ctrl: add Protection Domain Restart Support") Cc: Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220916122910.170730-3-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/slimbus/qcom-ngd-ctrl.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 4a7fc44b56a2..21519ce05bdb 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1567,18 +1567,27 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) ctrl->pdr = pdr_handle_alloc(slim_pd_status, ctrl); if (IS_ERR(ctrl->pdr)) { dev_err(dev, "Failed to init PDR handle\n"); - return PTR_ERR(ctrl->pdr); + ret = PTR_ERR(ctrl->pdr); + goto err_pdr_alloc; } pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd"); if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) { ret = PTR_ERR(pds); dev_err(dev, "pdr add lookup failed: %d\n", ret); - return ret; + goto err_pdr_lookup; } platform_driver_register(&qcom_slim_ngd_driver); return of_qcom_slim_ngd_register(dev, ctrl); + +err_pdr_alloc: + qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb); + +err_pdr_lookup: + pdr_handle_release(ctrl->pdr); + + return ret; } static int qcom_slim_ngd_ctrl_remove(struct platform_device *pdev) From e0b1c16fdadd7e6c7e7d539a2be5d8f6062aa701 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Mon, 19 Sep 2022 06:44:34 -0700 Subject: [PATCH 071/610] scsi: qedf: Populate sysfs attributes for vport commit 592642e6b11e620e4b43189f8072752429fc8dc3 upstream. Few vport parameters were displayed by systool as 'Unknown' or 'NULL'. Copy speed, supported_speed, frame_size and update port_type for NPIV port. Link: https://lore.kernel.org/r/20220919134434.3513-1-njavali@marvell.com Cc: stable@vger.kernel.org Tested-by: Guangwu Zhang Reviewed-by: John Meneghini Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qedf/qedf_main.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 73c7197081ea..fa49a3e52a9b 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -1921,6 +1921,27 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) fc_vport_setlink(vn_port); } + /* Set symbolic node name */ + if (base_qedf->pdev->device == QL45xxx) + snprintf(fc_host_symbolic_name(vn_port->host), 256, + "Marvell FastLinQ 45xxx FCoE v%s", QEDF_VERSION); + + if (base_qedf->pdev->device == QL41xxx) + snprintf(fc_host_symbolic_name(vn_port->host), 256, + "Marvell FastLinQ 41xxx FCoE v%s", QEDF_VERSION); + + /* Set supported speed */ + fc_host_supported_speeds(vn_port->host) = n_port->link_supported_speeds; + + /* Set speed */ + vn_port->link_speed = n_port->link_speed; + + /* Set port type */ + fc_host_port_type(vn_port->host) = FC_PORTTYPE_NPIV; + + /* Set maxframe size */ + fc_host_maxframe_size(vn_port->host) = n_port->mfs; + QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_NPIV, "vn_port=%p.\n", vn_port); From 5d97378b3626001a86bd9cfcb632c5dea65f863d Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Fri, 30 Sep 2022 15:20:33 +0200 Subject: [PATCH 072/610] gpio: rockchip: request GPIO mux to pinctrl when setting direction commit 8ea8af6c8469156ac2042d83d73f6b74eb4b4b45 upstream. Before the split of gpio and pinctrl sections in their own driver, rockchip_set_mux was called in pinmux_ops.gpio_set_direction for configuring a pin in its GPIO function. This is essential for cases where pinctrl is "bypassed" by gpio consumers otherwise the GPIO function is not configured for the pin and it does not work. Such was the case for the sysfs/libgpiod userspace GPIO handling. Let's call pinctrl_gpio_direction_input/output when setting the direction of a GPIO so that the pinctrl core requests from the rockchip pinctrl driver to put the pin in its GPIO function. Fixes: 9ce9a02039de ("pinctrl/rockchip: drop the gpio related codes") Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio") Cc: stable@vger.kernel.org Reviewed-by: Heiko Stuebner Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20220930132033.4003377-3-foss+kernel@0leil.net Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/gpio/gpio-rockchip.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index f31b0947eaaa..d32928c1efe0 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,12 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip, unsigned long flags; u32 data = input ? 0 : 1; + + if (input) + pinctrl_gpio_direction_input(bank->pin_base + offset); + else + pinctrl_gpio_direction_output(bank->pin_base + offset); + raw_spin_lock_irqsave(&bank->slock, flags); rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); raw_spin_unlock_irqrestore(&bank->slock, flags); From aa7b2c927e4ef3bbff28a0dd71d06bbb59870f4d Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Fri, 30 Sep 2022 15:20:32 +0200 Subject: [PATCH 073/610] pinctrl: rockchip: add pinmux_ops.gpio_set_direction callback commit 4635c0e2a7f7f3568cbfccae70121f9835efa62c upstream. Before the split of gpio and pinctrl sections in their own driver, rockchip_set_mux was called in pinmux_ops.gpio_set_direction for configuring a pin in its GPIO function. This is essential for cases where pinctrl is "bypassed" by gpio consumers otherwise the GPIO function is not configured for the pin and it does not work. Such was the case for the sysfs/libgpiod userspace GPIO handling. Let's re-implement the pinmux_ops.gpio_set_direction callback so that the gpio subsystem can request from the pinctrl driver to put the pin in its GPIO function. Fixes: 9ce9a02039de ("pinctrl/rockchip: drop the gpio related codes") Cc: stable@vger.kernel.org Reviewed-by: Heiko Stuebner Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20220930132033.4003377-2-foss+kernel@0leil.net Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/pinctrl-rockchip.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 350e721c4658..bae6cc83ea36 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2072,11 +2072,24 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, return 0; } +static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset, + bool input) +{ + struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + struct rockchip_pin_bank *bank; + + bank = pin_to_bank(info, offset); + return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO); +} + static const struct pinmux_ops rockchip_pmx_ops = { .get_functions_count = rockchip_pmx_get_funcs_count, .get_function_name = rockchip_pmx_get_func_name, .get_function_groups = rockchip_pmx_get_groups, .set_mux = rockchip_pmx_set, + .gpio_set_direction = rockchip_pmx_gpio_set_direction, }; /* From 2b0897e33682a332167b7d355eec28693b62119e Mon Sep 17 00:00:00 2001 From: Hyunwoo Kim Date: Sun, 25 Sep 2022 06:32:43 -0700 Subject: [PATCH 074/610] fbdev: smscufx: Fix use-after-free in ufx_ops_open() commit 5610bcfe8693c02e2e4c8b31427f1bdbdecc839c upstream. A race condition may occur if the user physically removes the USB device while calling open() for this device node. This is a race condition between the ufx_ops_open() function and the ufx_usb_disconnect() function, which may eventually result in UAF. So, add a mutex to the ufx_ops_open() and ufx_usb_disconnect() functions to avoid race contidion of krefs. Signed-off-by: Hyunwoo Kim Cc: stable@vger.kernel.org Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/smscufx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index 28768c272b73..7673db5da26b 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -137,6 +137,8 @@ static int ufx_submit_urb(struct ufx_data *dev, struct urb * urb, size_t len); static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size); static void ufx_free_urb_list(struct ufx_data *dev); +static DEFINE_MUTEX(disconnect_mutex); + /* reads a control register */ static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data) { @@ -1070,9 +1072,13 @@ static int ufx_ops_open(struct fb_info *info, int user) if (user == 0 && !console) return -EBUSY; + mutex_lock(&disconnect_mutex); + /* If the USB device is gone, we don't accept new opens */ - if (dev->virtualized) + if (dev->virtualized) { + mutex_unlock(&disconnect_mutex); return -ENODEV; + } dev->fb_count++; @@ -1096,6 +1102,8 @@ static int ufx_ops_open(struct fb_info *info, int user) pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d", info->node, user, info, dev->fb_count); + mutex_unlock(&disconnect_mutex); + return 0; } @@ -1740,6 +1748,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface) { struct ufx_data *dev; + mutex_lock(&disconnect_mutex); + dev = usb_get_intfdata(interface); pr_debug("USB disconnect starting\n"); @@ -1760,6 +1770,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface) kref_put(&dev->kref, ufx_free); /* consider ufx_data freed */ + + mutex_unlock(&disconnect_mutex); } static struct usb_driver ufx_driver = { From 39b68556282584ebbc03bc37b8770cbaf4e056cf Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 22 Sep 2022 23:35:43 +0900 Subject: [PATCH 075/610] ksmbd: fix endless loop when encryption for response fails commit 360c8ee6fefdb496fffd2c18bb9a96a376a1a804 upstream. If ->encrypt_resp return error, goto statement cause endless loop. It send an error response immediately after removing it. Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/ksmbd/server.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c index 36d368e59a64..976d09aaee70 100644 --- a/fs/ksmbd/server.c +++ b/fs/ksmbd/server.c @@ -235,10 +235,8 @@ send: if (work->sess && work->sess->enc && work->encrypted && conn->ops->encrypt_resp) { rc = conn->ops->encrypt_resp(work); - if (rc < 0) { + if (rc < 0) conn->ops->set_rsp_status(work, STATUS_DATA_ERROR); - goto send; - } } ksmbd_conn_write(work); From a19f316406ea73b2108ff5108610c01bdf876fac Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 26 Sep 2022 11:36:30 +0800 Subject: [PATCH 076/610] ksmbd: Fix wrong return value and message length check in smb2_ioctl() commit b1763d265af62800ec96eeb79803c4c537dcef3a upstream. Commit c7803b05f74b ("smb3: fix ksmbd bigendian bug in oplock break, and move its struct to smbfs_common") use the defination of 'struct validate_negotiate_info_req' in smbfs_common, the array length of 'Dialects' changed from 1 to 4, but the protocol does not require the client to send all 4. This lead the request which satisfied with protocol and server to fail. So just ensure the request payload has the 'DialectCount' in smb2_ioctl(), then fsctl_validate_negotiate_info() will use it to validate the payload length and each dialect. Also when the {in, out}_buf_len is less than the required, should goto out to initialize the status in the response header. Fixes: f7db8fd03a4b ("ksmbd: add validation in smb2_ioctl") Cc: stable@vger.kernel.org Signed-off-by: Zhang Xiaoxu Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/ksmbd/smb2pdu.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 55ee639703ff..bec9a84572c0 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -7617,11 +7617,16 @@ int smb2_ioctl(struct ksmbd_work *work) goto out; } - if (in_buf_len < sizeof(struct validate_negotiate_info_req)) - return -EINVAL; + if (in_buf_len < offsetof(struct validate_negotiate_info_req, + Dialects)) { + ret = -EINVAL; + goto out; + } - if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) - return -EINVAL; + if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) { + ret = -EINVAL; + goto out; + } ret = fsctl_validate_negotiate_info(conn, (struct validate_negotiate_info_req *)&req->Buffer[0], From 95a520b591c91dd4f78135cecb5eed15707b1a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Date: Thu, 29 Sep 2022 12:04:47 +0200 Subject: [PATCH 077/610] ksmbd: Fix user namespace mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7c88c1e0ab1704bacb751341ee6431c3be34b834 upstream. A kernel daemon should not rely on the current thread, which is unknown and might be malicious. Before this security fix, ksmbd_override_fsids() didn't correctly override FS UID/GID which means that arbitrary user space threads could trick the kernel to impersonate arbitrary users or groups for file system access checks, leading to file system access bypass. This was found while investigating truncate support for Landlock: https://lore.kernel.org/r/CAKYAXd8fpMJ7guizOjHgxEyyjoUwPsx3jLOPZP=wPYcbhkVXqA@mail.gmail.com Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: Hyunchul Lee Cc: Steve French Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün Link: https://lore.kernel.org/r/20220929100447.108468-1-mic@digikod.net Acked-by: Christian Brauner (Microsoft) Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/ksmbd/smb_common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c index 31da57d375db..22f460984742 100644 --- a/fs/ksmbd/smb_common.c +++ b/fs/ksmbd/smb_common.c @@ -4,6 +4,8 @@ * Copyright (C) 2018 Namjae Jeon */ +#include + #include "smb_common.h" #include "server.h" #include "misc.h" @@ -624,8 +626,8 @@ int ksmbd_override_fsids(struct ksmbd_work *work) if (!cred) return -ENOMEM; - cred->fsuid = make_kuid(current_user_ns(), uid); - cred->fsgid = make_kgid(current_user_ns(), gid); + cred->fsuid = make_kuid(&init_user_ns, uid); + cred->fsgid = make_kgid(&init_user_ns, gid); gi = groups_alloc(0); if (!gi) { From 0d942303430824f785ac7ed8434a05d87bf4bb13 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Thu, 25 Aug 2022 12:06:57 +0200 Subject: [PATCH 078/610] fs: record I_DIRTY_TIME even if inode already has I_DIRTY_INODE commit cbfecb927f429a6fa613d74b998496bd71e4438a upstream. Currently the I_DIRTY_TIME will never get set if the inode already has I_DIRTY_INODE with assumption that it supersedes I_DIRTY_TIME. That's true, however ext4 will only update the on-disk inode in ->dirty_inode(), not on actual writeback. As a result if the inode already has I_DIRTY_INODE state by the time we get to __mark_inode_dirty() only with I_DIRTY_TIME, the time was already filled into on-disk inode and will not get updated until the next I_DIRTY_INODE update, which might never come if we crash or get a power failure. The problem can be reproduced on ext4 by running xfstest generic/622 with -o iversion mount option. Fix it by allowing I_DIRTY_TIME to be set even if the inode already has I_DIRTY_INODE. Also make sure that the case is properly handled in writeback_single_inode() as well. Additionally changes in xfs_fs_dirty_inode() was made to accommodate for I_DIRTY_TIME in flag. Thanks Jan Kara for suggestions on how to make this work properly. Cc: Dave Chinner Cc: Christoph Hellwig Cc: stable@kernel.org Signed-off-by: Lukas Czerner Suggested-by: Jan Kara Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220825100657.44217-1-lczerner@redhat.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- Documentation/filesystems/vfs.rst | 3 +++ fs/fs-writeback.c | 37 +++++++++++++++++++++---------- fs/xfs/xfs_super.c | 10 +++++++-- include/linux/fs.h | 9 ++++---- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index bf5c48066fac..a99c1c338e8f 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -274,6 +274,9 @@ or bottom half). This is specifically for the inode itself being marked dirty, not its data. If the update needs to be persisted by fdatasync(), then I_DIRTY_DATASYNC will be set in the flags argument. + I_DIRTY_TIME will be set in the flags in case lazytime is enabled + and struct inode has times updated since the last ->dirty_inode + call. ``write_inode`` this method is called when the VFS needs to write an inode to diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 9761470a7ecf..2a27f0256fa3 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1745,9 +1745,14 @@ static int writeback_single_inode(struct inode *inode, */ if (!(inode->i_state & I_DIRTY_ALL)) inode_cgwb_move_to_attached(inode, wb); - else if (!(inode->i_state & I_SYNC_QUEUED) && - (inode->i_state & I_DIRTY)) - redirty_tail_locked(inode, wb); + else if (!(inode->i_state & I_SYNC_QUEUED)) { + if ((inode->i_state & I_DIRTY)) + redirty_tail_locked(inode, wb); + else if (inode->i_state & I_DIRTY_TIME) { + inode->dirtied_when = jiffies; + inode_io_list_move_locked(inode, wb, &wb->b_dirty_time); + } + } spin_unlock(&wb->list_lock); inode_sync_complete(inode); @@ -2400,6 +2405,20 @@ void __mark_inode_dirty(struct inode *inode, int flags) trace_writeback_mark_inode_dirty(inode, flags); if (flags & I_DIRTY_INODE) { + /* + * Inode timestamp update will piggback on this dirtying. + * We tell ->dirty_inode callback that timestamps need to + * be updated by setting I_DIRTY_TIME in flags. + */ + if (inode->i_state & I_DIRTY_TIME) { + spin_lock(&inode->i_lock); + if (inode->i_state & I_DIRTY_TIME) { + inode->i_state &= ~I_DIRTY_TIME; + flags |= I_DIRTY_TIME; + } + spin_unlock(&inode->i_lock); + } + /* * Notify the filesystem about the inode being dirtied, so that * (if needed) it can update on-disk fields and journal the @@ -2409,7 +2428,8 @@ void __mark_inode_dirty(struct inode *inode, int flags) */ trace_writeback_dirty_inode_start(inode, flags); if (sb->s_op->dirty_inode) - sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE); + sb->s_op->dirty_inode(inode, + flags & (I_DIRTY_INODE | I_DIRTY_TIME)); trace_writeback_dirty_inode(inode, flags); /* I_DIRTY_INODE supersedes I_DIRTY_TIME. */ @@ -2430,21 +2450,15 @@ void __mark_inode_dirty(struct inode *inode, int flags) */ smp_mb(); - if (((inode->i_state & flags) == flags) || - (dirtytime && (inode->i_state & I_DIRTY_INODE))) + if ((inode->i_state & flags) == flags) return; spin_lock(&inode->i_lock); - if (dirtytime && (inode->i_state & I_DIRTY_INODE)) - goto out_unlock_inode; if ((inode->i_state & flags) != flags) { const int was_dirty = inode->i_state & I_DIRTY; inode_attach_wb(inode, NULL); - /* I_DIRTY_INODE supersedes I_DIRTY_TIME. */ - if (flags & I_DIRTY_INODE) - inode->i_state &= ~I_DIRTY_TIME; inode->i_state |= flags; /* @@ -2517,7 +2531,6 @@ void __mark_inode_dirty(struct inode *inode, int flags) out_unlock: if (wb) spin_unlock(&wb->list_lock); -out_unlock_inode: spin_unlock(&inode->i_lock); } EXPORT_SYMBOL(__mark_inode_dirty); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 5410bf0ab426..df1d6be61bfa 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -642,7 +642,7 @@ xfs_fs_destroy_inode( static void xfs_fs_dirty_inode( struct inode *inode, - int flag) + int flags) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; @@ -650,7 +650,13 @@ xfs_fs_dirty_inode( if (!(inode->i_sb->s_flags & SB_LAZYTIME)) return; - if (flag != I_DIRTY_SYNC || !(inode->i_state & I_DIRTY_TIME)) + + /* + * Only do the timestamp update if the inode is dirty (I_DIRTY_SYNC) + * and has dirty timestamp (I_DIRTY_TIME). I_DIRTY_TIME can be passed + * in flags possibly together with I_DIRTY_SYNC. + */ + if ((flags & ~I_DIRTY_TIME) != I_DIRTY_SYNC || !(flags & I_DIRTY_TIME)) return; if (xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp)) diff --git a/include/linux/fs.h b/include/linux/fs.h index 76162f046670..fd4c450dc612 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2288,13 +2288,14 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src, * don't have to write inode on fdatasync() when only * e.g. the timestamps have changed. * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. - * I_DIRTY_TIME The inode itself only has dirty timestamps, and the + * I_DIRTY_TIME The inode itself has dirty timestamps, and the * lazytime mount option is enabled. We keep track of this * separately from I_DIRTY_SYNC in order to implement * lazytime. This gets cleared if I_DIRTY_INODE - * (I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set. I.e. - * either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in - * i_state, but not both. I_DIRTY_PAGES may still be set. + * (I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set. But + * I_DIRTY_TIME can still be set if I_DIRTY_SYNC is already + * in place because writeback might already be in progress + * and we don't want to lose the time update * I_NEW Serves as both a mutex and completion notification. * New inodes set I_NEW. If two processes both create * the same inode, one of them will release its inode and From 4b996a3014ef014af8f97b60c35f5289210a4720 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 23 Aug 2022 12:45:42 +0100 Subject: [PATCH 079/610] btrfs: fix race between quota enable and quota rescan ioctl commit 331cd9461412e103d07595a10289de90004ac890 upstream. When enabling quotas, at btrfs_quota_enable(), after committing the transaction, we change fs_info->quota_root to point to the quota root we created and set BTRFS_FS_QUOTA_ENABLED at fs_info->flags. Then we try to start the qgroup rescan worker, first by initializing it with a call to qgroup_rescan_init() - however if that fails we end up freeing the quota root but we leave fs_info->quota_root still pointing to it, this can later result in a use-after-free somewhere else. We have previously set the flags BTRFS_FS_QUOTA_ENABLED and BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with -EINPROGRESS at btrfs_quota_enable(), which is possible if someone already called the quota rescan ioctl, and therefore started the rescan worker. So fix this by ignoring an -EINPROGRESS and asserting we can't get any other error. Reported-by: Ye Bin Link: https://lore.kernel.org/linux-btrfs/20220823015931.421355-1-yebin10@huawei.com/ CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/qgroup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 4ca809fa80ea..e01065696e9c 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1157,6 +1157,21 @@ out_add_root: fs_info->qgroup_rescan_running = true; btrfs_queue_work(fs_info->qgroup_rescan_workers, &fs_info->qgroup_rescan_work); + } else { + /* + * We have set both BTRFS_FS_QUOTA_ENABLED and + * BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with + * -EINPROGRESS. That can happen because someone started the + * rescan worker by calling quota rescan ioctl before we + * attempted to initialize the rescan worker. Failure due to + * quotas disabled in the meanwhile is not possible, because + * we are holding a write lock on fs_info->subvol_sem, which + * is also acquired when disabling quotas. + * Ignore such error, and any other error would need to undo + * everything we did in the transaction we just committed. + */ + ASSERT(ret == -EINPROGRESS); + ret = 0; } out_free_path: From 0a408c6212c16b9a2a1141d3c531247582ef8101 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 20 Sep 2022 22:43:51 +0900 Subject: [PATCH 080/610] btrfs: set generation before calling btrfs_clean_tree_block in btrfs_init_new_buffer commit cbddcc4fa3443fe8cfb2ff8e210deb1f6a0eea38 upstream. syzbot is reporting uninit-value in btrfs_clean_tree_block() [1], for commit bc877d285ca3dba2 ("btrfs: Deduplicate extent_buffer init code") missed that btrfs_set_header_generation() in btrfs_init_new_buffer() must not be moved to after clean_tree_block() because clean_tree_block() is calling btrfs_header_generation() since commit 55c69072d6bd5be1 ("Btrfs: Fix extent_buffer usage when nodesize != leafsize"). Since memzero_extent_buffer() will reset "struct btrfs_header" part, we can't move btrfs_set_header_generation() to before memzero_extent_buffer(). Just re-add btrfs_set_header_generation() before btrfs_clean_tree_block(). Link: https://syzkaller.appspot.com/bug?extid=fba8e2116a12609b6c59 [1] Reported-by: syzbot Fixes: bc877d285ca3dba2 ("btrfs: Deduplicate extent_buffer init code") CC: stable@vger.kernel.org # 4.19+ Signed-off-by: Tetsuo Handa Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/extent-tree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 401a425a587c..b90e9aa24005 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4802,6 +4802,9 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, !test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state)) lockdep_owner = BTRFS_FS_TREE_OBJECTID; + /* btrfs_clean_tree_block() accesses generation field. */ + btrfs_set_header_generation(buf, trans->transid); + /* * This needs to stay, because we could allocate a freed block from an * old tree into a new tree, so we need to make sure this new block is From ab4958975490d0fbd2f9709e40e66bd2c679297b Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 18 Aug 2022 22:40:09 -0700 Subject: [PATCH 081/610] f2fs: complete checkpoints during remount commit 4f99484d27961cb194cebcd917176fa038a5025f upstream. Otherwise, pending checkpoints can contribute a race condition to give a quota warning. - Thread - checkpoint thread add checkpoints to the list do_remount() down_write(&sb->s_umount); f2fs_remount() block_operations() down_read_trylock(&sb->s_umount) = 0 up_write(&sb->s_umount); f2fs_quota_sync() dquot_writeback_dquots() WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount)); Or, do_remount() down_write(&sb->s_umount); f2fs_remount() create a ckpt thread f2fs_enable_checkpoint() adds checkpoints wait for f2fs_sync_fs() trigger another pending checkpoint block_operations() down_read_trylock(&sb->s_umount) = 0 up_write(&sb->s_umount); f2fs_quota_sync() dquot_writeback_dquots() WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount)); Cc: stable@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/super.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index ca11bbb1500f..ba032eb3e0c5 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2152,6 +2152,9 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) up_write(&sbi->gc_lock); f2fs_sync_fs(sbi->sb, 1); + + /* Let's ensure there's no pending checkpoint anymore */ + f2fs_flush_ckpt_thread(sbi); } static int f2fs_remount(struct super_block *sb, int *flags, char *data) @@ -2318,6 +2321,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) f2fs_stop_ckpt_thread(sbi); need_restart_ckpt = true; } else { + /* Flush if the prevous checkpoint, if exists. */ + f2fs_flush_ckpt_thread(sbi); + err = f2fs_start_ckpt_thread(sbi); if (err) { f2fs_err(sbi, From 0035b84223debe8a64ebd626b4e8a9f20b96a008 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 19 Aug 2022 15:52:02 -0700 Subject: [PATCH 082/610] f2fs: flush pending checkpoints when freezing super commit c7b58576370147833999fd4cc874d0f918bdf9ca upstream. This avoids -EINVAL when trying to freeze f2fs. Cc: stable@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/checkpoint.c | 24 ++++++++++++++++++------ fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 5 ++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f2fe4940a8cd..2046c1f4cb2c 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1892,15 +1892,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi) void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi) { struct ckpt_req_control *cprc = &sbi->cprc_info; + struct task_struct *ckpt_task; - if (cprc->f2fs_issue_ckpt) { - struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt; + if (!cprc->f2fs_issue_ckpt) + return; - cprc->f2fs_issue_ckpt = NULL; - kthread_stop(ckpt_task); + ckpt_task = cprc->f2fs_issue_ckpt; + cprc->f2fs_issue_ckpt = NULL; + kthread_stop(ckpt_task); - flush_remained_ckpt_reqs(sbi, NULL); - } + f2fs_flush_ckpt_thread(sbi); +} + +void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi) +{ + struct ckpt_req_control *cprc = &sbi->cprc_info; + + flush_remained_ckpt_reqs(sbi, NULL); + + /* Let's wait for the previous dispatched checkpoint. */ + while (atomic_read(&cprc->queued_ckpt)) + io_schedule_timeout(DEFAULT_IO_TIMEOUT); } void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a0e1e29b9640..9a3f2e366cd8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3540,6 +3540,7 @@ unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi, * checkpoint.c */ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io); +void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi); struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index); struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index ba032eb3e0c5..59215c48a31b 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1661,9 +1661,8 @@ static int f2fs_freeze(struct super_block *sb) if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY)) return -EINVAL; - /* ensure no checkpoint required */ - if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list)) - return -EINVAL; + /* Let's flush checkpoints and stop the thread. */ + f2fs_flush_ckpt_thread(F2FS_SB(sb)); /* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */ set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING); From 7f10357c9046dae1912b793e83fb81683f996a77 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 23 Aug 2022 10:18:42 -0700 Subject: [PATCH 083/610] f2fs: increase the limit for reserve_root commit da35fe96d12d15779f3cb74929b7ed03941cf983 upstream. This patch increases the threshold that limits the reserved root space from 0.2% to 12.5% by using simple shift operation. Typically Android sets 128MB, but if the storage capacity is 32GB, 0.2% which is around 64MB becomes too small. Let's relax it. Cc: stable@vger.kernel.org Reported-by: Aran Dalton Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 59215c48a31b..a0d1ef73b83e 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -306,10 +306,10 @@ static void f2fs_destroy_casefold_cache(void) { } static inline void limit_reserve_root(struct f2fs_sb_info *sbi) { - block_t limit = min((sbi->user_block_count << 1) / 1000, + block_t limit = min((sbi->user_block_count >> 3), sbi->user_block_count - sbi->reserved_blocks); - /* limit is 0.2% */ + /* limit is 12.5% */ if (test_opt(sbi, RESERVE_ROOT) && F2FS_OPTION(sbi).root_reserved_blocks > limit) { F2FS_OPTION(sbi).root_reserved_blocks = limit; From ed854f10e6afd5cbd5c3274d4c4df4bfe0ab4362 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 13 Sep 2022 10:08:41 +0800 Subject: [PATCH 084/610] f2fs: fix to do sanity check on destination blkaddr during recovery commit 0ef4ca04a3f9223ff8bc440041c524b2123e09a3 upstream. As Wenqing Liu reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216456 loop5: detected capacity change from 0 to 131072 F2FS-fs (loop5): recover_inode: ino = 6, name = hln, inline = 1 F2FS-fs (loop5): recover_data: ino = 6 (i_size: recover) err = 0 F2FS-fs (loop5): recover_inode: ino = 6, name = hln, inline = 1 F2FS-fs (loop5): recover_data: ino = 6 (i_size: recover) err = 0 F2FS-fs (loop5): recover_inode: ino = 6, name = hln, inline = 1 F2FS-fs (loop5): recover_data: ino = 6 (i_size: recover) err = 0 F2FS-fs (loop5): Bitmap was wrongly set, blk:5634 ------------[ cut here ]------------ WARNING: CPU: 3 PID: 1013 at fs/f2fs/segment.c:2198 RIP: 0010:update_sit_entry+0xa55/0x10b0 [f2fs] Call Trace: f2fs_do_replace_block+0xa98/0x1890 [f2fs] f2fs_replace_block+0xeb/0x180 [f2fs] recover_data+0x1a69/0x6ae0 [f2fs] f2fs_recover_fsync_data+0x120d/0x1fc0 [f2fs] f2fs_fill_super+0x4665/0x61e0 [f2fs] mount_bdev+0x2cf/0x3b0 legacy_get_tree+0xed/0x1d0 vfs_get_tree+0x81/0x2b0 path_mount+0x47e/0x19d0 do_mount+0xce/0xf0 __x64_sys_mount+0x12c/0x1a0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd If we enable CONFIG_F2FS_CHECK_FS config, it will trigger a kernel panic instead of warning. The root cause is: in fuzzed image, SIT table is inconsistent with inode mapping table, result in triggering such warning during SIT table update. This patch introduces a new flag DATA_GENERIC_ENHANCE_UPDATE, w/ this flag, data block recovery flow can check destination blkaddr's validation in SIT table, and skip f2fs_replace_block() to avoid inconsistent status. Cc: stable@vger.kernel.org Reported-by: Wenqing Liu Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/checkpoint.c | 10 +++++++++- fs/f2fs/f2fs.h | 4 ++++ fs/f2fs/recovery.c | 8 ++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 2046c1f4cb2c..2917299d45c0 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -139,7 +139,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, unsigned int segno, offset; bool exist; - if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ) + if (type == DATA_GENERIC) return true; segno = GET_SEGNO(sbi, blkaddr); @@ -147,6 +147,13 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, se = get_seg_entry(sbi, segno); exist = f2fs_test_bit(offset, se->cur_valid_map); + if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) { + f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d", + blkaddr, exist); + set_sbi_flag(sbi, SBI_NEED_FSCK); + return exist; + } + if (!exist && type == DATA_GENERIC_ENHANCE) { f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d", blkaddr, exist); @@ -184,6 +191,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, case DATA_GENERIC: case DATA_GENERIC_ENHANCE: case DATA_GENERIC_ENHANCE_READ: + case DATA_GENERIC_ENHANCE_UPDATE: if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || blkaddr < MAIN_BLKADDR(sbi))) { f2fs_warn(sbi, "access invalid blkaddr:%u", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9a3f2e366cd8..4caac78e2034 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -249,6 +249,10 @@ enum { * condition of read on truncated area * by extent_cache */ + DATA_GENERIC_ENHANCE_UPDATE, /* + * strong check on range and segment + * bitmap for update case + */ META_GENERIC, }; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 66b75bc6a60a..19e5b5928c41 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -677,6 +677,14 @@ retry_prev: goto err; } + if (f2fs_is_valid_blkaddr(sbi, dest, + DATA_GENERIC_ENHANCE_UPDATE)) { + f2fs_err(sbi, "Inconsistent dest blkaddr:%u, ino:%lu, ofs:%u", + dest, inode->i_ino, dn.ofs_in_node); + err = -EFSCORRUPTED; + goto err; + } + /* write dummy data page */ f2fs_replace_block(sbi, &dn, src, dest, ni.version, false, false); From 73687c53919f49dff3852155621dab7a35c52854 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 14 Sep 2022 19:51:51 +0800 Subject: [PATCH 085/610] f2fs: fix to do sanity check on summary info commit c6ad7fd16657ebd34a87a97d9588195aae87597d upstream. As Wenqing Liu reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216456 BUG: KASAN: use-after-free in recover_data+0x63ae/0x6ae0 [f2fs] Read of size 4 at addr ffff8881464dcd80 by task mount/1013 CPU: 3 PID: 1013 Comm: mount Tainted: G W 6.0.0-rc4 #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 Call Trace: dump_stack_lvl+0x45/0x5e print_report.cold+0xf3/0x68d kasan_report+0xa8/0x130 recover_data+0x63ae/0x6ae0 [f2fs] f2fs_recover_fsync_data+0x120d/0x1fc0 [f2fs] f2fs_fill_super+0x4665/0x61e0 [f2fs] mount_bdev+0x2cf/0x3b0 legacy_get_tree+0xed/0x1d0 vfs_get_tree+0x81/0x2b0 path_mount+0x47e/0x19d0 do_mount+0xce/0xf0 __x64_sys_mount+0x12c/0x1a0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd The root cause is: in fuzzed image, SSA table is corrupted: ofs_in_node is larger than ADDRS_PER_PAGE(), result in out-of-range access on 4k-size page. - recover_data - do_recover_data - check_index_in_prev_nodes - f2fs_data_blkaddr This patch adds sanity check on summary info in recovery and GC flow in where the flows rely on them. After patch: [ 29.310883] F2FS-fs (loop0): Inconsistent ofs_in_node:65286 in summary, ino:0, nid:6, max:1018 Cc: stable@vger.kernel.org Reported-by: Wenqing Liu Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/gc.c | 10 +++++++++- fs/f2fs/recovery.c | 15 ++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index ceb5fc6b4039..e75a276f5b9c 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1002,7 +1002,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, { struct page *node_page; nid_t nid; - unsigned int ofs_in_node; + unsigned int ofs_in_node, max_addrs; block_t source_blkaddr; nid = le32_to_cpu(sum->nid); @@ -1028,6 +1028,14 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, return false; } + max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE : + DEF_ADDRS_PER_BLOCK; + if (ofs_in_node >= max_addrs) { + f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u", + ofs_in_node, dni->ino, dni->nid, max_addrs); + return false; + } + *nofs = ofs_of_node(node_page); source_blkaddr = data_blkaddr(NULL, node_page, ofs_in_node); f2fs_put_page(node_page, 1); diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 19e5b5928c41..ed21e34b59c7 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -452,7 +452,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, struct dnode_of_data tdn = *dn; nid_t ino, nid; struct inode *inode; - unsigned int offset; + unsigned int offset, ofs_in_node, max_addrs; block_t bidx; int i; @@ -479,15 +479,24 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, got_it: /* Use the locked dnode page and inode */ nid = le32_to_cpu(sum.nid); + ofs_in_node = le16_to_cpu(sum.ofs_in_node); + + max_addrs = ADDRS_PER_PAGE(dn->node_page, dn->inode); + if (ofs_in_node >= max_addrs) { + f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%lu, nid:%u, max:%u", + ofs_in_node, dn->inode->i_ino, nid, max_addrs); + return -EFSCORRUPTED; + } + if (dn->inode->i_ino == nid) { tdn.nid = nid; if (!dn->inode_page_locked) lock_page(dn->inode_page); tdn.node_page = dn->inode_page; - tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node); + tdn.ofs_in_node = ofs_in_node; goto truncate_out; } else if (dn->nid == nid) { - tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node); + tdn.ofs_in_node = ofs_in_node; goto truncate_out; } From 095493833b1860abe40ca1173b308b21f22f7ded Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 14 Sep 2021 12:49:03 -0700 Subject: [PATCH 086/610] hardening: Avoid harmless Clang option under CONFIG_INIT_STACK_ALL_ZERO commit f02003c860d921171be4a27e2893766eb3bc6871 upstream. Currently under Clang, CC_HAS_AUTO_VAR_INIT_ZERO requires an extra -enable flag compared to CC_HAS_AUTO_VAR_INIT_PATTERN. GCC 12[1] will not, and will happily ignore the Clang-specific flag. However, its presence on the command-line is both cumbersome and confusing. Due to GCC's tolerant behavior, though, we can continue to use a single Kconfig cc-option test for the feature on both compilers, but then drop the Clang-specific option in the Makefile. In other words, this patch does not change anything other than making the compiler command line shorter once GCC supports -ftrivial-auto-var-init=zero. [1] https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=a25e0b5e6ac8a77a71c229e0a7b744603365b0e9 Cc: Greg Kroah-Hartman Cc: Masahiro Yamada Cc: llvm@lists.linux.dev Fixes: dcb7c0b9461c ("hardening: Clarify Kconfig text for auto-var-init") Suggested-by: Will Deacon Link: https://lore.kernel.org/lkml/20210914102837.6172-1-will@kernel.org/ Reviewed-by: Nick Desaulniers Reviewed-by: Nathan Chancellor Acked-by: Will Deacon Signed-off-by: Kees Cook Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- Makefile | 6 +++--- security/Kconfig.hardening | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 86b6ca862e39..83ed146a73ce 100644 --- a/Makefile +++ b/Makefile @@ -844,12 +844,12 @@ endif # Initialize all stack variables with a zero value. ifdef CONFIG_INIT_STACK_ALL_ZERO -# Future support for zero initialization is still being debated, see -# https://bugs.llvm.org/show_bug.cgi?id=45497. These flags are subject to being -# renamed or dropped. KBUILD_CFLAGS += -ftrivial-auto-var-init=zero +ifdef CONFIG_CC_IS_CLANG +# https://bugs.llvm.org/show_bug.cgi?id=45497 KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang endif +endif # While VLAs have been removed, GCC produces unreachable stack probes # for the randomize_kstack_offset feature. Disable it for all compilers. diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index 90cbaff86e13..ded17b8abce2 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -23,13 +23,16 @@ config CC_HAS_AUTO_VAR_INIT_PATTERN def_bool $(cc-option,-ftrivial-auto-var-init=pattern) config CC_HAS_AUTO_VAR_INIT_ZERO + # GCC ignores the -enable flag, so we can test for the feature with + # a single invocation using the flag, but drop it as appropriate in + # the Makefile, depending on the presence of Clang. def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang) choice prompt "Initialize kernel stack variables at function entry" default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN - default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_PATTERN + default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_ZERO default INIT_STACK_NONE help This option enables initialization of stack variables at From 7434626c5eaaf4178c643f79828f8cf288308dfd Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 29 Sep 2022 22:57:43 -0700 Subject: [PATCH 087/610] hardening: Remove Clang's enable flag for -ftrivial-auto-var-init=zero commit 607e57c6c62c00965ae276902c166834ce73014a upstream. Now that Clang's -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang option is no longer required, remove it from the command line. Clang 16 and later will warn when it is used, which will cause Kconfig to think it can't use -ftrivial-auto-var-init=zero at all. Check for whether it is required and only use it when so. Cc: Nathan Chancellor Cc: Masahiro Yamada Cc: Nick Desaulniers Cc: linux-kbuild@vger.kernel.org Cc: llvm@lists.linux.dev Cc: stable@vger.kernel.org Fixes: f02003c860d9 ("hardening: Avoid harmless Clang option under CONFIG_INIT_STACK_ALL_ZERO") Signed-off-by: Kees Cook Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- Makefile | 4 ++-- security/Kconfig.hardening | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 83ed146a73ce..e2bed548d450 100644 --- a/Makefile +++ b/Makefile @@ -845,8 +845,8 @@ endif # Initialize all stack variables with a zero value. ifdef CONFIG_INIT_STACK_ALL_ZERO KBUILD_CFLAGS += -ftrivial-auto-var-init=zero -ifdef CONFIG_CC_IS_CLANG -# https://bugs.llvm.org/show_bug.cgi?id=45497 +ifdef CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER +# https://github.com/llvm/llvm-project/issues/44842 KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang endif endif diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index ded17b8abce2..942ed8de36d3 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -22,11 +22,17 @@ menu "Memory initialization" config CC_HAS_AUTO_VAR_INIT_PATTERN def_bool $(cc-option,-ftrivial-auto-var-init=pattern) -config CC_HAS_AUTO_VAR_INIT_ZERO - # GCC ignores the -enable flag, so we can test for the feature with - # a single invocation using the flag, but drop it as appropriate in - # the Makefile, depending on the presence of Clang. +config CC_HAS_AUTO_VAR_INIT_ZERO_BARE + def_bool $(cc-option,-ftrivial-auto-var-init=zero) + +config CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER + # Clang 16 and later warn about using the -enable flag, but it + # is required before then. def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang) + depends on !CC_HAS_AUTO_VAR_INIT_ZERO_BARE + +config CC_HAS_AUTO_VAR_INIT_ZERO + def_bool CC_HAS_AUTO_VAR_INIT_ZERO_BARE || CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER choice prompt "Initialize kernel stack variables at function entry" From d87fe290a5339df0b215495a780969544ffbd178 Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Wed, 7 Sep 2022 19:59:59 +0300 Subject: [PATCH 088/610] jbd2: wake up journal waiters in FIFO order, not LIFO commit 34fc8768ec6089565d6d73bad26724083cecf7bd upstream. LIFO wakeup order is unfair and sometimes leads to a journal user not being able to get a journal handle for hundreds of transactions in a row. FIFO wakeup can make things more fair. Cc: stable@kernel.org Signed-off-by: Alexey Lyashkov Reviewed-by: Ritesh Harjani (IBM) Link: https://lore.kernel.org/r/20220907165959.1137482-1-alexey.lyashkov@gmail.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/commit.c | 2 +- fs/jbd2/transaction.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 69538061c551..ac328e332124 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -581,7 +581,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) journal->j_running_transaction = NULL; start_time = ktime_get(); commit_transaction->t_log_start = journal->j_head; - wake_up(&journal->j_wait_transaction_locked); + wake_up_all(&journal->j_wait_transaction_locked); write_unlock(&journal->j_state_lock); jbd_debug(3, "JBD2: commit phase 2a\n"); diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 53cb236b53db..a57c0c8c63c4 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -173,7 +173,7 @@ static void wait_transaction_locked(journal_t *journal) int need_to_start; tid_t tid = journal->j_running_transaction->t_tid; - prepare_to_wait(&journal->j_wait_transaction_locked, &wait, + prepare_to_wait_exclusive(&journal->j_wait_transaction_locked, &wait, TASK_UNINTERRUPTIBLE); need_to_start = !tid_geq(journal->j_commit_request, tid); read_unlock(&journal->j_state_lock); @@ -199,7 +199,7 @@ static void wait_transaction_switching(journal_t *journal) read_unlock(&journal->j_state_lock); return; } - prepare_to_wait(&journal->j_wait_transaction_locked, &wait, + prepare_to_wait_exclusive(&journal->j_wait_transaction_locked, &wait, TASK_UNINTERRUPTIBLE); read_unlock(&journal->j_state_lock); /* @@ -911,7 +911,7 @@ void jbd2_journal_unlock_updates (journal_t *journal) write_lock(&journal->j_state_lock); --journal->j_barrier_count; write_unlock(&journal->j_state_lock); - wake_up(&journal->j_wait_transaction_locked); + wake_up_all(&journal->j_wait_transaction_locked); } static void warn_dirty_buffer(struct buffer_head *bh) From e7385c868ee038d6a0cb0e85c22d2741e7910fd5 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 14 Sep 2022 18:08:11 +0800 Subject: [PATCH 089/610] jbd2: fix potential buffer head reference count leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e0d5fc7a6d80ac2406c7dfc6bb625201d0250a8a upstream. As in 'jbd2_fc_wait_bufs' if buffer isn't uptodate, will return -EIO without update 'journal->j_fc_off'. But 'jbd2_fc_release_bufs' will release buffer head from ‘j_fc_off - 1’ if 'bh' is NULL will terminal release which will lead to buffer head buffer head reference count leak. To solve above issue, update 'journal->j_fc_off' before return -EIO. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220914100812.1414768-2-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/journal.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 1f8493ef181d..a6efcf545b90 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -926,8 +926,14 @@ int jbd2_fc_wait_bufs(journal_t *journal, int num_blks) wait_on_buffer(bh); put_bh(bh); journal->j_fc_wbuf[i] = NULL; - if (unlikely(!buffer_uptodate(bh))) + /* + * Update j_fc_off so jbd2_fc_release_bufs can release remain + * buffer head. + */ + if (unlikely(!buffer_uptodate(bh))) { + journal->j_fc_off = i; return -EIO; + } } return 0; From d11d2ded293976a1a0d9d9471827a44dc9e3c63f Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 14 Sep 2022 18:08:12 +0800 Subject: [PATCH 090/610] jbd2: fix potential use-after-free in jbd2_fc_wait_bufs commit 243d1a5d505d0b0460c9af0ad56ed4a56ef0bebd upstream. In 'jbd2_fc_wait_bufs' use 'bh' after put buffer head reference count which may lead to use-after-free. So judge buffer if uptodate before put buffer head reference count. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220914100812.1414768-3-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/journal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index a6efcf545b90..097ba728d516 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -924,16 +924,16 @@ int jbd2_fc_wait_bufs(journal_t *journal, int num_blks) for (i = j_fc_off - 1; i >= j_fc_off - num_blks; i--) { bh = journal->j_fc_wbuf[i]; wait_on_buffer(bh); - put_bh(bh); - journal->j_fc_wbuf[i] = NULL; /* * Update j_fc_off so jbd2_fc_release_bufs can release remain * buffer head. */ if (unlikely(!buffer_uptodate(bh))) { - journal->j_fc_off = i; + journal->j_fc_off = i + 1; return -EIO; } + put_bh(bh); + journal->j_fc_wbuf[i] = NULL; } return 0; From 56fcd0788f0d9243c1754bd6f80b8b327c4afeee Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Sat, 17 Sep 2022 17:38:05 +0800 Subject: [PATCH 091/610] jbd2: add miss release buffer head in fc_do_one_pass() commit dfff66f30f66b9524b661f311bbed8ff3d2ca49f upstream. In fc_do_one_pass() miss release buffer head after use which will lead to reference count leak. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220917093805.1782845-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/recovery.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 8ca3527189f8..3c5dd010e39d 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -256,6 +256,7 @@ static int fc_do_one_pass(journal_t *journal, err = journal->j_fc_replay_callback(journal, bh, pass, next_fc_block - journal->j_fc_first, expected_commit_id); + brelse(bh); next_fc_block++; if (err < 0 || err == JBD2_FC_REPLAY_STOP) break; From d8e4af8314df54d94cf2a541cf9c8626afe81d41 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 27 Jul 2022 17:57:53 +0200 Subject: [PATCH 092/610] ext4: avoid crash when inline data creation follows DIO write commit 4bb26f2885ac6930984ee451b952c5a6042f2c0e upstream. When inode is created and written to using direct IO, there is nothing to clear the EXT4_STATE_MAY_INLINE_DATA flag. Thus when inode gets truncated later to say 1 byte and written using normal write, we will try to store the data as inline data. This confuses the code later because the inode now has both normal block and inline data allocated and the confusion manifests for example as: kernel BUG at fs/ext4/inode.c:2721! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 359 Comm: repro Not tainted 5.19.0-rc8-00001-g31ba1e3b8305-dirty #15 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-1.fc36 04/01/2014 RIP: 0010:ext4_writepages+0x363d/0x3660 RSP: 0018:ffffc90000ccf260 EFLAGS: 00010293 RAX: ffffffff81e1abcd RBX: 0000008000000000 RCX: ffff88810842a180 RDX: 0000000000000000 RSI: 0000008000000000 RDI: 0000000000000000 RBP: ffffc90000ccf650 R08: ffffffff81e17d58 R09: ffffed10222c680b R10: dfffe910222c680c R11: 1ffff110222c680a R12: ffff888111634128 R13: ffffc90000ccf880 R14: 0000008410000000 R15: 0000000000000001 FS: 00007f72635d2640(0000) GS:ffff88811b000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000565243379180 CR3: 000000010aa74000 CR4: 0000000000150eb0 Call Trace: do_writepages+0x397/0x640 filemap_fdatawrite_wbc+0x151/0x1b0 file_write_and_wait_range+0x1c9/0x2b0 ext4_sync_file+0x19e/0xa00 vfs_fsync_range+0x17b/0x190 ext4_buffered_write_iter+0x488/0x530 ext4_file_write_iter+0x449/0x1b90 vfs_write+0xbcd/0xf40 ksys_write+0x198/0x2c0 __x64_sys_write+0x7b/0x90 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Fix the problem by clearing EXT4_STATE_MAY_INLINE_DATA when we are doing direct IO write to a file. Cc: stable@kernel.org Reported-by: Tadeusz Struk Reported-by: syzbot+bd13648a53ed6933ca49@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=a1e89d09bbbcbd5c4cb45db230ee28c822953984 Signed-off-by: Jan Kara Reviewed-by: Lukas Czerner Tested-by: Tadeusz Struk Link: https://lore.kernel.org/r/20220727155753.13969-1-jack@suse.cz Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/file.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index b25c1f8f7c4f..45f6d75de660 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -528,6 +528,12 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from) ret = -EAGAIN; goto out; } + /* + * Make sure inline data cannot be created anymore since we are going + * to allocate blocks for DIO. We know the inode does not have any + * inline data now because ext4_dio_supported() checked for that. + */ + ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); offset = iocb->ki_pos; count = ret; From 533c60a0b97cee5daab376933f486207e6680fb7 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Fri, 5 Aug 2022 20:39:47 +0800 Subject: [PATCH 093/610] ext4: fix null-ptr-deref in ext4_write_info commit f9c1f248607d5546075d3f731e7607d5571f2b60 upstream. I caught a null-ptr-deref bug as follows: ================================================================== KASAN: null-ptr-deref in range [0x0000000000000068-0x000000000000006f] CPU: 1 PID: 1589 Comm: umount Not tainted 5.10.0-02219-dirty #339 RIP: 0010:ext4_write_info+0x53/0x1b0 [...] Call Trace: dquot_writeback_dquots+0x341/0x9a0 ext4_sync_fs+0x19e/0x800 __sync_filesystem+0x83/0x100 sync_filesystem+0x89/0xf0 generic_shutdown_super+0x79/0x3e0 kill_block_super+0xa1/0x110 deactivate_locked_super+0xac/0x130 deactivate_super+0xb6/0xd0 cleanup_mnt+0x289/0x400 __cleanup_mnt+0x16/0x20 task_work_run+0x11c/0x1c0 exit_to_user_mode_prepare+0x203/0x210 syscall_exit_to_user_mode+0x5b/0x3a0 do_syscall_64+0x59/0x70 entry_SYSCALL_64_after_hwframe+0x44/0xa9 ================================================================== Above issue may happen as follows: ------------------------------------- exit_to_user_mode_prepare task_work_run __cleanup_mnt cleanup_mnt deactivate_super deactivate_locked_super kill_block_super generic_shutdown_super shrink_dcache_for_umount dentry = sb->s_root sb->s_root = NULL <--- Here set NULL sync_filesystem __sync_filesystem sb->s_op->sync_fs > ext4_sync_fs dquot_writeback_dquots sb->dq_op->write_info > ext4_write_info ext4_journal_start(d_inode(sb->s_root), EXT4_HT_QUOTA, 2) d_inode(sb->s_root) s_root->d_inode <--- Null pointer dereference To solve this problem, we use ext4_journal_start_sb directly to avoid s_root being used. Cc: stable@kernel.org Signed-off-by: Baokun Li Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220805123947.565152-1-libaokun1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3c39c88582f5..c3b0909fc824 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -6207,7 +6207,7 @@ static int ext4_write_info(struct super_block *sb, int type) handle_t *handle; /* Data block + inode block */ - handle = ext4_journal_start(d_inode(sb->s_root), EXT4_HT_QUOTA, 2); + handle = ext4_journal_start_sb(sb, EXT4_HT_QUOTA, 2); if (IS_ERR(handle)) return PTR_ERR(handle); ret = dquot_commit_info(sb, type); From 4a967fe8b0438c73ec738dfa8a4dbb56b6523217 Mon Sep 17 00:00:00 2001 From: Lalith Rajendran Date: Thu, 18 Aug 2022 21:40:49 +0000 Subject: [PATCH 094/610] ext4: make ext4_lazyinit_thread freezable commit 3b575495ab8dbb4dbe85b4ac7f991693c3668ff5 upstream. ext4_lazyinit_thread is not set freezable. Hence when the thread calls try_to_freeze it doesn't freeze during suspend and continues to send requests to the storage during suspend, resulting in suspend failures. Cc: stable@kernel.org Signed-off-by: Lalith Rajendran Link: https://lore.kernel.org/r/20220818214049.1519544-1-lalithkraj@google.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index c3b0909fc824..823f35ed95fa 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3377,6 +3377,7 @@ static int ext4_lazyinit_thread(void *arg) unsigned long next_wakeup, cur; BUG_ON(NULL == eli); + set_freezable(); cont_thread: while (true) { From dd366295d1eca557e7a9000407ec3952f691d27b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 22 Aug 2022 13:48:32 +0200 Subject: [PATCH 095/610] ext4: fix check for block being out of directory size commit 61a1d87a324ad5e3ed27c6699dfc93218fcf3201 upstream. The check in __ext4_read_dirblock() for block being outside of directory size was wrong because it compared block number against directory size in bytes. Fix it. Fixes: 65f8ea4cd57d ("ext4: check if directory block is within i_size") CVE: CVE-2022-1184 CC: stable@vger.kernel.org Signed-off-by: Jan Kara Reviewed-by: Lukas Czerner Link: https://lore.kernel.org/r/20220822114832.1482-1-jack@suse.cz Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 7d3ec39121f7..86ee0e0eef67 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -126,7 +126,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, struct ext4_dir_entry *dirent; int is_dx_block = 0; - if (block >= inode->i_size) { + if (block >= inode->i_size >> inode->i_blkbits) { ext4_error_inode(inode, func, line, block, "Attempting to read directory block (%u) that is past i_size (%llu)", block, inode->i_size); From 1f5e643b3829af830da2083e58c158e044eb01b0 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Wed, 24 Aug 2022 18:03:47 +0200 Subject: [PATCH 096/610] ext4: don't increase iversion counter for ea_inodes commit 50f094a5580e6297bf10a807d16f0ee23fa576cf upstream. ea_inodes are using i_version for storing part of the reference count so we really need to leave it alone. The problem can be reproduced by xfstest ext4/026 when iversion is enabled. Fix it by not calling inode_inc_iversion() for EXT4_EA_INODE_FL inodes in ext4_mark_iloc_dirty(). Cc: stable@kernel.org Signed-off-by: Lukas Czerner Reviewed-by: Jan Kara Reviewed-by: Jeff Layton Reviewed-by: Christian Brauner (Microsoft) Link: https://lore.kernel.org/r/20220824160349.39664-1-lczerner@redhat.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 98f381f6fc18..4118b720b676 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5701,7 +5701,12 @@ int ext4_mark_iloc_dirty(handle_t *handle, } ext4_fc_track_inode(handle, inode); - if (IS_I_VERSION(inode)) + /* + * ea_inodes are using i_version for storing reference count, don't + * mess with it + */ + if (IS_I_VERSION(inode) && + !(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) inode_inc_iversion(inode); /* the do_update_inode consumes one bh->b_count */ From 46e5f470a144da7e5e4166eaada8c2d351669a80 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Wed, 31 Aug 2022 15:46:29 +0800 Subject: [PATCH 097/610] ext4: ext4_read_bh_lock() should submit IO if the buffer isn't uptodate commit 0b73284c564d3ae4feef4bc920292f004acf4980 upstream. Recently we notice that ext4 filesystem would occasionally fail to read metadata from disk and report error message, but the disk and block layer looks fine. After analyse, we lockon commit 88dbcbb3a484 ("blkdev: avoid migration stalls for blkdev pages"). It provide a migration method for the bdev, we could move page that has buffers without extra users now, but it lock the buffers on the page, which breaks the fragile metadata read operation on ext4 filesystem, ext4_read_bh_lock() was copied from ll_rw_block(), it depends on the assumption of that locked buffer means it is under IO. So it just trylock the buffer and skip submit IO if it lock failed, after wait_on_buffer() we conclude IO error because the buffer is not uptodate. This issue could be easily reproduced by add some delay just after buffer_migrate_lock_buffers() in __buffer_migrate_folio() and do fsstress on ext4 filesystem. EXT4-fs error (device pmem1): __ext4_find_entry:1658: inode #73193: comm fsstress: reading directory lblock 0 EXT4-fs error (device pmem1): __ext4_find_entry:1658: inode #75334: comm fsstress: reading directory lblock 0 Fix it by removing the trylock logic in ext4_read_bh_lock(), just lock the buffer and submit IO if it's not uptodate, and also leave over readahead helper. Cc: stable@kernel.org Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220831074629.3755110-1-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/super.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 823f35ed95fa..eec41990fa65 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -186,19 +186,12 @@ int ext4_read_bh(struct buffer_head *bh, int op_flags, bh_end_io_t *end_io) int ext4_read_bh_lock(struct buffer_head *bh, int op_flags, bool wait) { - if (trylock_buffer(bh)) { - if (wait) - return ext4_read_bh(bh, op_flags, NULL); + lock_buffer(bh); + if (!wait) { ext4_read_bh_nowait(bh, op_flags, NULL); return 0; } - if (wait) { - wait_on_buffer(bh); - if (buffer_uptodate(bh)) - return 0; - return -EIO; - } - return 0; + return ext4_read_bh(bh, op_flags, NULL); } /* @@ -245,7 +238,8 @@ void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block) struct buffer_head *bh = sb_getblk_gfp(sb, block, 0); if (likely(bh)) { - ext4_read_bh_lock(bh, REQ_RAHEAD, false); + if (trylock_buffer(bh)) + ext4_read_bh_nowait(bh, REQ_RAHEAD, NULL); brelse(bh); } } From d12471b41674eb5f8b91a8b987dbe4e5ba1cb9d0 Mon Sep 17 00:00:00 2001 From: Jinke Han Date: Sat, 3 Sep 2022 09:24:29 +0800 Subject: [PATCH 098/610] ext4: place buffer head allocation before handle start commit d1052d236eddf6aa851434db1897b942e8db9921 upstream. In our product environment, we encounter some jbd hung waiting handles to stop while several writters were doing memory reclaim for buffer head allocation in delay alloc write path. Ext4 do buffer head allocation with holding transaction handle which may be blocked too long if the reclaim works not so smooth. According to our bcc trace, the reclaim time in buffer head allocation can reach 258s and the jbd transaction commit also take almost the same time meanwhile. Except for these extreme cases, we often see several seconds delays for cgroup memory reclaim on our servers. This is more likely to happen considering docker environment. One thing to note, the allocation of buffer heads is as often as page allocation or more often when blocksize less than page size. Just like page cache allocation, we should also place the buffer head allocation before startting the handle. Cc: stable@kernel.org Signed-off-by: Jinke Han Link: https://lore.kernel.org/r/20220903012429.22555-1-hanjinke.666@bytedance.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 4118b720b676..bdadbe57ea80 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1177,6 +1177,13 @@ retry_grab: page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; + /* + * The same as page allocation, we prealloc buffer heads before + * starting the handle. + */ + if (!page_has_buffers(page)) + create_empty_buffers(page, inode->i_sb->s_blocksize, 0); + unlock_page(page); retry_journal: From d29fa1ab4e6261f8dae6ba5b0364c3c9ae849342 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Sun, 11 Sep 2022 12:52:04 +0800 Subject: [PATCH 099/610] ext4: fix dir corruption when ext4_dx_add_entry() fails commit 7177dd009c7c04290891e9a534cd47d1b620bd04 upstream. Following process may lead to fs corruption: 1. ext4_create(dir/foo) ext4_add_nondir ext4_add_entry ext4_dx_add_entry a. add_dirent_to_buf ext4_mark_inode_dirty ext4_handle_dirty_metadata // dir inode bh is recorded into journal b. ext4_append // dx_get_count(entries) == dx_get_limit(entries) ext4_bread(EXT4_GET_BLOCKS_CREATE) ext4_getblk ext4_map_blocks ext4_ext_map_blocks ext4_mb_new_blocks dquot_alloc_block dquot_alloc_space_nodirty inode_add_bytes // update dir's i_blocks ext4_ext_insert_extent ext4_ext_dirty // record extent bh into journal ext4_handle_dirty_metadata(bh) // record new block into journal inode->i_size += inode->i_sb->s_blocksize // new size(in mem) c. ext4_handle_dirty_dx_node(bh2) // record dir's new block(dx_node) into journal d. ext4_handle_dirty_dx_node((frame - 1)->bh) e. ext4_handle_dirty_dx_node(frame->bh) f. do_split // ret err! g. add_dirent_to_buf ext4_mark_inode_dirty(dir) // update raw_inode on disk(skipped) 2. fsck -a /dev/sdb drop last block(dx_node) which beyonds dir's i_size. /dev/sdb: recovering journal /dev/sdb contains a file system with errors, check forced. /dev/sdb: Inode 12, end of extent exceeds allowed value (logical block 128, physical block 3938, len 1) 3. fsck -fn /dev/sdb dx_node->entry[i].blk > dir->i_size Pass 2: Checking directory structure Problem in HTREE directory inode 12 (/dir): bad block number 128. Clear HTree index? no Problem in HTREE directory inode 12: block #3 has invalid depth (2) Problem in HTREE directory inode 12: block #3 has bad max hash Problem in HTREE directory inode 12: block #3 not referenced Fix it by marking inode dirty directly inside ext4_append(). Fetch a reproducer in [Link]. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216466 Cc: stable@vger.kernel.org Signed-off-by: Zhihao Cheng Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220911045204.516460-1-chengzhihao1@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/namei.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 86ee0e0eef67..971a08d947f4 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -85,15 +85,20 @@ static struct buffer_head *ext4_append(handle_t *handle, return bh; inode->i_size += inode->i_sb->s_blocksize; EXT4_I(inode)->i_disksize = inode->i_size; + err = ext4_mark_inode_dirty(handle, inode); + if (err) + goto out; BUFFER_TRACE(bh, "get_write_access"); err = ext4_journal_get_write_access(handle, inode->i_sb, bh, EXT4_JTR_NONE); - if (err) { - brelse(bh); - ext4_std_error(inode->i_sb, err); - return ERR_PTR(err); - } + if (err) + goto out; return bh; + +out: + brelse(bh); + ext4_std_error(inode->i_sb, err); + return ERR_PTR(err); } static int ext4_dx_csum_verify(struct inode *inode, From ef1607c99136cabdcdad806f7e6d491e259f436d Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 14 Sep 2022 18:08:59 +0800 Subject: [PATCH 100/610] ext4: fix miss release buffer head in ext4_fc_write_inode commit ccbf8eeb39f2ff00b54726a2b20b35d788c4ecb5 upstream. In 'ext4_fc_write_inode' function first call 'ext4_get_inode_loc' get 'iloc', after use it miss release 'iloc.bh'. So just release 'iloc.bh' before 'ext4_fc_write_inode' return. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220914100859.1415196-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fast_commit.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c index 285c91b0166c..eba0e766177a 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -794,22 +794,25 @@ static int ext4_fc_write_inode(struct inode *inode, u32 *crc) tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_INODE); tl.fc_len = cpu_to_le16(inode_len + sizeof(fc_inode.fc_ino)); + ret = -ECANCELED; dst = ext4_fc_reserve_space(inode->i_sb, sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc); if (!dst) - return -ECANCELED; + goto err; if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc)) - return -ECANCELED; + goto err; dst += sizeof(tl); if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc)) - return -ECANCELED; + goto err; dst += sizeof(fc_inode); if (!ext4_fc_memcpy(inode->i_sb, dst, (u8 *)ext4_raw_inode(&iloc), inode_len, crc)) - return -ECANCELED; - - return 0; + goto err; + ret = 0; +err: + brelse(iloc.bh); + return ret; } /* From 9b5eb368a86f97eb9831f5b53b8e43ec69bc7cd4 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 21 Sep 2022 14:40:38 +0800 Subject: [PATCH 101/610] ext4: fix potential memory leak in ext4_fc_record_modified_inode() commit 9305721a309fa1bd7c194e0d4a2335bf3b29dca4 upstream. As krealloc may return NULL, in this case 'state->fc_modified_inodes' may not be freed by krealloc, but 'state->fc_modified_inodes' already set NULL. Then will lead to 'state->fc_modified_inodes' memory leak. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220921064040.3693255-2-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fast_commit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c index eba0e766177a..eb29c8e21d1b 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1414,13 +1414,15 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino) if (state->fc_modified_inodes[i] == ino) return 0; if (state->fc_modified_inodes_used == state->fc_modified_inodes_size) { - state->fc_modified_inodes = krealloc( - state->fc_modified_inodes, + int *fc_modified_inodes; + + fc_modified_inodes = krealloc(state->fc_modified_inodes, sizeof(int) * (state->fc_modified_inodes_size + EXT4_FC_REPLAY_REALLOC_INCREMENT), GFP_KERNEL); - if (!state->fc_modified_inodes) + if (!fc_modified_inodes) return -ENOMEM; + state->fc_modified_inodes = fc_modified_inodes; state->fc_modified_inodes_size += EXT4_FC_REPLAY_REALLOC_INCREMENT; } From 417b0455a0b6d0f60a2930592731d1f8340e24be Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 21 Sep 2022 14:40:39 +0800 Subject: [PATCH 102/610] ext4: fix potential memory leak in ext4_fc_record_regions() commit 7069d105c1f15c442b68af43f7fde784f3126739 upstream. As krealloc may return NULL, in this case 'state->fc_regions' may not be freed by krealloc, but 'state->fc_regions' already set NULL. Then will lead to 'state->fc_regions' memory leak. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220921064040.3693255-3-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fast_commit.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c index eb29c8e21d1b..61601bd076df 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1607,15 +1607,17 @@ int ext4_fc_record_regions(struct super_block *sb, int ino, if (replay && state->fc_regions_used != state->fc_regions_valid) state->fc_regions_used = state->fc_regions_valid; if (state->fc_regions_used == state->fc_regions_size) { + struct ext4_fc_alloc_region *fc_regions; + state->fc_regions_size += EXT4_FC_REPLAY_REALLOC_INCREMENT; - state->fc_regions = krealloc( - state->fc_regions, - state->fc_regions_size * - sizeof(struct ext4_fc_alloc_region), - GFP_KERNEL); - if (!state->fc_regions) + fc_regions = krealloc(state->fc_regions, + state->fc_regions_size * + sizeof(struct ext4_fc_alloc_region), + GFP_KERNEL); + if (!fc_regions) return -ENOMEM; + state->fc_regions = fc_regions; } region = &state->fc_regions[state->fc_regions_used++]; region->ino = ino; From 36997b75bbb39c3d17cf8ca595d463c508acef63 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 21 Sep 2022 14:40:40 +0800 Subject: [PATCH 103/610] ext4: update 'state->fc_regions_size' after successful memory allocation commit 27cd49780381c6ccbf248798e5e8fd076200ffba upstream. To avoid to 'state->fc_regions_size' mismatch with 'state->fc_regions' when fail to reallocate 'fc_reqions',only update 'state->fc_regions_size' after 'state->fc_regions' is allocated successfully. Cc: stable@kernel.org Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20220921064040.3693255-4-yebin10@huawei.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fast_commit.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c index 61601bd076df..be3f8ce98962 100644 --- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1609,14 +1609,15 @@ int ext4_fc_record_regions(struct super_block *sb, int ino, if (state->fc_regions_used == state->fc_regions_size) { struct ext4_fc_alloc_region *fc_regions; - state->fc_regions_size += - EXT4_FC_REPLAY_REALLOC_INCREMENT; fc_regions = krealloc(state->fc_regions, - state->fc_regions_size * - sizeof(struct ext4_fc_alloc_region), + sizeof(struct ext4_fc_alloc_region) * + (state->fc_regions_size + + EXT4_FC_REPLAY_REALLOC_INCREMENT), GFP_KERNEL); if (!fc_regions) return -ENOMEM; + state->fc_regions_size += + EXT4_FC_REPLAY_REALLOC_INCREMENT; state->fc_regions = fc_regions; } region = &state->fc_regions[state->fc_regions_used++]; From 31dc1727c10328b38a91a49ac0e48bbb6da95fbd Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Mon, 8 Aug 2022 15:00:19 -0400 Subject: [PATCH 104/610] livepatch: fix race between fork and KLP transition commit 747f7a2901174c9afa805dddfb7b24db6f65e985 upstream. The KLP transition code depends on the TIF_PATCH_PENDING and the task->patch_state to stay in sync. On a normal (forward) transition, TIF_PATCH_PENDING will be set on every task in the system, while on a reverse transition (after a failed forward one) first TIF_PATCH_PENDING will be cleared from every task, followed by it being set on tasks that need to be transitioned back to the original code. However, the fork code copies over the TIF_PATCH_PENDING flag from the parent to the child early on, in dup_task_struct and setup_thread_stack. Much later, klp_copy_process will set child->patch_state to match that of the parent. However, the parent's patch_state may have been changed by KLP loading or unloading since it was initially copied over into the child. This results in the KLP code occasionally hitting this warning in klp_complete_transition: for_each_process_thread(g, task) { WARN_ON_ONCE(test_tsk_thread_flag(task, TIF_PATCH_PENDING)); task->patch_state = KLP_UNDEFINED; } Set, or clear, the TIF_PATCH_PENDING flag in the child task depending on whether or not it is needed at the time klp_copy_process is called, at a point in copy_process where the tasklist_lock is held exclusively, preventing races with the KLP code. The KLP code does have a few places where the state is changed without the tasklist_lock held, but those should not cause problems because klp_update_patch_state(current) cannot be called while the current task is in the middle of fork, klp_check_and_switch_task() which is called under the pi_lock, which prevents rescheduling, and manipulation of the patch state of idle tasks, which do not fork. This should prevent this warning from triggering again in the future, and close the race for both normal and reverse transitions. Signed-off-by: Rik van Riel Reported-by: Breno Leitao Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Fixes: d83a7cb375ee ("livepatch: change to a per-task consistency model") Cc: stable@kernel.org Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20220808150019.03d6a67b@imladris.surriel.com Signed-off-by: Greg Kroah-Hartman --- kernel/livepatch/transition.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index 291b857a6e20..dc94bb9420ff 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -610,9 +610,23 @@ void klp_reverse_transition(void) /* Called from copy_process() during fork */ void klp_copy_process(struct task_struct *child) { - child->patch_state = current->patch_state; - /* TIF_PATCH_PENDING gets copied in setup_thread_stack() */ + /* + * The parent process may have gone through a KLP transition since + * the thread flag was copied in setup_thread_stack earlier. Bring + * the task flag up to date with the parent here. + * + * The operation is serialized against all klp_*_transition() + * operations by the tasklist_lock. The only exception is + * klp_update_patch_state(current), but we cannot race with + * that because we are current. + */ + if (test_tsk_thread_flag(current, TIF_PATCH_PENDING)) + set_tsk_thread_flag(child, TIF_PATCH_PENDING); + else + clear_tsk_thread_flag(child, TIF_PATCH_PENDING); + + child->patch_state = current->patch_state; } /* From fb96b7489fbde9138d01cec61eabe218a89cacf7 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Mon, 26 Sep 2022 15:20:08 +0000 Subject: [PATCH 105/610] ftrace: Properly unset FTRACE_HASH_FL_MOD commit 0ce0638edf5ec83343302b884fa208179580700a upstream. When executing following commands like what document said, but the log "#### all functions enabled ####" was not shown as expect: 1. Set a 'mod' filter: $ echo 'write*:mod:ext3' > /sys/kernel/tracing/set_ftrace_filter 2. Invert above filter: $ echo '!write*:mod:ext3' >> /sys/kernel/tracing/set_ftrace_filter 3. Read the file: $ cat /sys/kernel/tracing/set_ftrace_filter By some debugging, I found that flag FTRACE_HASH_FL_MOD was not unset after inversion like above step 2 and then result of ftrace_hash_empty() is incorrect. Link: https://lkml.kernel.org/r/20220926152008.2239274-1-zhengyejian1@huawei.com Cc: Cc: stable@vger.kernel.org Fixes: 8c08f0d5c6fb ("ftrace: Have cached module filters be an active filter") Signed-off-by: Zheng Yejian Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ftrace.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index e10cf1b54812..37db5bfa8edc 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5654,8 +5654,12 @@ int ftrace_regex_release(struct inode *inode, struct file *file) if (filter_hash) { orig_hash = &iter->ops->func_hash->filter_hash; - if (iter->tr && !list_empty(&iter->tr->mod_trace)) - iter->hash->flags |= FTRACE_HASH_FL_MOD; + if (iter->tr) { + if (list_empty(&iter->tr->mod_trace)) + iter->hash->flags &= ~FTRACE_HASH_FL_MOD; + else + iter->hash->flags |= FTRACE_HASH_FL_MOD; + } } else orig_hash = &iter->ops->func_hash->notrace_hash; From e8d116738514f5d3cd2a09f812e576be281e7a5f Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 27 Sep 2022 14:43:17 -0400 Subject: [PATCH 106/610] ring-buffer: Allow splice to read previous partially read pages commit fa8f4a89736b654125fb254b0db753ac68a5fced upstream. If a page is partially read, and then the splice system call is run against the ring buffer, it will always fail to read, no matter how much is in the ring buffer. That's because the code path for a partial read of the page does will fail if the "full" flag is set. The splice system call wants full pages, so if the read of the ring buffer is not yet full, it should return zero, and the splice will block. But if a previous read was done, where the beginning has been consumed, it should still be given to the splice caller if the rest of the page has been written to. This caused the splice command to never consume data in this scenario, and let the ring buffer just fill up and lose events. Link: https://lkml.kernel.org/r/20220927144317.46be6b80@gandalf.local.home Cc: stable@vger.kernel.org Fixes: 8789a9e7df6bf ("ring-buffer: read page interface") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 46ae72095c1e..2e65ebb809c1 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5574,7 +5574,15 @@ int ring_buffer_read_page(struct trace_buffer *buffer, unsigned int pos = 0; unsigned int size; - if (full) + /* + * If a full page is expected, this can still be returned + * if there's been a previous partial read and the + * rest of the page can be read and the commit page is off + * the reader page. + */ + if (full && + (!read || (len < (commit - read)) || + cpu_buffer->reader_page == cpu_buffer->commit_page)) goto out_unlock; if (len > (commit - read)) From bc6d4e9d64845110948546d750f14538aa84d01a Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 27 Sep 2022 19:15:24 -0400 Subject: [PATCH 107/610] ring-buffer: Have the shortest_full queue be the shortest not longest commit 3b19d614b61b93a131f463817e08219c9ce1fee3 upstream. The logic to know when the shortest waiters on the ring buffer should be woken up or not has uses a less than instead of a greater than compare, which causes the shortest_full to actually be the longest. Link: https://lkml.kernel.org/r/20220927231823.718039222@goodmis.org Cc: stable@vger.kernel.org Cc: Ingo Molnar Cc: Andrew Morton Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 2e65ebb809c1..07e274e769db 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -975,7 +975,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) nr_pages = cpu_buffer->nr_pages; dirty = ring_buffer_nr_dirty_pages(buffer, cpu); if (!cpu_buffer->shortest_full || - cpu_buffer->shortest_full < full) + cpu_buffer->shortest_full > full) cpu_buffer->shortest_full = full; raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); if (!pagebusy && From 5201dd81aef7f2b864f765cc4fa54e7c11f89c67 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 27 Sep 2022 19:15:25 -0400 Subject: [PATCH 108/610] ring-buffer: Check pending waiters when doing wake ups as well commit ec0bbc5ec5664dcee344f79373852117dc672c86 upstream. The wake up waiters only checks the "wakeup_full" variable and not the "full_waiters_pending". The full_waiters_pending is set when a waiter is added to the wait queue. The wakeup_full is only set when an event is triggered, and it clears the full_waiters_pending to avoid multiple calls to irq_work_queue(). The irq_work callback really needs to check both wakeup_full as well as full_waiters_pending such that this code can be used to wake up waiters when a file is closed that represents the ring buffer and the waiters need to be woken up. Link: https://lkml.kernel.org/r/20220927231824.209460321@goodmis.org Cc: stable@vger.kernel.org Cc: Ingo Molnar Cc: Andrew Morton Fixes: 15693458c4bc0 ("tracing/ring-buffer: Move poll wake ups into ring buffer code") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 07e274e769db..5613b5ea766e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -881,8 +881,9 @@ static void rb_wake_up_waiters(struct irq_work *work) struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work); wake_up_all(&rbwork->waiters); - if (rbwork->wakeup_full) { + if (rbwork->full_waiters_pending || rbwork->wakeup_full) { rbwork->wakeup_full = false; + rbwork->full_waiters_pending = false; wake_up_all(&rbwork->full_waiters); } } From be60f698c2769ce8cd9bc8df294e3a0df0924e51 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 28 Sep 2022 13:39:38 -0400 Subject: [PATCH 109/610] ring-buffer: Add ring_buffer_wake_waiters() commit 7e9fbbb1b776d8d7969551565bc246f74ec53b27 upstream. On closing of a file that represents a ring buffer or flushing the file, there may be waiters on the ring buffer that needs to be woken up and exit the ring_buffer_wait() function. Add ring_buffer_wake_waiters() to wake up the waiters on the ring buffer and allow them to exit the wait loop. Link: https://lkml.kernel.org/r/20220928133938.28dc2c27@gandalf.local.home Cc: stable@vger.kernel.org Cc: Ingo Molnar Cc: Andrew Morton Fixes: 15693458c4bc0 ("tracing/ring-buffer: Move poll wake ups into ring buffer code") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- include/linux/ring_buffer.h | 2 +- kernel/trace/ring_buffer.c | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index dac53fd3afea..2504df9a0453 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -101,7 +101,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full); __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, struct file *filp, poll_table *poll_table); - +void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu); #define RING_BUFFER_ALL_CPUS -1 diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5613b5ea766e..eda8f5a744a7 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -405,6 +405,7 @@ struct rb_irq_work { struct irq_work work; wait_queue_head_t waiters; wait_queue_head_t full_waiters; + long wait_index; bool waiters_pending; bool full_waiters_pending; bool wakeup_full; @@ -888,6 +889,37 @@ static void rb_wake_up_waiters(struct irq_work *work) } } +/** + * ring_buffer_wake_waiters - wake up any waiters on this ring buffer + * @buffer: The ring buffer to wake waiters on + * + * In the case of a file that represents a ring buffer is closing, + * it is prudent to wake up any waiters that are on this. + */ +void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu) +{ + struct ring_buffer_per_cpu *cpu_buffer; + struct rb_irq_work *rbwork; + + if (cpu == RING_BUFFER_ALL_CPUS) { + + /* Wake up individual ones too. One level recursion */ + for_each_buffer_cpu(buffer, cpu) + ring_buffer_wake_waiters(buffer, cpu); + + rbwork = &buffer->irq_work; + } else { + cpu_buffer = buffer->buffers[cpu]; + rbwork = &cpu_buffer->irq_work; + } + + rbwork->wait_index++; + /* make sure the waiters see the new index */ + smp_wmb(); + + rb_wake_up_waiters(&rbwork->work); +} + /** * ring_buffer_wait - wait for input to the ring buffer * @buffer: buffer to wait on @@ -903,6 +935,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) struct ring_buffer_per_cpu *cpu_buffer; DEFINE_WAIT(wait); struct rb_irq_work *work; + long wait_index; int ret = 0; /* @@ -921,6 +954,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) work = &cpu_buffer->irq_work; } + wait_index = READ_ONCE(work->wait_index); while (true) { if (full) @@ -985,6 +1019,11 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full) } schedule(); + + /* Make sure to see the new wait index */ + smp_rmb(); + if (wait_index != work->wait_index) + break; } if (full) From d4ab9bc5f56ec8db0902d335af7bc69f19fbf1ff Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Thu, 29 Sep 2022 10:49:09 -0400 Subject: [PATCH 110/610] ring-buffer: Fix race between reset page and reading page commit a0fcaaed0c46cf9399d3a2d6e0c87ddb3df0e044 upstream. The ring buffer is broken up into sub buffers (currently of page size). Each sub buffer has a pointer to its "tail" (the last event written to the sub buffer). When a new event is requested, the tail is locally incremented to cover the size of the new event. This is done in a way that there is no need for locking. If the tail goes past the end of the sub buffer, the process of moving to the next sub buffer takes place. After setting the current sub buffer to the next one, the previous one that had the tail go passed the end of the sub buffer needs to be reset back to the original tail location (before the new event was requested) and the rest of the sub buffer needs to be "padded". The race happens when a reader takes control of the sub buffer. As readers do a "swap" of sub buffers from the ring buffer to get exclusive access to the sub buffer, it replaces the "head" sub buffer with an empty sub buffer that goes back into the writable portion of the ring buffer. This swap can happen as soon as the writer moves to the next sub buffer and before it updates the last sub buffer with padding. Because the sub buffer can be released to the reader while the writer is still updating the padding, it is possible for the reader to see the event that goes past the end of the sub buffer. This can cause obvious issues. To fix this, add a few memory barriers so that the reader definitely sees the updates to the sub buffer, and also waits until the writer has put back the "tail" of the sub buffer back to the last event that was written on it. To be paranoid, it will only spin for 1 second, otherwise it will warn and shutdown the ring buffer code. 1 second should be enough as the writer does have preemption disabled. If the writer doesn't move within 1 second (with preemption disabled) something is horribly wrong. No interrupt should last 1 second! Link: https://lore.kernel.org/all/20220830120854.7545-1-jiazi.li@transsion.com/ Link: https://bugzilla.kernel.org/show_bug.cgi?id=216369 Link: https://lkml.kernel.org/r/20220929104909.0650a36c@gandalf.local.home Cc: Ingo Molnar Cc: Andrew Morton Cc: stable@vger.kernel.org Fixes: c7b0930857e22 ("ring-buffer: prevent adding write in discarded area") Reported-by: Jiazi.Li Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index eda8f5a744a7..90fc95e85232 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2612,6 +2612,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, /* Mark the rest of the page with padding */ rb_event_set_padding(event); + /* Make sure the padding is visible before the write update */ + smp_wmb(); + /* Set the write back to the previous setting */ local_sub(length, &tail_page->write); return; @@ -2623,6 +2626,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, /* time delta must be non zero */ event->time_delta = 1; + /* Make sure the padding is visible before the tail_page->write update */ + smp_wmb(); + /* Set write to end of buffer */ length = (tail + length) - BUF_PAGE_SIZE; local_sub(length, &tail_page->write); @@ -4587,6 +4593,33 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) arch_spin_unlock(&cpu_buffer->lock); local_irq_restore(flags); + /* + * The writer has preempt disable, wait for it. But not forever + * Although, 1 second is pretty much "forever" + */ +#define USECS_WAIT 1000000 + for (nr_loops = 0; nr_loops < USECS_WAIT; nr_loops++) { + /* If the write is past the end of page, a writer is still updating it */ + if (likely(!reader || rb_page_write(reader) <= BUF_PAGE_SIZE)) + break; + + udelay(1); + + /* Get the latest version of the reader write value */ + smp_rmb(); + } + + /* The writer is not moving forward? Something is wrong */ + if (RB_WARN_ON(cpu_buffer, nr_loops == USECS_WAIT)) + reader = NULL; + + /* + * Make sure we see any padding after the write update + * (see rb_reset_tail()) + */ + smp_rmb(); + + return reader; } From 48272aa48d80a1ed877bc4398594def6c8e7920f Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Thu, 22 Sep 2022 10:56:22 -0400 Subject: [PATCH 111/610] tracing: Disable interrupt or preemption before acquiring arch_spinlock_t commit c0a581d7126c0bbc96163276f585fd7b4e4d8d0e upstream. It was found that some tracing functions in kernel/trace/trace.c acquire an arch_spinlock_t with preemption and irqs enabled. An example is the tracing_saved_cmdlines_size_read() function which intermittently causes a "BUG: using smp_processor_id() in preemptible" warning when the LTP read_all_proc test is run. That can be problematic in case preemption happens after acquiring the lock. Add the necessary preemption or interrupt disabling code in the appropriate places before acquiring an arch_spinlock_t. The convention here is to disable preemption for trace_cmdline_lock and interupt for max_lock. Link: https://lkml.kernel.org/r/20220922145622.1744826-1-longman@redhat.com Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Will Deacon Cc: Boqun Feng Cc: stable@vger.kernel.org Fixes: a35873a0993b ("tracing: Add conditional snapshot") Fixes: 939c7a4f04fc ("tracing: Introduce saved_cmdlines_size file") Suggested-by: Steven Rostedt Signed-off-by: Waiman Long Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d93f9c59f50e..61090aec498e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1181,12 +1181,14 @@ void *tracing_cond_snapshot_data(struct trace_array *tr) { void *cond_data = NULL; + local_irq_disable(); arch_spin_lock(&tr->max_lock); if (tr->cond_snapshot) cond_data = tr->cond_snapshot->cond_data; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); return cond_data; } @@ -1322,9 +1324,11 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data, goto fail_unlock; } + local_irq_disable(); arch_spin_lock(&tr->max_lock); tr->cond_snapshot = cond_snapshot; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); mutex_unlock(&trace_types_lock); @@ -1351,6 +1355,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr) { int ret = 0; + local_irq_disable(); arch_spin_lock(&tr->max_lock); if (!tr->cond_snapshot) @@ -1361,6 +1366,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr) } arch_spin_unlock(&tr->max_lock); + local_irq_enable(); return ret; } @@ -2187,6 +2193,11 @@ static size_t tgid_map_max; #define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX +/* + * Preemption must be disabled before acquiring trace_cmdline_lock. + * The various trace_arrays' max_lock must be acquired in a context + * where interrupt is disabled. + */ static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; struct saved_cmdlines_buffer { unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; @@ -2399,7 +2410,11 @@ static int trace_save_cmdline(struct task_struct *tsk) * the lock, but we also don't want to spin * nor do we want to disable interrupts, * so if we miss here, then better luck next time. + * + * This is called within the scheduler and wake up, so interrupts + * had better been disabled and run queue lock been held. */ + lockdep_assert_preemption_disabled(); if (!arch_spin_trylock(&trace_cmdline_lock)) return 0; @@ -5861,9 +5876,11 @@ tracing_saved_cmdlines_size_read(struct file *filp, char __user *ubuf, char buf[64]; int r; + preempt_disable(); arch_spin_lock(&trace_cmdline_lock); r = scnprintf(buf, sizeof(buf), "%u\n", savedcmd->cmdline_num); arch_spin_unlock(&trace_cmdline_lock); + preempt_enable(); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -5888,10 +5905,12 @@ static int tracing_resize_saved_cmdlines(unsigned int val) return -ENOMEM; } + preempt_disable(); arch_spin_lock(&trace_cmdline_lock); savedcmd_temp = savedcmd; savedcmd = s; arch_spin_unlock(&trace_cmdline_lock); + preempt_enable(); free_saved_cmdlines_buffer(savedcmd_temp); return 0; @@ -6344,10 +6363,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) #ifdef CONFIG_TRACER_SNAPSHOT if (t->use_max_tr) { + local_irq_disable(); arch_spin_lock(&tr->max_lock); if (tr->cond_snapshot) ret = -EBUSY; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); if (ret) goto out; } @@ -7420,10 +7441,12 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, goto out; } + local_irq_disable(); arch_spin_lock(&tr->max_lock); if (tr->cond_snapshot) ret = -EBUSY; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); if (ret) goto out; From 2475de2bc0de17fb1b24c5e90194f84b5ca70d3e Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 27 Sep 2022 19:15:27 -0400 Subject: [PATCH 112/610] tracing: Wake up ring buffer waiters on closing of the file commit f3ddb74ad0790030c9592229fb14d8c451f4e9a8 upstream. When the file that represents the ring buffer is closed, there may be waiters waiting on more input from the ring buffer. Call ring_buffer_wake_waiters() to wake up any waiters when the file is closed. Link: https://lkml.kernel.org/r/20220927231825.182416969@goodmis.org Cc: stable@vger.kernel.org Cc: Ingo Molnar Cc: Andrew Morton Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- include/linux/trace_events.h | 1 + kernel/trace/trace.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 57113190448c..ff137179e0c3 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -91,6 +91,7 @@ struct trace_iterator { unsigned int temp_size; char *fmt; /* modified format holder */ unsigned int fmt_size; + long wait_index; /* trace_seq for __print_flags() and __print_symbolic() etc. */ struct trace_seq tmp_seq; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 61090aec498e..bf0b693143d0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8117,6 +8117,12 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) __trace_array_put(iter->tr); + iter->wait_index++; + /* Make sure the waiters see the new wait_index */ + smp_wmb(); + + ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file); + if (info->spare) ring_buffer_free_read_page(iter->array_buffer->buffer, info->spare_cpu, info->spare); @@ -8270,6 +8276,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, /* did we read anything? */ if (!spd.nr_pages) { + long wait_index; + if (ret) goto out; @@ -8277,10 +8285,17 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) goto out; + wait_index = READ_ONCE(iter->wait_index); + ret = wait_on_pipe(iter, iter->tr->buffer_percent); if (ret) goto out; + /* Make sure we see the new wait_index */ + smp_rmb(); + if (wait_index != iter->wait_index) + goto out; + goto again; } From 32eb54a986f40a9a586a7c58c01e4916de78d57c Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 28 Sep 2022 18:22:20 -0400 Subject: [PATCH 113/610] tracing: Wake up waiters when tracing is disabled commit 2b0fd9a59b7990c161fa1cb7b79edb22847c87c2 upstream. When tracing is disabled, there's no reason that waiters should stay waiting, wake them up, otherwise tasks get stuck when they should be flushing the buffers. Cc: stable@vger.kernel.org Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bf0b693143d0..2f98c0a0e8a6 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8291,6 +8291,10 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, if (ret) goto out; + /* No need to wait after waking up when tracing is off */ + if (!tracer_tracing_is_on(iter->tr)) + goto out; + /* Make sure we see the new wait_index */ smp_rmb(); if (wait_index != iter->wait_index) @@ -9000,6 +9004,8 @@ rb_simple_write(struct file *filp, const char __user *ubuf, tracer_tracing_off(tr); if (tr->current_trace->stop) tr->current_trace->stop(tr); + /* Wake up any waiters */ + ring_buffer_wake_waiters(buffer, RING_BUFFER_ALL_CPUS); } mutex_unlock(&trace_types_lock); } From 84f4be2093e17481790eedf63ca15eee65832b36 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Thu, 29 Sep 2022 09:50:29 -0400 Subject: [PATCH 114/610] tracing: Add ioctl() to force ring buffer waiters to wake up commit 01b2a52171735c6eea80ee2f355f32bea6c41418 upstream. If a process is waiting on the ring buffer for data, there currently isn't a clean way to force it to wake up. Add an ioctl call that will force any tasks that are waiting on the trace_pipe_raw file to wake up. Link: https://lkml.kernel.org/r/20220929095029.117f913f@gandalf.local.home Cc: stable@vger.kernel.org Cc: Ingo Molnar Cc: Andrew Morton Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2f98c0a0e8a6..0dc17fd96102 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8310,12 +8310,34 @@ out: return ret; } +/* An ioctl call with cmd 0 to the ring buffer file will wake up all waiters */ +static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct ftrace_buffer_info *info = file->private_data; + struct trace_iterator *iter = &info->iter; + + if (cmd) + return -ENOIOCTLCMD; + + mutex_lock(&trace_types_lock); + + iter->wait_index++; + /* Make sure the waiters see the new wait_index */ + smp_wmb(); + + ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file); + + mutex_unlock(&trace_types_lock); + return 0; +} + static const struct file_operations tracing_buffers_fops = { .open = tracing_buffers_open, .read = tracing_buffers_read, .poll = tracing_buffers_poll, .release = tracing_buffers_release, .splice_read = tracing_buffers_splice_read, + .unlocked_ioctl = tracing_buffers_ioctl, .llseek = no_llseek, }; From 8ae88c4842c21f2d0d3d69fa02fe4538994253f8 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 12 Oct 2022 06:40:56 -0400 Subject: [PATCH 115/610] tracing: Move duplicate code of trace_kprobe/eprobe.c into header commit f1d3cbfaafc10464550c6d3a125f4fc802bbaed5 upstream. The functions: fetch_store_strlen_user() fetch_store_strlen() fetch_store_string_user() fetch_store_string() are identical in both trace_kprobe.c and trace_eprobe.c. Move them into a new header file trace_probe_kernel.h to share it. This code will later be used by the synthetic events as well. Marked for stable as a fix for a crash in synthetic events requires it. Link: https://lkml.kernel.org/r/20221012104534.467668078@goodmis.org Cc: stable@vger.kernel.org Cc: Andrew Morton Cc: Tom Zanussi Acked-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Fixes: bd82631d7ccdc ("tracing: Add support for dynamic strings to synthetic events") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_eprobe.c | 60 ++----------------- kernel/trace/trace_kprobe.c | 60 ++----------------- kernel/trace/trace_probe_kernel.h | 96 +++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 110 deletions(-) create mode 100644 kernel/trace/trace_probe_kernel.h diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index 32688357c6da..399e6d066348 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -16,6 +16,7 @@ #include "trace_dynevent.h" #include "trace_probe.h" #include "trace_probe_tmpl.h" +#include "trace_probe_kernel.h" #define EPROBE_EVENT_SYSTEM "eprobes" @@ -447,29 +448,14 @@ NOKPROBE_SYMBOL(process_fetch_insn) static nokprobe_inline int fetch_store_strlen_user(unsigned long addr) { - const void __user *uaddr = (__force const void __user *)addr; - - return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); + return kern_fetch_store_strlen_user(addr); } /* Return the length of string -- including null terminal byte */ static nokprobe_inline int fetch_store_strlen(unsigned long addr) { - int ret, len = 0; - u8 c; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if (addr < TASK_SIZE) - return fetch_store_strlen_user(addr); -#endif - - do { - ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1); - len++; - } while (c && ret == 0 && len < MAX_STRING_SIZE); - - return (ret < 0) ? ret : len; + return kern_fetch_store_strlen(addr); } /* @@ -479,21 +465,7 @@ fetch_store_strlen(unsigned long addr) static nokprobe_inline int fetch_store_string_user(unsigned long addr, void *dest, void *base) { - const void __user *uaddr = (__force const void __user *)addr; - int maxlen = get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest = get_loc_data(dest, base); - - ret = strncpy_from_user_nofault(__dest, uaddr, maxlen); - if (ret >= 0) - *(u32 *)dest = make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string_user(addr, dest, base); } /* @@ -503,29 +475,7 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base) static nokprobe_inline int fetch_store_string(unsigned long addr, void *dest, void *base) { - int maxlen = get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if ((unsigned long)addr < TASK_SIZE) - return fetch_store_string_user(addr, dest, base); -#endif - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest = get_loc_data(dest, base); - - /* - * Try to get string again, since the string can be changed while - * probing. - */ - ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); - if (ret >= 0) - *(u32 *)dest = make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string(addr, dest, base); } static nokprobe_inline int diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 6a9c1ef15d5d..e755e09805ab 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -19,6 +19,7 @@ #include "trace_kprobe_selftest.h" #include "trace_probe.h" #include "trace_probe_tmpl.h" +#include "trace_probe_kernel.h" #define KPROBE_EVENT_SYSTEM "kprobes" #define KRETPROBE_MAXACTIVE_MAX 4096 @@ -1223,29 +1224,14 @@ static const struct file_operations kprobe_profile_ops = { static nokprobe_inline int fetch_store_strlen_user(unsigned long addr) { - const void __user *uaddr = (__force const void __user *)addr; - - return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); + return kern_fetch_store_strlen_user(addr); } /* Return the length of string -- including null terminal byte */ static nokprobe_inline int fetch_store_strlen(unsigned long addr) { - int ret, len = 0; - u8 c; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if (addr < TASK_SIZE) - return fetch_store_strlen_user(addr); -#endif - - do { - ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1); - len++; - } while (c && ret == 0 && len < MAX_STRING_SIZE); - - return (ret < 0) ? ret : len; + return kern_fetch_store_strlen(addr); } /* @@ -1255,21 +1241,7 @@ fetch_store_strlen(unsigned long addr) static nokprobe_inline int fetch_store_string_user(unsigned long addr, void *dest, void *base) { - const void __user *uaddr = (__force const void __user *)addr; - int maxlen = get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest = get_loc_data(dest, base); - - ret = strncpy_from_user_nofault(__dest, uaddr, maxlen); - if (ret >= 0) - *(u32 *)dest = make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string_user(addr, dest, base); } /* @@ -1279,29 +1251,7 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base) static nokprobe_inline int fetch_store_string(unsigned long addr, void *dest, void *base) { - int maxlen = get_loc_len(*(u32 *)dest); - void *__dest; - long ret; - -#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE - if ((unsigned long)addr < TASK_SIZE) - return fetch_store_string_user(addr, dest, base); -#endif - - if (unlikely(!maxlen)) - return -ENOMEM; - - __dest = get_loc_data(dest, base); - - /* - * Try to get string again, since the string can be changed while - * probing. - */ - ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); - if (ret >= 0) - *(u32 *)dest = make_data_loc(ret, __dest - base); - - return ret; + return kern_fetch_store_string(addr, dest, base); } static nokprobe_inline int diff --git a/kernel/trace/trace_probe_kernel.h b/kernel/trace/trace_probe_kernel.h new file mode 100644 index 000000000000..1d43df29a1f8 --- /dev/null +++ b/kernel/trace/trace_probe_kernel.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __TRACE_PROBE_KERNEL_H_ +#define __TRACE_PROBE_KERNEL_H_ + +/* + * This depends on trace_probe.h, but can not include it due to + * the way trace_probe_tmpl.h is used by trace_kprobe.c and trace_eprobe.c. + * Which means that any other user must include trace_probe.h before including + * this file. + */ +/* Return the length of string -- including null terminal byte */ +static nokprobe_inline int +kern_fetch_store_strlen_user(unsigned long addr) +{ + const void __user *uaddr = (__force const void __user *)addr; + + return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); +} + +/* Return the length of string -- including null terminal byte */ +static nokprobe_inline int +kern_fetch_store_strlen(unsigned long addr) +{ + int ret, len = 0; + u8 c; + +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if (addr < TASK_SIZE) + return kern_fetch_store_strlen_user(addr); +#endif + + do { + ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1); + len++; + } while (c && ret == 0 && len < MAX_STRING_SIZE); + + return (ret < 0) ? ret : len; +} + +/* + * Fetch a null-terminated string from user. Caller MUST set *(u32 *)buf + * with max length and relative data location. + */ +static nokprobe_inline int +kern_fetch_store_string_user(unsigned long addr, void *dest, void *base) +{ + const void __user *uaddr = (__force const void __user *)addr; + int maxlen = get_loc_len(*(u32 *)dest); + void *__dest; + long ret; + + if (unlikely(!maxlen)) + return -ENOMEM; + + __dest = get_loc_data(dest, base); + + ret = strncpy_from_user_nofault(__dest, uaddr, maxlen); + if (ret >= 0) + *(u32 *)dest = make_data_loc(ret, __dest - base); + + return ret; +} + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max + * length and relative data location. + */ +static nokprobe_inline int +kern_fetch_store_string(unsigned long addr, void *dest, void *base) +{ + int maxlen = get_loc_len(*(u32 *)dest); + void *__dest; + long ret; + +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if ((unsigned long)addr < TASK_SIZE) + return kern_fetch_store_string_user(addr, dest, base); +#endif + + if (unlikely(!maxlen)) + return -ENOMEM; + + __dest = get_loc_data(dest, base); + + /* + * Try to get string again, since the string can be changed while + * probing. + */ + ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); + if (ret >= 0) + *(u32 *)dest = make_data_loc(ret, __dest - base); + + return ret; +} + +#endif /* __TRACE_PROBE_KERNEL_H_ */ From b9ab154d22b8eb15de1ed4a2569d5e4c86e32ef9 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 12 Oct 2022 06:40:57 -0400 Subject: [PATCH 116/610] tracing: Add "(fault)" name injection to kernel probes commit 2e9906f84fc7c99388bb7123ade167250d50f1c0 upstream. Have the specific functions for kernel probes that read strings to inject the "(fault)" name directly. trace_probes.c does this too (for uprobes) but as the code to read strings are going to be used by synthetic events (and perhaps other utilities), it simplifies the code by making sure those other uses do not need to implement the "(fault)" name injection as well. Link: https://lkml.kernel.org/r/20221012104534.644803645@goodmis.org Cc: stable@vger.kernel.org Cc: Andrew Morton Cc: Tom Zanussi Acked-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Fixes: bd82631d7ccdc ("tracing: Add support for dynamic strings to synthetic events") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_probe_kernel.h | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_probe_kernel.h b/kernel/trace/trace_probe_kernel.h index 1d43df29a1f8..77dbd9ff9782 100644 --- a/kernel/trace/trace_probe_kernel.h +++ b/kernel/trace/trace_probe_kernel.h @@ -2,6 +2,8 @@ #ifndef __TRACE_PROBE_KERNEL_H_ #define __TRACE_PROBE_KERNEL_H_ +#define FAULT_STRING "(fault)" + /* * This depends on trace_probe.h, but can not include it due to * the way trace_probe_tmpl.h is used by trace_kprobe.c and trace_eprobe.c. @@ -13,8 +15,16 @@ static nokprobe_inline int kern_fetch_store_strlen_user(unsigned long addr) { const void __user *uaddr = (__force const void __user *)addr; + int ret; - return strnlen_user_nofault(uaddr, MAX_STRING_SIZE); + ret = strnlen_user_nofault(uaddr, MAX_STRING_SIZE); + /* + * strnlen_user_nofault returns zero on fault, insert the + * FAULT_STRING when that occurs. + */ + if (ret <= 0) + return strlen(FAULT_STRING) + 1; + return ret; } /* Return the length of string -- including null terminal byte */ @@ -34,7 +44,18 @@ kern_fetch_store_strlen(unsigned long addr) len++; } while (c && ret == 0 && len < MAX_STRING_SIZE); - return (ret < 0) ? ret : len; + /* For faults, return enough to hold the FAULT_STRING */ + return (ret < 0) ? strlen(FAULT_STRING) + 1 : len; +} + +static nokprobe_inline void set_data_loc(int ret, void *dest, void *__dest, void *base, int len) +{ + if (ret >= 0) { + *(u32 *)dest = make_data_loc(ret, __dest - base); + } else { + strscpy(__dest, FAULT_STRING, len); + ret = strlen(__dest) + 1; + } } /* @@ -55,8 +76,7 @@ kern_fetch_store_string_user(unsigned long addr, void *dest, void *base) __dest = get_loc_data(dest, base); ret = strncpy_from_user_nofault(__dest, uaddr, maxlen); - if (ret >= 0) - *(u32 *)dest = make_data_loc(ret, __dest - base); + set_data_loc(ret, dest, __dest, base, maxlen); return ret; } @@ -87,8 +107,7 @@ kern_fetch_store_string(unsigned long addr, void *dest, void *base) * probing. */ ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen); - if (ret >= 0) - *(u32 *)dest = make_data_loc(ret, __dest - base); + set_data_loc(ret, dest, __dest, base, maxlen); return ret; } From d9c79fbcbdb6cb10c07c85040eaf615180b26c48 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 12 Oct 2022 06:40:58 -0400 Subject: [PATCH 117/610] tracing: Fix reading strings from synthetic events commit 0934ae9977c27133449b6dd8c6213970e7eece38 upstream. The follow commands caused a crash: # cd /sys/kernel/tracing # echo 's:open char file[]' > dynamic_events # echo 'hist:keys=common_pid:file=filename:onchange($file).trace(open,$file)' > events/syscalls/sys_enter_openat/trigger' # echo 1 > events/synthetic/open/enable BOOM! The problem is that the synthetic event field "char file[]" will read the value given to it as a string without any memory checks to make sure the address is valid. The above example will pass in the user space address and the sythetic event code will happily call strlen() on it and then strscpy() where either one will cause an oops when accessing user space addresses. Use the helper functions from trace_kprobe and trace_eprobe that can read strings safely (and actually succeed when the address is from user space and the memory is mapped in). Now the above can show: packagekitd-1721 [000] ...2. 104.597170: open: file=/usr/lib/rpm/fileattrs/cmake.attr in:imjournal-978 [006] ...2. 104.599642: open: file=/var/lib/rsyslog/imjournal.state.tmp packagekitd-1721 [000] ...2. 104.626308: open: file=/usr/lib/rpm/fileattrs/debuginfo.attr Link: https://lkml.kernel.org/r/20221012104534.826549315@goodmis.org Cc: stable@vger.kernel.org Cc: Andrew Morton Cc: Tom Zanussi Acked-by: Masami Hiramatsu (Google) Reviewed-by: Tom Zanussi Fixes: bd82631d7ccdc ("tracing: Add support for dynamic strings to synthetic events") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events_synth.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 8c26092db8de..bc7dd0653b05 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -17,6 +17,8 @@ /* for gfp flag names */ #include #include +#include "trace_probe.h" +#include "trace_probe_kernel.h" #include "trace_synth.h" @@ -401,6 +403,7 @@ static unsigned int trace_string(struct synth_trace_event *entry, { unsigned int len = 0; char *str_field; + int ret; if (is_dynamic) { u32 data_offset; @@ -409,19 +412,27 @@ static unsigned int trace_string(struct synth_trace_event *entry, data_offset += event->n_u64 * sizeof(u64); data_offset += data_size; - str_field = (char *)entry + data_offset; - - len = strlen(str_val) + 1; - strscpy(str_field, str_val, len); + len = kern_fetch_store_strlen((unsigned long)str_val); data_offset |= len << 16; *(u32 *)&entry->fields[*n_u64] = data_offset; + ret = kern_fetch_store_string((unsigned long)str_val, &entry->fields[*n_u64], entry); + (*n_u64)++; } else { str_field = (char *)&entry->fields[*n_u64]; - strscpy(str_field, str_val, STR_VAR_LEN_MAX); +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if ((unsigned long)str_val < TASK_SIZE) + ret = strncpy_from_user_nofault(str_field, str_val, STR_VAR_LEN_MAX); + else +#endif + ret = strncpy_from_kernel_nofault(str_field, str_val, STR_VAR_LEN_MAX); + + if (ret < 0) + strcpy(str_field, FAULT_STRING); + (*n_u64) += STR_VAR_LEN_MAX / sizeof(u64); } @@ -454,7 +465,7 @@ static notrace void trace_event_raw_event_synth(void *__data, val_idx = var_ref_idx[field_pos]; str_val = (char *)(long)var_ref_vals[val_idx]; - len = strlen(str_val) + 1; + len = kern_fetch_store_strlen((unsigned long)str_val); fields_size += len; } From 5cda4a11b4906ddd037b216845e7f9c96ac93772 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 26 Sep 2022 09:33:50 -0500 Subject: [PATCH 118/610] thunderbolt: Explicitly enable lane adapter hotplug events at startup commit 5d2569cb4a65c373896ec0217febdf88739ed295 upstream. Software that has run before the USB4 CM in Linux runs may have disabled hotplug events for a given lane adapter. Other CMs such as that one distributed with Windows 11 will enable hotplug events. Do the same thing in the Linux CM which fixes hotplug events on "AMD Pink Sardine". Cc: stable@vger.kernel.org Signed-off-by: Mario Limonciello Signed-off-by: Mika Westerberg Signed-off-by: Greg Kroah-Hartman --- drivers/thunderbolt/switch.c | 24 ++++++++++++++++++++++++ drivers/thunderbolt/tb.h | 1 + drivers/thunderbolt/tb_regs.h | 1 + drivers/thunderbolt/usb4.c | 20 ++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 50a5b160ccde..ef647477ab38 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -2690,6 +2690,26 @@ static void tb_switch_credits_init(struct tb_switch *sw) tb_sw_info(sw, "failed to determine preferred buffer allocation, using defaults\n"); } +static int tb_switch_port_hotplug_enable(struct tb_switch *sw) +{ + struct tb_port *port; + + if (tb_switch_is_icm(sw)) + return 0; + + tb_switch_for_each_port(sw, port) { + int res; + + if (!port->cap_usb4) + continue; + + res = usb4_port_hotplug_enable(port); + if (res) + return res; + } + return 0; +} + /** * tb_switch_add() - Add a switch to the domain * @sw: Switch to add @@ -2761,6 +2781,10 @@ int tb_switch_add(struct tb_switch *sw) return ret; } + ret = tb_switch_port_hotplug_enable(sw); + if (ret) + return ret; + ret = device_add(&sw->dev); if (ret) { dev_err(&sw->dev, "failed to add device: %d\n", ret); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 725104c83e3d..b535d296d37e 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1067,6 +1067,7 @@ int usb4_switch_add_ports(struct tb_switch *sw); void usb4_switch_remove_ports(struct tb_switch *sw); int usb4_port_unlock(struct tb_port *port); +int usb4_port_hotplug_enable(struct tb_port *port); int usb4_port_configure(struct tb_port *port); void usb4_port_unconfigure(struct tb_port *port); int usb4_port_configure_xdomain(struct tb_port *port); diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index 484f25be2849..67f21e6c1813 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -301,6 +301,7 @@ struct tb_regs_port_header { #define ADP_CS_5 0x05 #define ADP_CS_5_LCA_MASK GENMASK(28, 22) #define ADP_CS_5_LCA_SHIFT 22 +#define ADP_CS_5_DHP BIT(31) /* TMU adapter registers */ #define TMU_ADP_CS_3 0x03 diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index ceddbe7e9f93..90986567f1f9 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -1068,6 +1068,26 @@ int usb4_port_unlock(struct tb_port *port) return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_4, 1); } +/** + * usb4_port_hotplug_enable() - Enables hotplug for a port + * @port: USB4 port to operate on + * + * Enables hot plug events on a given port. This is only intended + * to be used on lane, DP-IN, and DP-OUT adapters. + */ +int usb4_port_hotplug_enable(struct tb_port *port) +{ + int ret; + u32 val; + + ret = tb_port_read(port, &val, TB_CFG_PORT, ADP_CS_5, 1); + if (ret) + return ret; + + val &= ~ADP_CS_5_DHP; + return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_5, 1); +} + static int usb4_port_set_configured(struct tb_port *port, bool configured) { int ret; From b19254eadab3270de20a4fd3125a7052c4a23110 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 15 Sep 2022 19:00:24 +0200 Subject: [PATCH 119/610] efi: libstub: drop pointless get_memory_map() call commit d80ca810f096ff66f451e7a3ed2f0cd9ef1ff519 upstream. Currently, the non-x86 stub code calls get_memory_map() redundantly, given that the data it returns is never used anywhere. So drop the call. Cc: # v4.14+ Fixes: 24d7c494ce46 ("efi/arm-stub: Round up FDT allocation to mapping size") Signed-off-by: Ard Biesheuvel Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efi/libstub/fdt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index fe567be0f118..804f542be3f2 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -280,14 +280,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, goto fail; } - /* - * Now that we have done our final memory allocation (and free) - * we can get the memory map key needed for exit_boot_services(). - */ - status = efi_get_memory_map(&map); - if (status != EFI_SUCCESS) - goto fail_free_new_fdt; - status = update_fdt((void *)fdt_addr, fdt_size, (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, initrd_addr, initrd_size); From b76fac61c33f8e8161e310d3366256d64067571c Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 18 Aug 2022 22:33:07 +0200 Subject: [PATCH 120/610] media: cedrus: Set the platform driver data earlier commit 708938f8495147fe2e77a9a3e1015d8e6899323e upstream. The cedrus_hw_resume() crashes with NULL deference on driver probe if runtime PM is disabled because it uses platform data that hasn't been set up yet. Fix this by setting the platform data earlier during probe. Cc: stable@vger.kernel.org Fixes: 50e761516f2b (media: platform: Add Cedrus VPU decoder driver) Signed-off-by: Dmitry Osipenko Signed-off-by: Nicolas Dufresne Reviewed-by: Samuel Holland Acked-by: Paul Kocialkowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/sunxi/cedrus/cedrus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index c0d005dafc6c..b1755407547b 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -369,6 +369,8 @@ static int cedrus_probe(struct platform_device *pdev) if (!dev) return -ENOMEM; + platform_set_drvdata(pdev, dev); + dev->vfd = cedrus_video_device; dev->dev = &pdev->dev; dev->pdev = pdev; @@ -440,8 +442,6 @@ static int cedrus_probe(struct platform_device *pdev) goto err_m2m_mc; } - platform_set_drvdata(pdev, dev); - return 0; err_m2m_mc: From e8e0a6f4b8a299a660a398bf0bae87704d0fd144 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 18 Aug 2022 22:33:08 +0200 Subject: [PATCH 121/610] media: cedrus: Fix endless loop in cedrus_h265_skip_bits() commit 91db7a3fc7fe670cf1770a398a43bb4a1f776bf1 upstream. The busy status bit may never de-assert if number of programmed skip bits is incorrect, resulting in a kernel hang because the bit is polled endlessly in the code. Fix it by adding timeout for the bit-polling. This problem is reproducible by setting the data_bit_offset field of the HEVC slice params to a wrong value by userspace. Cc: stable@vger.kernel.org Fixes: 7678c5462680 (media: cedrus: Fix decoding for some HEVC videos) Reported-by: Nicolas Dufresne Signed-off-by: Dmitry Osipenko Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index 830cae03fc6e..f2d9603a9ffb 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -234,8 +234,9 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num) cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_FLUSH_BITS | VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp)); - while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY) - udelay(1); + + if (cedrus_wait_for(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_VLD_BUSY)) + dev_err_ratelimited(dev->dev, "timed out waiting to skip bits\n"); count += tmp; } From e3e5baa368798be702285ddc6ece4eaf57237378 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Tue, 13 Sep 2022 18:57:49 +0800 Subject: [PATCH 122/610] blk-wbt: call rq_qos_add() after wb_normal is initialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 8c5035dfbb9475b67c82b3fdb7351236525bf52b upstream. Our test found a problem that wbt inflight counter is negative, which will cause io hang(noted that this problem doesn't exist in mainline): t1: device create t2: issue io add_disk blk_register_queue wbt_enable_default wbt_init rq_qos_add // wb_normal is still 0 /* * in mainline, disk can't be opened before * bdev_add(), however, in old kernels, disk * can be opened before blk_register_queue(). */ blkdev_issue_flush // disk size is 0, however, it's not checked submit_bio_wait submit_bio blk_mq_submit_bio rq_qos_throttle wbt_wait bio_to_wbt_flags rwb_enabled // wb_normal is 0, inflight is not increased wbt_queue_depth_changed(&rwb->rqos); wbt_update_limits // wb_normal is initialized rq_qos_track wbt_track rq->wbt_flags |= bio_to_wbt_flags(rwb, bio); // wb_normal is not 0,wbt_flags will be set t3: io completion blk_mq_free_request rq_qos_done wbt_done wbt_is_tracked // return true __wbt_done wbt_rqw_done atomic_dec_return(&rqw->inflight); // inflight is decreased commit 8235b5c1e8c1 ("block: call bdev_add later in device_add_disk") can avoid this problem, however it's better to fix this problem in wbt: 1) Lower kernel can't backport this patch due to lots of refactor. 2) Root cause is that wbt call rq_qos_add() before wb_normal is initialized. Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism") Cc: Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20220913105749.3086243-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/blk-wbt.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index ae6ea0b54579..d5aa2a32df25 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -843,6 +843,10 @@ int wbt_init(struct request_queue *q) rwb->enable_state = WBT_STATE_ON_DEFAULT; rwb->wc = 1; rwb->rq_depth.default_depth = RWB_DEF_DEPTH; + rwb->min_lat_nsec = wbt_default_latency_nsec(q); + + wbt_queue_depth_changed(&rwb->rqos); + wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags)); /* * Assign rwb and add the stats callback. @@ -853,11 +857,6 @@ int wbt_init(struct request_queue *q) blk_stat_add_callback(q, rwb->cb); - rwb->min_lat_nsec = wbt_default_latency_nsec(q); - - wbt_queue_depth_changed(&rwb->rqos); - wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags)); - return 0; err_free: From 379de01906eb60356a4f9b6d66735d33add9d9dc Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Mon, 22 Aug 2022 00:06:47 +0200 Subject: [PATCH 123/610] KVM: x86/emulator: Fix handing of POP SS to correctly set interruptibility commit 6aa5c47c351b22c21205c87977c84809cd015fcf upstream. The emulator checks the wrong variable while setting the CPU interruptibility state, the target segment is embedded in the instruction opcode, not the ModR/M register. Fix the condition. Signed-off-by: Michal Luczaj Fixes: a5457e7bcf9a ("KVM: emulate: POP SS triggers a MOV SS shadow too") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20220821215900.1419215-1-mhal@rbox.co Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/emulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 3b4e1d8d239a..45d82a950132 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1936,7 +1936,7 @@ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt) if (rc != X86EMUL_CONTINUE) return rc; - if (ctxt->modrm_reg == VCPU_SREG_SS) + if (seg == VCPU_SREG_SS) ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS; if (ctxt->op_bytes > 2) rsp_increment(ctxt, ctxt->op_bytes - 2); From be1a6a61f1b3b39d054e0aa274486085a064e743 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 30 Aug 2022 23:15:48 +0000 Subject: [PATCH 124/610] KVM: nVMX: Unconditionally purge queued/injected events on nested "exit" commit d953540430c5af57f5de97ea9e36253908204027 upstream. Drop pending exceptions and events queued for re-injection when leaving nested guest mode, even if the "exit" is due to VM-Fail, SMI, or forced by host userspace. Failure to purge events could result in an event belonging to L2 being injected into L1. This _should_ never happen for VM-Fail as all events should be blocked by nested_run_pending, but it's possible if KVM, not the L1 hypervisor, is the source of VM-Fail when running vmcs02. SMI is a nop (barring unknown bugs) as recognition of SMI and thus entry to SMM is blocked by pending exceptions and re-injected events. Forced exit is definitely buggy, but has likely gone unnoticed because userspace probably follows the forced exit with KVM_SET_VCPU_EVENTS (or some other ioctl() that purges the queue). Fixes: 4f350c6dbcb9 ("kvm: nVMX: Handle deferred early VMLAUNCH/VMRESUME failure properly") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Reviewed-by: Jim Mattson Reviewed-by: Maxim Levitsky Link: https://lore.kernel.org/r/20220830231614.3580124-2-seanjc@google.com Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/nested.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 61d601387058..23c51954c0d1 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4251,14 +4251,6 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, nested_vmx_abort(vcpu, VMX_ABORT_SAVE_GUEST_MSR_FAIL); } - - /* - * Drop what we picked up for L2 via vmx_complete_interrupts. It is - * preserved above and would only end up incorrectly in L1. - */ - vcpu->arch.nmi_injected = false; - kvm_clear_exception_queue(vcpu); - kvm_clear_interrupt_queue(vcpu); } /* @@ -4598,6 +4590,17 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, WARN_ON_ONCE(nested_early_check); } + /* + * Drop events/exceptions that were queued for re-injection to L2 + * (picked up via vmx_complete_interrupts()), as well as exceptions + * that were pending for L2. Note, this must NOT be hoisted above + * prepare_vmcs12(), events/exceptions queued for re-injection need to + * be captured in vmcs12 (see vmcs12_save_pending_event()). + */ + vcpu->arch.nmi_injected = false; + kvm_clear_exception_queue(vcpu); + kvm_clear_interrupt_queue(vcpu); + vmx_switch_vmcs(vcpu, &vmx->vmcs01); /* Update any VMCS fields that might have changed while L2 ran */ From 4f7b1e7d0f3662d44fa1fece54d4ec3c4731ed4d Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 30 Aug 2022 15:37:21 +0200 Subject: [PATCH 125/610] KVM: nVMX: Don't propagate vmcs12's PERF_GLOBAL_CTRL settings to vmcs02 commit def9d705c05eab3fdedeb10ad67907513b12038e upstream. Don't propagate vmcs12's VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL to vmcs02. KVM doesn't disallow L1 from using VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL even when KVM itself doesn't use the control, e.g. due to the various CPU errata that where the MSR can be corrupted on VM-Exit. Preserve KVM's (vmcs01) setting to hopefully avoid having to toggle the bit in vmcs02 at a later point. E.g. if KVM is loading PERF_GLOBAL_CTRL when running L1, then odds are good KVM will also load the MSR when running L2. Fixes: 8bf00a529967 ("KVM: VMX: add support for switching of PERF_GLOBAL_CTRL") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Signed-off-by: Vitaly Kuznetsov Link: https://lore.kernel.org/r/20220830133737.1539624-18-vkuznets@redhat.com Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/nested.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 23c51954c0d1..96e589edf960 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2313,9 +2313,14 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0 * are emulated by vmx_set_efer() in prepare_vmcs02(), but speculate * on the related bits (if supported by the CPU) in the hope that * we can avoid VMWrites during vmx_set_efer(). + * + * Similarly, take vmcs01's PERF_GLOBAL_CTRL in the hope that if KVM is + * loading PERF_GLOBAL_CTRL via the VMCS for L1, then KVM will want to + * do the same for L2. */ exec_control = __vm_entry_controls_get(vmcs01); - exec_control |= vmcs12->vm_entry_controls; + exec_control |= (vmcs12->vm_entry_controls & + ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL); exec_control &= ~(VM_ENTRY_IA32E_MODE | VM_ENTRY_LOAD_IA32_EFER); if (cpu_has_load_ia32_efer()) { if (guest_efer & EFER_LMA) From 28eb4bdb23e212bd70a5af8ba03d858db41c7036 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 30 Aug 2022 23:15:49 +0000 Subject: [PATCH 126/610] KVM: VMX: Drop bits 31:16 when shoving exception error code into VMCS commit eba9799b5a6efe2993cf92529608e4aa8163d73b upstream. Deliberately truncate the exception error code when shoving it into the VMCS (VM-Entry field for vmcs01 and vmcs02, VM-Exit field for vmcs12). Intel CPUs are incapable of handling 32-bit error codes and will never generate an error code with bits 31:16, but userspace can provide an arbitrary error code via KVM_SET_VCPU_EVENTS. Failure to drop the bits on exception injection results in failed VM-Entry, as VMX disallows setting bits 31:16. Setting the bits on VM-Exit would at best confuse L1, and at worse induce a nested VM-Entry failure, e.g. if L1 decided to reinject the exception back into L2. Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Reviewed-by: Jim Mattson Reviewed-by: Maxim Levitsky Link: https://lore.kernel.org/r/20220830231614.3580124-3-seanjc@google.com Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/nested.c | 11 ++++++++++- arch/x86/kvm/vmx/vmx.c | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 96e589edf960..91b182fafb43 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3826,7 +3826,16 @@ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu, u32 intr_info = nr | INTR_INFO_VALID_MASK; if (vcpu->arch.exception.has_error_code) { - vmcs12->vm_exit_intr_error_code = vcpu->arch.exception.error_code; + /* + * Intel CPUs do not generate error codes with bits 31:16 set, + * and more importantly VMX disallows setting bits 31:16 in the + * injected error code for VM-Entry. Drop the bits to mimic + * hardware and avoid inducing failure on nested VM-Entry if L1 + * chooses to inject the exception back to L2. AMD CPUs _do_ + * generate "full" 32-bit error codes, so KVM allows userspace + * to inject exception error codes with bits 31:16 set. + */ + vmcs12->vm_exit_intr_error_code = (u16)vcpu->arch.exception.error_code; intr_info |= INTR_INFO_DELIVER_CODE_MASK; } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e5584e974c77..ba457167ae8a 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1676,7 +1676,17 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu) kvm_deliver_exception_payload(vcpu); if (has_error_code) { - vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); + /* + * Despite the error code being architecturally defined as 32 + * bits, and the VMCS field being 32 bits, Intel CPUs and thus + * VMX don't actually supporting setting bits 31:16. Hardware + * will (should) never provide a bogus error code, but AMD CPUs + * do generate error codes with bits 31:16 set, and so KVM's + * ABI lets userspace shove in arbitrary 32-bit values. Drop + * the upper bits to avoid VM-Fail, losing information that + * does't really exist is preferable to killing the VM. + */ + vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, (u16)error_code); intr_info |= INTR_INFO_DELIVER_CODE_MASK; } From 4dab0d27a4211a27135a6899d6c737e6e0759a11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 2 Sep 2022 16:37:15 +0200 Subject: [PATCH 127/610] staging: greybus: audio_helper: remove unused and wrong debugfs usage commit d517cdeb904ddc0cbebcc959d43596426cac40b0 upstream. In the greybus audio_helper code, the debugfs file for the dapm has the potential to be removed and memory will be leaked. There is also the very real potential for this code to remove ALL debugfs entries from the system, and it seems like this is what will really happen if this code ever runs. This all is very wrong as the greybus audio driver did not create this debugfs file, the sound core did and controls the lifespan of it. So remove all of the debugfs logic from the audio_helper code as there's no way it could be correct. If this really is needed, it can come back with a fixup for the incorrect usage of the debugfs_lookup() call which is what caused this to be noticed at all. Cc: Johan Hovold Cc: Alex Elder Cc: Greg Kroah-Hartman Cc: stable Link: https://lore.kernel.org/r/20220902143715.320500-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/audio_helper.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/greybus/audio_helper.c b/drivers/staging/greybus/audio_helper.c index 843760675876..79bb2bd8e000 100644 --- a/drivers/staging/greybus/audio_helper.c +++ b/drivers/staging/greybus/audio_helper.c @@ -3,7 +3,6 @@ * Greybus Audio Sound SoC helper APIs */ -#include #include #include #include @@ -116,10 +115,6 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm, { int i; struct snd_soc_dapm_widget *w, *next_w; -#ifdef CONFIG_DEBUG_FS - struct dentry *parent = dapm->debugfs_dapm; - struct dentry *debugfs_w = NULL; -#endif mutex_lock(&dapm->card->dapm_mutex); for (i = 0; i < num; i++) { @@ -139,12 +134,6 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm, continue; } widget++; -#ifdef CONFIG_DEBUG_FS - if (!parent) - debugfs_w = debugfs_lookup(w->name, parent); - debugfs_remove(debugfs_w); - debugfs_w = NULL; -#endif gbaudio_dapm_free_widget(w); } mutex_unlock(&dapm->card->dapm_mutex); From 446d40e2a8cbf2d53bcf066edab412e6867c6a1b Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Tue, 16 Aug 2022 14:04:36 -0400 Subject: [PATCH 128/610] drm/nouveau/kms/nv140-: Disable interlacing commit 8ba9249396bef37cb68be9e8dee7847f1737db9d upstream. As it turns out: while Nvidia does actually have interlacing knobs on their GPU still pretty much no current GPUs since Volta actually support it. Trying interlacing on these GPUs will result in NVDisplay being quite unhappy like so: nouveau 0000:1f:00.0: disp: chid 0 stat 00004802 reason 4 [INVALID_ARG] mthd 2008 data 00000001 code 00080000 nouveau 0000:1f:00.0: disp: chid 0 stat 10005080 reason 5 [INVALID_STATE] mthd 0200 data 00000001 code 00000001 So let's fix this by following the same behavior Nvidia's driver does and disable interlacing entirely. Signed-off-by: Lyude Paul Cc: stable@vger.kernel.org Reviewed-by: Karol Herbst Link: https://patchwork.freedesktop.org/patch/msgid/20220816180436.156310-1-lyude@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index df83c4654e26..96be2ecb86d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -503,7 +503,8 @@ nouveau_connector_set_encoder(struct drm_connector *connector, connector->interlace_allowed = nv_encoder->caps.dp_interlace; else - connector->interlace_allowed = true; + connector->interlace_allowed = + drm->client.device.info.family < NV_DEVICE_INFO_V0_VOLTA; connector->doublescan_allowed = true; } else if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS || From 861f085f81fd569b02cc2c11165a9e6cca144424 Mon Sep 17 00:00:00 2001 From: Jianglei Nie Date: Tue, 5 Jul 2022 21:25:46 +0800 Subject: [PATCH 129/610] drm/nouveau: fix a use-after-free in nouveau_gem_prime_import_sg_table() commit 540dfd188ea2940582841c1c220bd035a7db0e51 upstream. nouveau_bo_init() is backed by ttm_bo_init() and ferries its return code back to the caller. On failures, ttm will call nouveau_bo_del_ttm() and free the memory.Thus, when nouveau_bo_init() returns an error, the gem object has already been released. Then the call to nouveau_bo_ref() will use the freed "nvbo->bo" and lead to a use-after-free bug. We should delete the call to nouveau_bo_ref() to avoid the use-after-free. Signed-off-by: Jianglei Nie Reviewed-by: Lyude Paul Signed-off-by: Lyude Paul Fixes: 019cbd4a4feb ("drm/nouveau: Initialize GEM object before TTM object") Cc: Thierry Reding Cc: # v5.4+ Link: https://patchwork.freedesktop.org/patch/msgid/20220705132546.2247677-1-niejianglei2021@163.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/nouveau/nouveau_prime.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index 60019d0532fc..531615719f6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -71,7 +71,6 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev, ret = nouveau_bo_init(nvbo, size, align, NOUVEAU_GEM_DOMAIN_GART, sg, robj); if (ret) { - nouveau_bo_ref(NULL, &nvbo); obj = ERR_PTR(ret); goto unlock; } From 20018a252f19d4e5437a77dbc69e56c4a72a2ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 3 Oct 2022 14:15:39 +0300 Subject: [PATCH 130/610] drm/i915: Fix watermark calculations for gen12+ RC CCS modifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit c56453a00f19ccddee302f5f9fe96b80e0b47fd3 upstream. Take the gen12+ RC CCS modifier into account when calculating the watermarks. Othwerwise we'll calculate the watermarks thinking this Y-tiled modifier is linear. The rc_surface part is actually a nop since that is not used for any glk+ platform. v2: Split RC CCS vs. MC CCS to separate patches Cc: stable@vger.kernel.org Fixes: b3e57bccd68a ("drm/i915/tgl: Gen-12 render decompression") Reviewed-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20221003111544.8007-2-ville.syrjala@linux.intel.com (cherry picked from commit a89a96a586114f67598c6391c75678b4dba5c2da) Signed-off-by: Tvrtko Ursulin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9123baf723d8..4b67dd85bea8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5402,10 +5402,12 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, wp->y_tiled = modifier == I915_FORMAT_MOD_Y_TILED || modifier == I915_FORMAT_MOD_Yf_TILED || modifier == I915_FORMAT_MOD_Y_TILED_CCS || - modifier == I915_FORMAT_MOD_Yf_TILED_CCS; + modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS; wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED; wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS || - modifier == I915_FORMAT_MOD_Yf_TILED_CCS; + modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS; wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier); wp->width = width; From 01bd3eaa53711e42e7378f2d91665a29f7666f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 3 Oct 2022 14:15:40 +0300 Subject: [PATCH 131/610] drm/i915: Fix watermark calculations for gen12+ MC CCS modifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 484b2b9281000274ef7c5cb0a9ebc5da6f5c281c upstream. Take the gen12+ MC CCS modifier into account when calculating the watermarks. Othwerwise we'll calculate the watermarks thinking this Y-tiled modifier is linear. The rc_surface part is actually a nop since that is not used for any glk+ platform. v2: Split RC CCS vs. MC CCS to separate patches Cc: stable@vger.kernel.org Fixes: 2dfbf9d2873a ("drm/i915/tgl: Gen-12 display can decompress surfaces compressed by the media engine") Reviewed-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20221003111544.8007-3-ville.syrjala@linux.intel.com (cherry picked from commit 91c9651425fe955b1387f3637607dda005f3f710) Signed-off-by: Tvrtko Ursulin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4b67dd85bea8..59bd37880d38 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5403,11 +5403,13 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, modifier == I915_FORMAT_MOD_Yf_TILED || modifier == I915_FORMAT_MOD_Y_TILED_CCS || modifier == I915_FORMAT_MOD_Yf_TILED_CCS || - modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS; + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED; wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS || modifier == I915_FORMAT_MOD_Yf_TILED_CCS || - modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS; + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier); wp->width = width; From 60a5174525609969b710ddd4a68586516cd4b63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 3 Oct 2022 14:15:41 +0300 Subject: [PATCH 132/610] drm/i915: Fix watermark calculations for gen12+ CCS+CC modifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 070a2855900de17b1e11a0dc35af9794e80f1a28 upstream. Take the gen12+ CCS+CC modifier into account when calculating the watermarks. Othwerwise we'll calculate the watermarks thinking this Y-tiled modifier is linear. The rc_surface part is actually a nop since that is not used for any glk+ platform. Cc: stable@vger.kernel.org Fixes: d1e2775e9b96 ("drm/i915/tgl: Add Clear Color support for TGL Render Decompression") Reviewed-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20221003111544.8007-4-ville.syrjala@linux.intel.com (cherry picked from commit a627455bbe50a111475d7a42beb58fa64bd96c83) Signed-off-by: Tvrtko Ursulin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 59bd37880d38..614cb84f2cee 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5404,12 +5404,14 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, modifier == I915_FORMAT_MOD_Y_TILED_CCS || modifier == I915_FORMAT_MOD_Yf_TILED_CCS || modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || - modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC; wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED; wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS || modifier == I915_FORMAT_MOD_Yf_TILED_CCS || modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || - modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC; wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier); wp->width = width; From adf428ae46be7920fa74dc1ef9395c101a33960c Mon Sep 17 00:00:00 2001 From: Yunxiang Li Date: Wed, 21 Sep 2022 17:20:19 -0400 Subject: [PATCH 133/610] drm/amd/display: Fix vblank refcount in vrr transition commit 8799c0be89ebb99a16098bdf618f49f817bef76a upstream. manage_dm_interrupts disable/enable vblank using drm_crtc_vblank_off/on which causes drm_crtc_vblank_get in vrr_transition to fail, and later when drm_crtc_vblank_put is called the refcount on vblank will be messed up. Therefore move the call to after manage_dm_interrupts. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1247 Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1380 Tested-by: Daniel Wheeler Reviewed-by: Rodrigo Siqueira Signed-off-by: Yunxiang Li Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 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 c826fc493e0f..9b815950b860 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8860,15 +8860,15 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, * We also need vupdate irq for the actual core vblank handling * at end of vblank. */ - dm_set_vupdate_irq(new_state->base.crtc, true); - drm_crtc_vblank_get(new_state->base.crtc); + WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0); + WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0); DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", __func__, new_state->base.crtc->base.id); } else if (old_vrr_active && !new_vrr_active) { /* Transition VRR active -> inactive: * Allow vblank irq disable again for fixed refresh rate. */ - dm_set_vupdate_irq(new_state->base.crtc, false); + WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0); drm_crtc_vblank_put(new_state->base.crtc); DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", __func__, new_state->base.crtc->base.id); @@ -9604,23 +9604,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) mutex_unlock(&dm->dc_lock); } - /* Count number of newly disabled CRTCs for dropping PM refs later. */ - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { - if (old_crtc_state->active && !new_crtc_state->active) - crtc_disable_count++; - - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); - dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - - /* For freesync config update on crtc state and params for irq */ - update_stream_irq_parameters(dm, dm_new_crtc_state); - - /* Handle vrr on->off / off->on transitions */ - amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, - dm_new_crtc_state); - } - /** * Enable interrupts for CRTCs that are newly enabled or went through * a modeset. It was intentionally deferred until after the front end @@ -9630,16 +9613,29 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); #ifdef CONFIG_DEBUG_FS - bool configure_crc = false; enum amdgpu_dm_pipe_crc_source cur_crc_src; #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) - struct crc_rd_work *crc_rd_wrk = dm->crc_rd_wrk; + struct crc_rd_work *crc_rd_wrk; +#endif +#endif + /* Count number of newly disabled CRTCs for dropping PM refs later. */ + if (old_crtc_state->active && !new_crtc_state->active) + crtc_disable_count++; + + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + + /* For freesync config update on crtc state and params for irq */ + update_stream_irq_parameters(dm, dm_new_crtc_state); + +#ifdef CONFIG_DEBUG_FS +#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) + crc_rd_wrk = dm->crc_rd_wrk; #endif spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); cur_crc_src = acrtc->dm_irq_params.crc_src; spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); #endif - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); if (new_crtc_state->active && (!old_crtc_state->active || @@ -9647,16 +9643,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dc_stream_retain(dm_new_crtc_state->stream); acrtc->dm_irq_params.stream = dm_new_crtc_state->stream; manage_dm_interrupts(adev, acrtc, true); + } + /* Handle vrr on->off / off->on transitions */ + amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state); #ifdef CONFIG_DEBUG_FS + if (new_crtc_state->active && + (!old_crtc_state->active || + drm_atomic_crtc_needs_modeset(new_crtc_state))) { /** * Frontend may have changed so reapply the CRC capture * settings for the stream. */ - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); - if (amdgpu_dm_is_valid_crc_source(cur_crc_src)) { - configure_crc = true; #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) if (amdgpu_dm_crc_window_is_activated(crtc)) { spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); @@ -9668,12 +9667,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); } #endif - } - - if (configure_crc) if (amdgpu_dm_crtc_configure_crc_source( crtc, dm_new_crtc_state, cur_crc_src)) DRM_DEBUG_DRIVER("Failed to configure crc source"); + } #endif } } From 73b8218ef4aac42d18d98ddf5c2fe46ea0d52300 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 14 Oct 2022 18:50:20 -0500 Subject: [PATCH 134/610] smb3: must initialize two ACL struct fields to zero commit f09bd695af3b8ab46fc24e5d6954a24104c38387 upstream. Coverity spotted that we were not initalizing Stbz1 and Stbz2 to zero in create_sd_buf. Addresses-Coverity: 1513848 ("Uninitialized scalar variable") Cc: Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2pdu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index cf8e85d8f488..8aa0372141f5 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2354,7 +2354,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) unsigned int acelen, acl_size, ace_count; unsigned int owner_offset = 0; unsigned int group_offset = 0; - struct smb3_acl acl; + struct smb3_acl acl = {}; *len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8); @@ -2427,6 +2427,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */ acl.AclSize = cpu_to_le16(acl_size); acl.AceCount = cpu_to_le16(ace_count); + /* acl.Sbz1 and Sbz2 MBZ so are not set here, but initialized above */ memcpy(aclptr, &acl, sizeof(struct smb3_acl)); buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd); From b7af9b8be89171f5bd842d8813eddeb846433ff3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 20 Sep 2022 19:12:52 +0200 Subject: [PATCH 135/610] selinux: use "grep -E" instead of "egrep" commit c969bb8dbaf2f3628927eae73e7c579a74cf1b6e upstream. The latest version of grep claims that egrep is now obsolete so the build now contains warnings that look like: egrep: warning: egrep is obsolescent; using grep -E fix this by using "grep -E" instead. Cc: Paul Moore Cc: Stephen Smalley Cc: Eric Paris Cc: selinux@vger.kernel.org Signed-off-by: Greg Kroah-Hartman [PM: tweak to remove vdso reference, cleanup subj line] Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- scripts/selinux/install_policy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh index 2dccf141241d..20af56ce245c 100755 --- a/scripts/selinux/install_policy.sh +++ b/scripts/selinux/install_policy.sh @@ -78,7 +78,7 @@ cd /etc/selinux/dummy/contexts/files $SF -F file_contexts / mounts=`cat /proc/$$/mounts | \ - egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ + grep -E "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ awk '{ print $2 '}` $SF -F file_contexts $mounts From 10918ebecdc9771999783e933ed8265d9b1d3e5a Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Wed, 17 Aug 2022 17:18:42 -0400 Subject: [PATCH 136/610] ima: fix blocking of security.ima xattrs of unsupported algorithms [ Upstream commit 5926586f291b53cb8a0c9631fc19489be1186e2d ] Limit validating the hash algorithm to just security.ima xattr, not the security.evm xattr or any of the protected EVM security xattrs, nor posix acls. Fixes: 50f742dd9147 ("IMA: block writes of the security.ima xattr with unsupported algorithms") Reported-by: Christian Brauner Acked-by: Christian Brauner (Microsoft) Signed-off-by: Mimi Zohar Signed-off-by: Sasha Levin --- security/integrity/ima/ima_appraise.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index ed04bb7c7512..08b49bd1e8ca 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -644,22 +644,26 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, const struct evm_ima_xattr_data *xvalue = xattr_value; int digsig = 0; int result; + int err; result = ima_protect_xattr(dentry, xattr_name, xattr_value, xattr_value_len); if (result == 1) { if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) return -EINVAL; + + err = validate_hash_algo(dentry, xvalue, xattr_value_len); + if (err) + return err; + digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG); } else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) { digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG); } if (result == 1 || evm_revalidate_status(xattr_name)) { - result = validate_hash_algo(dentry, xvalue, xattr_value_len); - if (result) - return result; - ima_reset_appraise_flags(d_backing_inode(dentry), digsig); + if (result == 1) + result = 0; } return result; } From 33d478eee2b52408326653519672ee23642b2117 Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Fri, 8 Jul 2022 11:34:51 +0200 Subject: [PATCH 137/610] userfaultfd: open userfaultfds with O_RDONLY [ Upstream commit abec3d015fdfb7c63105c7e1c956188bf381aa55 ] Since userfaultfd doesn't implement a write operation, it is more appropriate to open it read-only. When userfaultfds are opened read-write like it is now, and such fd is passed from one process to another, SELinux will check both read and write permissions for the target process, even though it can't actually do any write operation on the fd later. Inspired by the following bug report, which has hit the SELinux scenario described above: https://bugzilla.redhat.com/show_bug.cgi?id=1974559 Reported-by: Robert O'Callahan Fixes: 86039bd3b4e6 ("userfaultfd: add new syscall to provide memory externalization") Signed-off-by: Ondrej Mosnacek Acked-by: Peter Xu Acked-by: Christian Brauner (Microsoft) Signed-off-by: Paul Moore Signed-off-by: Sasha Levin --- fs/userfaultfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 22bf14ab2d16..b56e8e31d967 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -982,7 +982,7 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *new, int fd; fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, new, - O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode); + O_RDONLY | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode); if (fd < 0) return fd; @@ -2097,7 +2097,7 @@ SYSCALL_DEFINE1(userfaultfd, int, flags) mmgrab(ctx->mm); fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, ctx, - O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL); + O_RDONLY | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL); if (fd < 0) { mmdrop(ctx->mm); kmem_cache_free(userfaultfd_ctx_cachep, ctx); From 81fb3ee298d5346a8db8ff47fd08662bb01a04cd Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 29 Aug 2022 14:38:40 +0200 Subject: [PATCH 138/610] ntfs3: rework xattr handlers and switch to POSIX ACL VFS helpers [ Upstream commit a26aa12384158116c0d80d50e0bdc7b3323551e2 ] The xattr code in ntfs3 is currently a bit confused. For example, it defines a POSIX ACL i_op->set_acl() method but instead of relying on the generic POSIX ACL VFS helpers it defines its own set of xattr helpers with the consequence that i_op->set_acl() is currently dead code. Switch ntfs3 to rely on the VFS POSIX ACL xattr handlers. Also remove i_op->{g,s}et_acl() methods from symlink inode operations. Symlinks don't support xattrs. This is a preliminary change for the following patches which move handling idmapped mounts directly in posix_acl_xattr_set(). This survives POSIX ACL xfstests. Fixes: be71b5cba2e6 ("fs/ntfs3: Add attrib operations") Signed-off-by: Christian Brauner (Microsoft) Reviewed-by: Seth Forshee (DigitalOcean) > Signed-off-by: Sasha Levin --- fs/ntfs3/inode.c | 2 - fs/ntfs3/xattr.c | 102 +++-------------------------------------------- 2 files changed, 6 insertions(+), 98 deletions(-) diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index b2cc1191be69..64b4a3c29878 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -1942,8 +1942,6 @@ const struct inode_operations ntfs_link_inode_operations = { .setattr = ntfs3_setattr, .listxattr = ntfs_listxattr, .permission = ntfs_permission, - .get_acl = ntfs_get_acl, - .set_acl = ntfs_set_acl, }; const struct address_space_operations ntfs_aops = { diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c index 4652b9796995..eb799a5cdfad 100644 --- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -623,67 +623,6 @@ int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false); } -static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns, - struct inode *inode, int type, void *buffer, - size_t size) -{ - struct posix_acl *acl; - int err; - - if (!(inode->i_sb->s_flags & SB_POSIXACL)) { - ntfs_inode_warn(inode, "add mount option \"acl\" to use acl"); - return -EOPNOTSUPP; - } - - acl = ntfs_get_acl(inode, type, false); - if (IS_ERR(acl)) - return PTR_ERR(acl); - - if (!acl) - return -ENODATA; - - err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); - posix_acl_release(acl); - - return err; -} - -static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns, - struct inode *inode, int type, const void *value, - size_t size) -{ - struct posix_acl *acl; - int err; - - if (!(inode->i_sb->s_flags & SB_POSIXACL)) { - ntfs_inode_warn(inode, "add mount option \"acl\" to use acl"); - return -EOPNOTSUPP; - } - - if (!inode_owner_or_capable(mnt_userns, inode)) - return -EPERM; - - if (!value) { - acl = NULL; - } else { - acl = posix_acl_from_xattr(&init_user_ns, value, size); - if (IS_ERR(acl)) - return PTR_ERR(acl); - - if (acl) { - err = posix_acl_valid(&init_user_ns, acl); - if (err) - goto release_and_out; - } - } - - err = ntfs_set_acl(mnt_userns, inode, acl, type); - -release_and_out: - posix_acl_release(acl); - return err; -} - /* * ntfs_init_acl - Initialize the ACLs of a new inode. * @@ -850,23 +789,6 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de, goto out; } -#ifdef CONFIG_NTFS3_FS_POSIX_ACL - if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 && - !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS, - sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) || - (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 && - !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, - sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) { - /* TODO: init_user_ns? */ - err = ntfs_xattr_get_acl( - &init_user_ns, inode, - name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 - ? ACL_TYPE_ACCESS - : ACL_TYPE_DEFAULT, - buffer, size); - goto out; - } -#endif /* Deal with NTFS extended attribute. */ err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL); @@ -979,22 +901,6 @@ set_new_fa: goto out; } -#ifdef CONFIG_NTFS3_FS_POSIX_ACL - if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 && - !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS, - sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) || - (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 && - !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, - sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) { - err = ntfs_xattr_set_acl( - mnt_userns, inode, - name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 - ? ACL_TYPE_ACCESS - : ACL_TYPE_DEFAULT, - value, size); - goto out; - } -#endif /* Deal with NTFS extended attribute. */ err = ntfs_set_ea(inode, name, name_len, value, size, flags); @@ -1082,7 +988,7 @@ static bool ntfs_xattr_user_list(struct dentry *dentry) } // clang-format off -static const struct xattr_handler ntfs_xattr_handler = { +static const struct xattr_handler ntfs_other_xattr_handler = { .prefix = "", .get = ntfs_getxattr, .set = ntfs_setxattr, @@ -1090,7 +996,11 @@ static const struct xattr_handler ntfs_xattr_handler = { }; const struct xattr_handler *ntfs_xattr_handlers[] = { - &ntfs_xattr_handler, +#ifdef CONFIG_NTFS3_FS_POSIX_ACL + &posix_acl_access_xattr_handler, + &posix_acl_default_xattr_handler, +#endif + &ntfs_other_xattr_handler, NULL, }; // clang-format on From 91fafd22f8520b4be6941d6066f58dd561ffa724 Mon Sep 17 00:00:00 2001 From: Xuewen Yan Date: Thu, 25 Aug 2022 19:40:17 +0800 Subject: [PATCH 139/610] thermal: cpufreq_cooling: Check the policy first in cpufreq_cooling_register() [ Upstream commit cff895277c8558221ba180aefe26799dcb4eec86 ] Since the policy needs to be accessed first when obtaining cpu devices, first check whether the policy is legal before this. Fixes: 5130802ddbb1 ("thermal: cpu_cooling: Switch to QoS requests for freq limits") Signed-off-by: Xuewen Yan Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/cpufreq_cooling.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 43b1ae8a7789..12a60415af95 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -525,17 +525,17 @@ __cpufreq_cooling_register(struct device_node *np, struct thermal_cooling_device_ops *cooling_ops; char *name; + if (IS_ERR_OR_NULL(policy)) { + pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy); + return ERR_PTR(-EINVAL); + } + dev = get_cpu_device(policy->cpu); if (unlikely(!dev)) { pr_warn("No cpu device for cpu %d\n", policy->cpu); return ERR_PTR(-ENODEV); } - if (IS_ERR_OR_NULL(policy)) { - pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy); - return ERR_PTR(-EINVAL); - } - i = cpufreq_table_count_valid_entries(policy); if (!i) { pr_debug("%s: CPUFreq table not found or has no valid entries\n", From 959855093f94554083406c6bec846db13e1fbe14 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 7 Sep 2022 16:40:44 -0700 Subject: [PATCH 140/610] sh: machvec: Use char[] for section boundaries [ Upstream commit c5783af354688b24abd359f7086c282ec74de993 ] As done for other sections, define the extern as a character array, which relaxes many of the compiler-time object size checks, which would otherwise assume it's a single long. Solves the following build error: arch/sh/kernel/machvec.c: error: array subscript 'struct sh_machine_vector[0]' is partly outside array bounds of 'long int[1]' [-Werror=array-bounds]: => 105:33 Cc: Yoshinori Sato Cc: Rich Felker Cc: linux-sh@vger.kernel.org Reported-by: Geert Uytterhoeven Link: https://lore.kernel.org/lkml/alpine.DEB.2.22.394.2209050944290.964530@ramsan.of.borg/ Fixes: 9655ad03af2d ("sh: Fixup machvec support.") Reviewed-by: Geert Uytterhoeven Reviewed-by: Gustavo A. R. Silva Acked-by: Rich Felker Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- arch/sh/include/asm/sections.h | 2 +- arch/sh/kernel/machvec.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h index 8edb824049b9..0cb0ca149ac3 100644 --- a/arch/sh/include/asm/sections.h +++ b/arch/sh/include/asm/sections.h @@ -4,7 +4,7 @@ #include -extern long __machvec_start, __machvec_end; +extern char __machvec_start[], __machvec_end[]; extern char __uncached_start, __uncached_end; extern char __start_eh_frame[], __stop_eh_frame[]; diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c index d606679a211e..57efaf5b82ae 100644 --- a/arch/sh/kernel/machvec.c +++ b/arch/sh/kernel/machvec.c @@ -20,8 +20,8 @@ #define MV_NAME_SIZE 32 #define for_each_mv(mv) \ - for ((mv) = (struct sh_machine_vector *)&__machvec_start; \ - (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \ + for ((mv) = (struct sh_machine_vector *)__machvec_start; \ + (mv) && (unsigned long)(mv) < (unsigned long)__machvec_end; \ (mv)++) static struct sh_machine_vector * __init get_mv_byname(const char *name) @@ -87,8 +87,8 @@ void __init sh_mv_setup(void) if (!machvec_selected) { unsigned long machvec_size; - machvec_size = ((unsigned long)&__machvec_end - - (unsigned long)&__machvec_start); + machvec_size = ((unsigned long)__machvec_end - + (unsigned long)__machvec_start); /* * Sanity check for machvec section alignment. Ensure @@ -102,7 +102,7 @@ void __init sh_mv_setup(void) * vector (usually the only one) from .machvec.init. */ if (machvec_size >= sizeof(struct sh_machine_vector)) - sh_mv = *(struct sh_machine_vector *)&__machvec_start; + sh_mv = *(struct sh_machine_vector *)__machvec_start; } pr_notice("Booting machvec: %s\n", get_system_type()); From 993b13abde17bda5ba3b9ec0ba655b60f04f8656 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 23 Apr 2022 15:24:03 +0200 Subject: [PATCH 141/610] MIPS: SGI-IP27: Free some unused memory [ Upstream commit 33d7085682b4aa212ebfadbc21da81dfefaaac16 ] platform_device_add_data() duplicates the memory it is passed. So we can free some memory to save a few bytes that would remain unused otherwise. Signed-off-by: Christophe JAILLET Signed-off-by: Thomas Bogendoerfer Stable-dep-of: 11bec9cba4de ("MIPS: SGI-IP27: Fix platform-device leak in bridge_platform_create()") Signed-off-by: Sasha Levin --- arch/mips/sgi-ip27/ip27-xtalk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c index 000ede156bdc..e762886d1dda 100644 --- a/arch/mips/sgi-ip27/ip27-xtalk.c +++ b/arch/mips/sgi-ip27/ip27-xtalk.c @@ -53,6 +53,8 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) } platform_device_add_resources(pdev, &w1_res, 1); platform_device_add_data(pdev, wd, sizeof(*wd)); + /* platform_device_add_data() duplicates the data */ + kfree(wd); platform_device_add(pdev); bd = kzalloc(sizeof(*bd), GFP_KERNEL); @@ -83,6 +85,8 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) bd->io_offset = offset; platform_device_add_data(pdev, bd, sizeof(*bd)); + /* platform_device_add_data() duplicates the data */ + kfree(bd); platform_device_add(pdev); pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget); return; From 93296e7ab774230b7c36541dead10b6da39b650f Mon Sep 17 00:00:00 2001 From: Lin Yujun Date: Wed, 14 Sep 2022 11:29:17 +0800 Subject: [PATCH 142/610] MIPS: SGI-IP27: Fix platform-device leak in bridge_platform_create() [ Upstream commit 11bec9cba4de06b3c0e9e4041453c2caaa1cbec1 ] In error case in bridge_platform_create after calling platform_device_add()/platform_device_add_data()/ platform_device_add_resources(), release the failed 'pdev' or it will be leak, call platform_device_put() to fix this problem. Besides, 'pdev' is divided into 'pdev_wd' and 'pdev_bd', use platform_device_unregister() to release sgi_w1 resources when xtalk-bridge registration fails. Fixes: 5dc76a96e95a ("MIPS: PCI: use information from 1-wire PROM for IOC3 detection") Signed-off-by: Lin Yujun Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/sgi-ip27/ip27-xtalk.c | 70 +++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c index e762886d1dda..5143d1cf8984 100644 --- a/arch/mips/sgi-ip27/ip27-xtalk.c +++ b/arch/mips/sgi-ip27/ip27-xtalk.c @@ -27,15 +27,18 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) { struct xtalk_bridge_platform_data *bd; struct sgi_w1_platform_data *wd; - struct platform_device *pdev; + struct platform_device *pdev_wd; + struct platform_device *pdev_bd; struct resource w1_res; unsigned long offset; offset = NODE_OFFSET(nasid); wd = kzalloc(sizeof(*wd), GFP_KERNEL); - if (!wd) - goto no_mem; + if (!wd) { + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); + return; + } snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx", offset + (widget << SWIN_SIZE_BITS)); @@ -46,24 +49,35 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) w1_res.end = w1_res.start + 3; w1_res.flags = IORESOURCE_MEM; - pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); - if (!pdev) { - kfree(wd); - goto no_mem; + pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO); + if (!pdev_wd) { + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); + goto err_kfree_wd; + } + if (platform_device_add_resources(pdev_wd, &w1_res, 1)) { + pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget); + goto err_put_pdev_wd; + } + if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) { + pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget); + goto err_put_pdev_wd; + } + if (platform_device_add(pdev_wd)) { + pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget); + goto err_put_pdev_wd; } - platform_device_add_resources(pdev, &w1_res, 1); - platform_device_add_data(pdev, wd, sizeof(*wd)); /* platform_device_add_data() duplicates the data */ kfree(wd); - platform_device_add(pdev); bd = kzalloc(sizeof(*bd), GFP_KERNEL); - if (!bd) - goto no_mem; - pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); - if (!pdev) { - kfree(bd); - goto no_mem; + if (!bd) { + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); + goto err_unregister_pdev_wd; + } + pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO); + if (!pdev_bd) { + pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); + goto err_kfree_bd; } @@ -84,15 +98,31 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) bd->io.flags = IORESOURCE_IO; bd->io_offset = offset; - platform_device_add_data(pdev, bd, sizeof(*bd)); + if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) { + pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget); + goto err_put_pdev_bd; + } + if (platform_device_add(pdev_bd)) { + pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget); + goto err_put_pdev_bd; + } /* platform_device_add_data() duplicates the data */ kfree(bd); - platform_device_add(pdev); pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget); return; -no_mem: - pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); +err_put_pdev_bd: + platform_device_put(pdev_bd); +err_kfree_bd: + kfree(bd); +err_unregister_pdev_wd: + platform_device_unregister(pdev_wd); + return; +err_put_pdev_wd: + platform_device_put(pdev_wd); +err_kfree_wd: + kfree(wd); + return; } static int probe_one_port(nasid_t nasid, int widget, int masterwid) From 2647b20e043cb08b0886ebfa5d1b707bd3eb0148 Mon Sep 17 00:00:00 2001 From: Wang Kefeng Date: Tue, 13 Sep 2022 05:25:51 +0100 Subject: [PATCH 143/610] ARM: 9244/1: dump: Fix wrong pg_level in walk_pmd() [ Upstream commit 2ccd19b3ffac07cc7e75a2bd1ed779728bb67197 ] After ARM supports p4d page tables, the pg_level for note_page() in walk_pmd() should be 4, not 3, fix it. Fixes: 84e6ffb2c49c ("arm: add support for folded p4d page tables") Signed-off-by: Kefeng Wang Signed-off-by: Russell King (Oracle) Signed-off-by: Sasha Levin --- arch/arm/mm/dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index fb688003d156..712da6a81b23 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -346,7 +346,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) addr = start + i * PMD_SIZE; domain = get_domain_name(pmd); if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd)) - note_page(st, addr, 3, pmd_val(*pmd), domain); + note_page(st, addr, 4, pmd_val(*pmd), domain); else walk_pte(st, pmd, addr, domain); From 425a2a9469d2ab262797c68655beca00d05038ab Mon Sep 17 00:00:00 2001 From: Wang Kefeng Date: Fri, 16 Sep 2022 12:10:49 +0100 Subject: [PATCH 144/610] ARM: 9247/1: mm: set readonly for MT_MEMORY_RO with ARM_LPAE [ Upstream commit 14ca1a4690750bb54e1049e49f3140ef48958a6e ] MT_MEMORY_RO is introduced by commit 598f0a99fa8a ("ARM: 9210/1: Mark the FDT_FIXED sections as shareable"), which is a readonly memory type for FDT area, but there are some different between ARM_LPAE and non-ARM_LPAE, we need to setup PMD_SECT_AP2 and L_PMD_SECT_RDONLY for MT_MEMORY_RO when ARM_LAPE enabled. non-ARM_LPAE 0xff800000-0xffa00000 2M PGD KERNEL ro NX SHD ARM_LPAE 0xff800000-0xffc00000 4M PMD RW NX SHD ARM_LPAE+fix 0xff800000-0xffc00000 4M PMD ro NX SHD Fixes: 598f0a99fa8a ("ARM: 9210/1: Mark the FDT_FIXED sections as shareable") Signed-off-by: Kefeng Wang Signed-off-by: Russell King (Oracle) Signed-off-by: Sasha Levin --- arch/arm/mm/mmu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index cd17e324aa51..83a91e0ab848 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -300,7 +300,11 @@ static struct mem_type mem_types[] __ro_after_init = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_XN | L_PTE_RDONLY, .prot_l1 = PMD_TYPE_TABLE, +#ifdef CONFIG_ARM_LPAE + .prot_sect = PMD_TYPE_SECT | L_PMD_SECT_RDONLY | PMD_SECT_AP2, +#else .prot_sect = PMD_TYPE_SECT, +#endif .domain = DOMAIN_KERNEL, }, [MT_ROM] = { From 5c4b234c44cbd860a89f0143d8ec9767aba61c2d Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 8 Sep 2022 14:54:58 -0700 Subject: [PATCH 145/610] objtool: Preserve special st_shndx indexes in elf_update_symbol [ Upstream commit 5141d3a06b2da1731ac82091298b766a1f95d3d8 ] elf_update_symbol fails to preserve the special st_shndx values between [SHN_LORESERVE, SHN_HIRESERVE], which results in it converting SHN_ABS entries into SHN_UNDEF, for example. Explicitly check for the special indexes and ensure these symbols are not marked undefined. Fixes: ead165fa1042 ("objtool: Fix symbol creation") Signed-off-by: Sami Tolvanen Acked-by: Peter Zijlstra (Intel) Tested-by: Peter Zijlstra (Intel) Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220908215504.3686827-17-samitolvanen@google.com Signed-off-by: Sasha Levin --- tools/objtool/elf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index bc3005ef5af8..4b78df22d42e 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -555,6 +555,11 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab, Elf64_Xword entsize = symtab->sh.sh_entsize; int max_idx, idx = sym->idx; Elf_Scn *s, *t = NULL; + bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE && + sym->sym.st_shndx != SHN_XINDEX; + + if (is_special_shndx) + shndx = sym->sym.st_shndx; s = elf_getscn(elf->elf, symtab->idx); if (!s) { @@ -640,7 +645,7 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab, } /* setup extended section index magic and write the symbol */ - if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) { + if ((shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) || is_special_shndx) { sym->sym.st_shndx = shndx; if (!shndx_data) shndx = 0; From aed8816305575b38dcc77feb6f1bc1d0ed32f5b8 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 1 Sep 2022 07:27:04 +0200 Subject: [PATCH 146/610] nfsd: Fix a memory leak in an error handling path [ Upstream commit fd1ef88049de09bc70d60b549992524cfc0e66ff ] If this memdup_user() call fails, the memory allocated in a previous call a few lines above should be freed. Otherwise it leaks. Fixes: 6ee95d1c8991 ("nfsd: add support for upcall version 2") Signed-off-by: Christophe JAILLET Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4recover.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index c634483d85d2..8f24485e0f04 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -815,8 +815,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg, princhash.data = memdup_user( &ci->cc_princhash.cp_data, princhashlen); - if (IS_ERR_OR_NULL(princhash.data)) + if (IS_ERR_OR_NULL(princhash.data)) { + kfree(name.data); return -EFAULT; + } princhash.len = princhashlen; } else princhash.len = 0; From 6b55707ff8b296243a9cf6636d6d8459b6a4a7f8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 1 Sep 2022 15:09:53 -0400 Subject: [PATCH 147/610] SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation [ Upstream commit 90bfc37b5ab91c1a6165e3e5cfc49bf04571b762 ] Ensure that stream-based argument decoding can't go past the actual end of the receive buffer. xdr_init_decode's calculation of the value of xdr->end over-estimates the end of the buffer because the Linux kernel RPC server code does not remove the size of the RPC header from rqstp->rq_arg before calling the upper layer's dispatcher. The server-side still uses the svc_getnl() macros to decode the RPC call header. These macros reduce the length of the head iov but do not update the total length of the message in the buffer (buf->len). A proper fix for this would be to replace the use of svc_getnl() and friends in the RPC header decoder, but that would be a large and invasive change that would be difficult to backport. Fixes: 5191955d6fc6 ("SUNRPC: Prepare for xdr_stream-style decoding on the server-side") Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- include/linux/sunrpc/svc.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 01f09adccc63..6be55d0e73fd 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -566,16 +566,27 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) } /** - * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding + * svcxdr_init_decode - Prepare an xdr_stream for Call decoding * @rqstp: controlling server RPC transaction context * + * This function currently assumes the RPC header in rq_arg has + * already been decoded. Upon return, xdr->p points to the + * location of the upper layer header. */ static inline void svcxdr_init_decode(struct svc_rqst *rqstp) { struct xdr_stream *xdr = &rqstp->rq_arg_stream; - struct kvec *argv = rqstp->rq_arg.head; + struct xdr_buf *buf = &rqstp->rq_arg; + struct kvec *argv = buf->head; - xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL); + /* + * svc_getnl() and friends do not keep the xdr_buf's ::len + * field up to date. Refresh that field before initializing + * the argument decoding stream. + */ + buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len; + + xdr_init_decode(xdr, buf, argv->iov_base, NULL); xdr_set_scratch_page(xdr, rqstp->rq_scratch_page); } From cedaf73c8bdaa666cd125257861155f273464a6f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 1 Sep 2022 15:09:59 -0400 Subject: [PATCH 148/610] SUNRPC: Fix svcxdr_init_encode's buflen calculation [ Upstream commit 1242a87da0d8cd2a428e96ca68e7ea899b0f4624 ] Commit 2825a7f90753 ("nfsd4: allow encoding across page boundaries") added an explicit computation of the remaining length in the rq_res XDR buffer. The computation appears to suffer from an "off-by-one" bug. Because buflen is too large by one page, XDR encoding can run off the end of the send buffer by eventually trying to use the struct page address in rq_page_end, which always contains NULL. Fixes: bddfdbcddbe2 ("NFSD: Extract the svcxdr_init_encode() helper") Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- include/linux/sunrpc/svc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 6be55d0e73fd..045f34add206 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -609,7 +609,7 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp) xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack; buf->len = resv->iov_len; xdr->page_ptr = buf->pages - 1; - buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages); + buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages); buf->buflen -= rqstp->rq_auth_slack; xdr->rqst = NULL; } From dc7f225090c29a5f3b9419b1af32846a201555e7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 1 Sep 2022 15:10:05 -0400 Subject: [PATCH 149/610] NFSD: Protect against send buffer overflow in NFSv2 READDIR [ Upstream commit 00b4492686e0497fdb924a9d4c8f6f99377e176c ] Restore the previous limit on the @count argument to prevent a buffer overflow attack. Fixes: 53b1119a6e50 ("NFSD: Fix READDIR buffer overflow") Signed-off-by: Chuck Lever Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfsproc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 081cca405983..b009da1dcbb5 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -557,12 +557,11 @@ static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp, struct xdr_buf *buf = &resp->dirlist; struct xdr_stream *xdr = &resp->xdr; - count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp)); - memset(buf, 0, sizeof(*buf)); /* Reserve room for the NULL ptr & eof flag (-2 words) */ - buf->buflen = count - XDR_UNIT * 2; + buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), (u32)PAGE_SIZE); + buf->buflen -= XDR_UNIT * 2; buf->pages = rqstp->rq_next_page; rqstp->rq_next_page++; From 80a474502ef53c9ae4f08cc107d47a9079534427 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 5 Sep 2022 15:33:32 -0400 Subject: [PATCH 150/610] NFSD: Fix handling of oversized NFSv4 COMPOUND requests [ Upstream commit 7518a3dc5ea249d4112156ce71b8b184eb786151 ] If an NFS server returns NFS4ERR_RESOURCE on the first operation in an NFSv4 COMPOUND, there's no way for a client to know where the problem is and then simplify the compound to make forward progress. So instead, make NFSD process as many operations in an oversized COMPOUND as it can and then return NFS4ERR_RESOURCE on the first operation it did not process. pynfs NFSv4.0 COMP6 exercises this case, but checks only for the COMPOUND status code, not whether the server has processed any of the operations. pynfs NFSv4.1 SEQ6 and SEQ7 exercise the NFSv4.1 case, which detects too many operations per COMPOUND by checking against the limits negotiated when the session was created. Suggested-by: Bruce Fields Fixes: 0078117c6d91 ("nfsd: return RESOURCE not GARBAGE_ARGS on too many ops") Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4proc.c | 19 +++++++++++++------ fs/nfsd/nfs4xdr.c | 11 +++-------- fs/nfsd/xdr4.h | 3 ++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index f7584787dab2..09dd70f79158 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2493,9 +2493,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) status = nfserr_minor_vers_mismatch; if (nfsd_minorversion(nn, args->minorversion, NFSD_TEST) <= 0) goto out; - status = nfserr_resource; - if (args->opcnt > NFSD_MAX_OPS_PER_COMPOUND) - goto out; status = nfs41_check_op_ordering(args); if (status) { @@ -2508,10 +2505,20 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) rqstp->rq_lease_breaker = (void **)&cstate->clp; - trace_nfsd_compound(rqstp, args->opcnt); + trace_nfsd_compound(rqstp, args->client_opcnt); while (!status && resp->opcnt < args->opcnt) { op = &args->ops[resp->opcnt++]; + if (unlikely(resp->opcnt == NFSD_MAX_OPS_PER_COMPOUND)) { + /* If there are still more operations to process, + * stop here and report NFS4ERR_RESOURCE. */ + if (cstate->minorversion == 0 && + args->client_opcnt > resp->opcnt) { + op->status = nfserr_resource; + goto encode_op; + } + } + /* * The XDR decode routines may have pre-set op->status; * for example, if there is a miscellaneous XDR error @@ -2587,8 +2594,8 @@ encode_op: status = op->status; } - trace_nfsd_compound_status(args->opcnt, resp->opcnt, status, - nfsd4_op_name(op->opnum)); + trace_nfsd_compound_status(args->client_opcnt, resp->opcnt, + status, nfsd4_op_name(op->opnum)); nfsd4_cstate_clear_replay(cstate); nfsd4_increment_op_stats(op->opnum); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f6d385e0efec..bda8478eb1ae 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2349,16 +2349,11 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0) return 0; - if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0) + if (xdr_stream_decode_u32(argp->xdr, &argp->client_opcnt) < 0) return 0; - /* - * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS - * here, so we return success at the xdr level so that - * nfsd4_proc can handle this is an NFS-level error. - */ - if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND) - return 1; + argp->opcnt = min_t(u32, argp->client_opcnt, + NFSD_MAX_OPS_PER_COMPOUND); if (argp->opcnt > ARRAY_SIZE(argp->iops)) { argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 3e4052e3bd50..45257666a688 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -688,9 +688,10 @@ struct nfsd4_compoundargs { struct svcxdr_tmpbuf *to_free; struct svc_rqst *rqstp; - u32 taglen; char * tag; + u32 taglen; u32 minorversion; + u32 client_opcnt; u32 opcnt; struct nfsd4_op *ops; struct nfsd4_op iops[8]; From 714536ff6f6c8968b79819c4d420716ed4a21830 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Mon, 1 Aug 2022 19:33:45 +0800 Subject: [PATCH 151/610] wifi: rtlwifi: 8192de: correct checking of IQK reload [ Upstream commit 93fbc1ebd978cf408ef5765e9c1630fce9a8621b ] Since IQK could spend time, we make a cache of IQK result matrix that looks like iqk_matrix[channel_idx].val[x][y], and we can reload the matrix if we have made a cache. To determine a cache is made, we check iqk_matrix[channel_idx].val[0][0]. The initial commit 7274a8c22980 ("rtlwifi: rtl8192de: Merge phy routines") make a mistake that checks incorrect iqk_matrix[channel_idx].val[0] that is always true, and this mistake is found by commit ee3db469dd31 ("wifi: rtlwifi: remove always-true condition pointed out by GCC 12"), so I recall the vendor driver to find fix and apply the correctness. Fixes: 7274a8c22980 ("rtlwifi: rtl8192de: Merge phy routines") Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220801113345.42016-1-pkshih@realtek.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c index 743e38a1aa51..4d153bd62c53 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c @@ -2386,11 +2386,10 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "Just Read IQK Matrix reg for channel:%d....\n", channel); - _rtl92d_phy_patha_fill_iqk_matrix(hw, true, - rtlphy->iqk_matrix[ - indexforchannel].value, 0, - (rtlphy->iqk_matrix[ - indexforchannel].value[0][2] == 0)); + if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0) + _rtl92d_phy_patha_fill_iqk_matrix(hw, true, + rtlphy->iqk_matrix[indexforchannel].value, 0, + rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0); if (IS_92D_SINGLEPHY(rtlhal->version)) { if ((rtlphy->iqk_matrix[ indexforchannel].value[0][4] != 0) From 54a3201f3c1ff813523937da78b5fa7649dbab71 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Mon, 1 Aug 2022 10:19:30 -0400 Subject: [PATCH 152/610] wifi: ath10k: add peer map clean up for peer delete in ath10k_sta_state() [ Upstream commit f020d9570a04df0762a2ac5c50cf1d8c511c9164 ] When peer delete failed in a disconnect operation, use-after-free detected by KFENCE in below log. It is because for each vdev_id and address, it has only one struct ath10k_peer, it is allocated in ath10k_peer_map_event(). When connected to an AP, it has more than one HTT_T2H_MSG_TYPE_PEER_MAP reported from firmware, then the array peer_map of struct ath10k will be set muti-elements to the same ath10k_peer in ath10k_peer_map_event(). When peer delete failed in ath10k_sta_state(), the ath10k_peer will be free for the 1st peer id in array peer_map of struct ath10k, and then use-after-free happened for the 2nd peer id because they map to the same ath10k_peer. And clean up all peers in array peer_map for the ath10k_peer, then user-after-free disappeared peer map event log: [ 306.911021] wlan0: authenticate with b0:2a:43:e6:75:0e [ 306.957187] ath10k_pci 0000:01:00.0: mac vdev 0 peer create b0:2a:43:e6:75:0e (new sta) sta 1 / 32 peer 1 / 33 [ 306.957395] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 246 [ 306.957404] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 198 [ 306.986924] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 166 peer unmap event log: [ 435.715691] wlan0: deauthenticating from b0:2a:43:e6:75:0e by local choice (Reason: 3=DEAUTH_LEAVING) [ 435.716802] ath10k_pci 0000:01:00.0: mac vdev 0 peer delete b0:2a:43:e6:75:0e sta ffff990e0e9c2b50 (sta gone) [ 435.717177] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 246 [ 435.717186] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 198 [ 435.717193] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 166 use-after-free log: [21705.888627] wlan0: deauthenticating from d0:76:8f:82:be:75 by local choice (Reason: 3=DEAUTH_LEAVING) [21713.799910] ath10k_pci 0000:01:00.0: failed to delete peer d0:76:8f:82:be:75 for vdev 0: -110 [21713.799925] ath10k_pci 0000:01:00.0: found sta peer d0:76:8f:82:be:75 (ptr 0000000000000000 id 102) entry on vdev 0 after it was supposedly removed [21713.799968] ================================================================== [21713.799991] BUG: KFENCE: use-after-free read in ath10k_sta_state+0x265/0xb8a [ath10k_core] [21713.799991] [21713.799997] Use-after-free read at 0x00000000abe1c75e (in kfence-#69): [21713.800010] ath10k_sta_state+0x265/0xb8a [ath10k_core] [21713.800041] drv_sta_state+0x115/0x677 [mac80211] [21713.800059] __sta_info_destroy_part2+0xb1/0x133 [mac80211] [21713.800076] __sta_info_flush+0x11d/0x162 [mac80211] [21713.800093] ieee80211_set_disassoc+0x12d/0x2f4 [mac80211] [21713.800110] ieee80211_mgd_deauth+0x26c/0x29b [mac80211] [21713.800137] cfg80211_mlme_deauth+0x13f/0x1bb [cfg80211] [21713.800153] nl80211_deauthenticate+0xf8/0x121 [cfg80211] [21713.800161] genl_rcv_msg+0x38e/0x3be [21713.800166] netlink_rcv_skb+0x89/0xf7 [21713.800171] genl_rcv+0x28/0x36 [21713.800176] netlink_unicast+0x179/0x24b [21713.800181] netlink_sendmsg+0x3a0/0x40e [21713.800187] sock_sendmsg+0x72/0x76 [21713.800192] ____sys_sendmsg+0x16d/0x1e3 [21713.800196] ___sys_sendmsg+0x95/0xd1 [21713.800200] __sys_sendmsg+0x85/0xbf [21713.800205] do_syscall_64+0x43/0x55 [21713.800210] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [21713.800213] [21713.800219] kfence-#69: 0x000000009149b0d5-0x000000004c0697fb, size=1064, cache=kmalloc-2k [21713.800219] [21713.800224] allocated by task 13 on cpu 0 at 21705.501373s: [21713.800241] ath10k_peer_map_event+0x7e/0x154 [ath10k_core] [21713.800254] ath10k_htt_t2h_msg_handler+0x586/0x1039 [ath10k_core] [21713.800265] ath10k_htt_htc_t2h_msg_handler+0x12/0x28 [ath10k_core] [21713.800277] ath10k_htc_rx_completion_handler+0x14c/0x1b5 [ath10k_core] [21713.800283] ath10k_pci_process_rx_cb+0x195/0x1df [ath10k_pci] [21713.800294] ath10k_ce_per_engine_service+0x55/0x74 [ath10k_core] [21713.800305] ath10k_ce_per_engine_service_any+0x76/0x84 [ath10k_core] [21713.800310] ath10k_pci_napi_poll+0x49/0x144 [ath10k_pci] [21713.800316] net_rx_action+0xdc/0x361 [21713.800320] __do_softirq+0x163/0x29a [21713.800325] asm_call_irq_on_stack+0x12/0x20 [21713.800331] do_softirq_own_stack+0x3c/0x48 [21713.800337] __irq_exit_rcu+0x9b/0x9d [21713.800342] common_interrupt+0xc9/0x14d [21713.800346] asm_common_interrupt+0x1e/0x40 [21713.800351] ksoftirqd_should_run+0x5/0x16 [21713.800357] smpboot_thread_fn+0x148/0x211 [21713.800362] kthread+0x150/0x15f [21713.800367] ret_from_fork+0x22/0x30 [21713.800370] [21713.800374] freed by task 708 on cpu 1 at 21713.799953s: [21713.800498] ath10k_sta_state+0x2c6/0xb8a [ath10k_core] [21713.800515] drv_sta_state+0x115/0x677 [mac80211] [21713.800532] __sta_info_destroy_part2+0xb1/0x133 [mac80211] [21713.800548] __sta_info_flush+0x11d/0x162 [mac80211] [21713.800565] ieee80211_set_disassoc+0x12d/0x2f4 [mac80211] [21713.800581] ieee80211_mgd_deauth+0x26c/0x29b [mac80211] [21713.800598] cfg80211_mlme_deauth+0x13f/0x1bb [cfg80211] [21713.800614] nl80211_deauthenticate+0xf8/0x121 [cfg80211] [21713.800619] genl_rcv_msg+0x38e/0x3be [21713.800623] netlink_rcv_skb+0x89/0xf7 [21713.800628] genl_rcv+0x28/0x36 [21713.800632] netlink_unicast+0x179/0x24b [21713.800637] netlink_sendmsg+0x3a0/0x40e [21713.800642] sock_sendmsg+0x72/0x76 [21713.800646] ____sys_sendmsg+0x16d/0x1e3 [21713.800651] ___sys_sendmsg+0x95/0xd1 [21713.800655] __sys_sendmsg+0x85/0xbf [21713.800659] do_syscall_64+0x43/0x55 [21713.800663] entry_SYSCALL_64_after_hwframe+0x44/0xa9 Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 Fixes: d0eeafad1189 ("ath10k: Clean up peer when sta goes away.") Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220801141930.16794-1-quic_wgong@quicinc.com Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath10k/mac.c | 54 ++++++++++++++------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 8a80919b627f..8208434d7d2b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -864,11 +864,36 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) return 0; } +static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer) +{ + int peer_id, i; + + lockdep_assert_held(&ar->conf_mutex); + + for_each_set_bit(peer_id, peer->peer_ids, + ATH10K_MAX_NUM_PEER_IDS) { + ar->peer_map[peer_id] = NULL; + } + + /* Double check that peer is properly un-referenced from + * the peer_map + */ + for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { + if (ar->peer_map[i] == peer) { + ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n", + peer->addr, peer, i); + ar->peer_map[i] = NULL; + } + } + + list_del(&peer->list); + kfree(peer); + ar->num_peers--; +} + static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) { struct ath10k_peer *peer, *tmp; - int peer_id; - int i; lockdep_assert_held(&ar->conf_mutex); @@ -880,25 +905,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n", peer->addr, vdev_id); - for_each_set_bit(peer_id, peer->peer_ids, - ATH10K_MAX_NUM_PEER_IDS) { - ar->peer_map[peer_id] = NULL; - } - - /* Double check that peer is properly un-referenced from - * the peer_map - */ - for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { - if (ar->peer_map[i] == peer) { - ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n", - peer->addr, peer, i); - ar->peer_map[i] = NULL; - } - } - - list_del(&peer->list); - kfree(peer); - ar->num_peers--; + ath10k_peer_map_cleanup(ar, peer); } spin_unlock_bh(&ar->data_lock); } @@ -7580,10 +7587,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, /* Clean up the peer object as well since we * must have failed to do this above. */ - list_del(&peer->list); - ar->peer_map[i] = NULL; - kfree(peer); - ar->num_peers--; + ath10k_peer_map_cleanup(ar, peer); } } spin_unlock_bh(&ar->data_lock); From 3d0a101e71395d185ce5826d76d396ef32a7f4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 15 Aug 2022 10:02:27 +0200 Subject: [PATCH 153/610] leds: lm3601x: Don't use mutex after it was destroyed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 32f7eed0c763a9b89f6b357ec54b48398fc7b99e ] The mutex might still be in use until the devm cleanup callback devm_led_classdev_flash_release() is called. This only happens some time after lm3601x_remove() completed. Fixes: e63a744871a3 ("leds: lm3601x: Convert class registration to device managed") Acked-by: Pavel Machek Signed-off-by: Uwe Kleine-König Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/leds/flash/leds-lm3601x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/leds/flash/leds-lm3601x.c b/drivers/leds/flash/leds-lm3601x.c index d0e1d4814042..3d1272748201 100644 --- a/drivers/leds/flash/leds-lm3601x.c +++ b/drivers/leds/flash/leds-lm3601x.c @@ -444,8 +444,6 @@ static int lm3601x_remove(struct i2c_client *client) { struct lm3601x_led *led = i2c_get_clientdata(client); - mutex_destroy(&led->lock); - return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG, LM3601X_ENABLE_MASK, LM3601X_MODE_STANDBY); From 4ed5155043c97ac8912bcf67331df87c833fb067 Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Tue, 23 Aug 2022 03:31:25 +0200 Subject: [PATCH 154/610] bpf: Fix reference state management for synchronous callbacks [ Upstream commit 9d9d00ac29d0ef7ce426964de46fa6b380357d0a ] Currently, verifier verifies callback functions (sync and async) as if they will be executed once, (i.e. it explores execution state as if the function was being called once). The next insn to explore is set to start of subprog and the exit from nested frame is handled using curframe > 0 and prepare_func_exit. In case of async callback it uses a customized variant of push_stack simulating a kind of branch to set up custom state and execution context for the async callback. While this approach is simple and works when callback really will be executed only once, it is unsafe for all of our current helpers which are for_each style, i.e. they execute the callback multiple times. A callback releasing acquired references of the caller may do so multiple times, but currently verifier sees it as one call inside the frame, which then returns to caller. Hence, it thinks it released some reference that the cb e.g. got access through callback_ctx (register filled inside cb from spilled typed register on stack). Similarly, it may see that an acquire call is unpaired inside the callback, so the caller will copy the reference state of callback and then will have to release the register with new ref_obj_ids. But again, the callback may execute multiple times, but the verifier will only account for acquired references for a single symbolic execution of the callback, which will cause leaks. Note that for async callback case, things are different. While currently we have bpf_timer_set_callback which only executes it once, even for multiple executions it would be safe, as reference state is NULL and check_reference_leak would force program to release state before BPF_EXIT. The state is also unaffected by analysis for the caller frame. Hence async callback is safe. Since we want the reference state to be accessible, e.g. for pointers loaded from stack through callback_ctx's PTR_TO_STACK, we still have to copy caller's reference_state to callback's bpf_func_state, but we enforce that whatever references it adds to that reference_state has been released before it hits BPF_EXIT. This requires introducing a new callback_ref member in the reference state to distinguish between caller vs callee references. Hence, check_reference_leak now errors out if it sees we are in callback_fn and we have not released callback_ref refs. Since there can be multiple nested callbacks, like frame 0 -> cb1 -> cb2 etc. we need to also distinguish between whether this particular ref belongs to this callback frame or parent, and only error for our own, so we store state->frameno (which is always non-zero for callbacks). In short, callbacks can read parent reference_state, but cannot mutate it, to be able to use pointers acquired by the caller. They must only undo their changes (by releasing their own acquired_refs before BPF_EXIT) on top of caller reference_state before returning (at which point the caller and callback state will match anyway, so no need to copy it back to caller). Fixes: 69c087ba6225 ("bpf: Add bpf_for_each_map_elem() helper") Signed-off-by: Kumar Kartikeya Dwivedi Link: https://lore.kernel.org/r/20220823013125.24938-1-memxor@gmail.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- include/linux/bpf_verifier.h | 11 ++++++++++ kernel/bpf/verifier.c | 42 ++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index bb1cc3fbc4ba..5625e19ae95b 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -192,6 +192,17 @@ struct bpf_reference_state { * is used purely to inform the user of a reference leak. */ int insn_idx; + /* There can be a case like: + * main (frame 0) + * cb (frame 1) + * func (frame 3) + * cb (frame 4) + * Hence for frame 4, if callback_ref just stored boolean, it would be + * impossible to distinguish nested callback refs. Hence store the + * frameno and compare that to callback_ref in check_reference_leak when + * exiting a callback function. + */ + int callback_ref; }; /* state of the program: diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 5c9ebcbf6f5f..c3a4158e838e 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -851,6 +851,7 @@ static int acquire_reference_state(struct bpf_verifier_env *env, int insn_idx) id = ++env->id_gen; state->refs[new_ofs].id = id; state->refs[new_ofs].insn_idx = insn_idx; + state->refs[new_ofs].callback_ref = state->in_callback_fn ? state->frameno : 0; return id; } @@ -863,6 +864,9 @@ static int release_reference_state(struct bpf_func_state *state, int ptr_id) last_idx = state->acquired_refs - 1; for (i = 0; i < state->acquired_refs; i++) { if (state->refs[i].id == ptr_id) { + /* Cannot release caller references in callbacks */ + if (state->in_callback_fn && state->refs[i].callback_ref != state->frameno) + return -EINVAL; if (last_idx && i != last_idx) memcpy(&state->refs[i], &state->refs[last_idx], sizeof(*state->refs)); @@ -6005,10 +6009,17 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx) caller->regs[BPF_REG_0] = *r0; } - /* Transfer references to the caller */ - err = copy_reference_state(caller, callee); - if (err) - return err; + /* callback_fn frame should have released its own additions to parent's + * reference state at this point, or check_reference_leak would + * complain, hence it must be the same as the caller. There is no need + * to copy it back. + */ + if (!callee->in_callback_fn) { + /* Transfer references to the caller */ + err = copy_reference_state(caller, callee); + if (err) + return err; + } *insn_idx = callee->callsite + 1; if (env->log.level & BPF_LOG_LEVEL) { @@ -6129,13 +6140,20 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta, static int check_reference_leak(struct bpf_verifier_env *env) { struct bpf_func_state *state = cur_func(env); + bool refs_lingering = false; int i; + if (state->frameno && !state->in_callback_fn) + return 0; + for (i = 0; i < state->acquired_refs; i++) { + if (state->in_callback_fn && state->refs[i].callback_ref != state->frameno) + continue; verbose(env, "Unreleased reference id=%d alloc_insn=%d\n", state->refs[i].id, state->refs[i].insn_idx); + refs_lingering = true; } - return state->acquired_refs ? -EINVAL : 0; + return refs_lingering ? -EINVAL : 0; } static int check_bpf_snprintf_call(struct bpf_verifier_env *env, @@ -11150,6 +11168,16 @@ static int do_check(struct bpf_verifier_env *env) return -EINVAL; } + /* We must do check_reference_leak here before + * prepare_func_exit to handle the case when + * state->curframe > 0, it may be a callback + * function, for which reference_state must + * match caller reference state when it exits. + */ + err = check_reference_leak(env); + if (err) + return err; + if (state->curframe) { /* exit from nested function */ err = prepare_func_exit(env, &env->insn_idx); @@ -11159,10 +11187,6 @@ static int do_check(struct bpf_verifier_env *env) continue; } - err = check_reference_leak(env); - if (err) - return err; - err = check_return_code(env); if (err) return err; From 6e8eadfa9bb1eb3b6a2eda3a69a3713ab8a55a45 Mon Sep 17 00:00:00 2001 From: Hari Chandrakanthan Date: Wed, 27 Jul 2022 12:02:29 +0530 Subject: [PATCH 155/610] wifi: mac80211: allow bw change during channel switch in mesh [ Upstream commit 6b75f133fe05c36c52d691ff21545d5757fff721 ] From 'IEEE Std 802.11-2020 section 11.8.8.4.1': The mesh channel switch may be triggered by the need to avoid interference to a detected radar signal, or to reassign mesh STA channels to ensure the MBSS connectivity. A 20/40 MHz MBSS may be changed to a 20 MHz MBSS and a 20 MHz MBSS may be changed to a 20/40 MHz MBSS. Since the standard allows the change of bandwidth during the channel switch in mesh, remove the bandwidth check present in ieee80211_set_csa_beacon. Fixes: c6da674aff94 ("{nl,cfg,mac}80211: enable the triggering of CSA frame in mesh") Signed-off-by: Hari Chandrakanthan Link: https://lore.kernel.org/r/1658903549-21218-1-git-send-email-quic_haric@quicinc.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/cfg.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3f625e836a03..4fa216a108ae 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3384,9 +3384,6 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_MESH_POINT: { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - if (params->chandef.width != sdata->vif.bss_conf.chandef.width) - return -EINVAL; - /* changes into another band are not supported */ if (sdata->vif.bss_conf.chandef.chan->band != params->chandef.chan->band) From 0a16bbc8b030ffe820b244f0702fe43f8293e1fa Mon Sep 17 00:00:00 2001 From: Lam Thai Date: Wed, 24 Aug 2022 15:59:00 -0700 Subject: [PATCH 156/610] bpftool: Fix a wrong type cast in btf_dumper_int [ Upstream commit 7184aef9c0f7a81db8fd18d183ee42481d89bf35 ] When `data` points to a boolean value, casting it to `int *` is problematic and could lead to a wrong value being passed to `jsonw_bool`. Change the cast to `bool *` instead. Fixes: b12d6ec09730 ("bpf: btf: add btf print functionality") Signed-off-by: Lam Thai Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet Acked-by: John Fastabend Link: https://lore.kernel.org/bpf/20220824225859.9038-1-lamthai@arista.com Signed-off-by: Sasha Levin --- tools/bpf/bpftool/btf_dumper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 9c25286a5c73..70fb26a3dfa8 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c @@ -418,7 +418,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, *(char *)data); break; case BTF_INT_BOOL: - jsonw_bool(jw, *(int *)data); + jsonw_bool(jw, *(bool *)data); break; default: /* shouldn't happen */ From e962e458bf96df2583b974a3ab272dd8a4bdb983 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 27 Aug 2022 13:42:07 +0200 Subject: [PATCH 157/610] spi: mt7621: Fix an error message in mt7621_spi_probe() [ Upstream commit 2b2bf6b7faa9010fae10dc7de76627a3fdb525b3 ] 'status' is known to be 0 at this point. The expected error code is PTR_ERR(clk). Switch to dev_err_probe() in order to display the expected error code (in a human readable way). This also filters -EPROBE_DEFER cases, should it happen. Fixes: 1ab7f2a43558 ("staging: mt7621-spi: add mt7621 support") Signed-off-by: Christophe JAILLET Reviewed-by: Matthias Brugger Link: https://lore.kernel.org/r/928f3fb507d53ba0774df27cea0bbba4b055993b.1661599671.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-mt7621.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-mt7621.c b/drivers/spi/spi-mt7621.c index b4b9b7309b5e..351b0ef52bbc 100644 --- a/drivers/spi/spi-mt7621.c +++ b/drivers/spi/spi-mt7621.c @@ -340,11 +340,9 @@ static int mt7621_spi_probe(struct platform_device *pdev) return PTR_ERR(base); clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", - status); - return PTR_ERR(clk); - } + if (IS_ERR(clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk), + "unable to get SYS clock\n"); status = clk_prepare_enable(clk); if (status) From 0559a6d96a991e421a8550a595e10465a31dacc7 Mon Sep 17 00:00:00 2001 From: Kohei Tarumizu Date: Wed, 24 Aug 2022 09:44:10 -0700 Subject: [PATCH 158/610] x86/resctrl: Fix to restore to original value when re-enabling hardware prefetch register [ Upstream commit 499c8bb4693d1c8d8f3d6dd38e5bdde3ff5bd906 ] The current pseudo_lock.c code overwrites the value of the MSR_MISC_FEATURE_CONTROL to 0 even if the original value is not 0. Therefore, modify it to save and restore the original values. Fixes: 018961ae5579 ("x86/intel_rdt: Pseudo-lock region creation/removal core") Fixes: 443810fe6160 ("x86/intel_rdt: Create debugfs files for pseudo-locking testing") Fixes: 8a2fc0e1bc0c ("x86/intel_rdt: More precise L2 hit/miss measurements") Signed-off-by: Kohei Tarumizu Signed-off-by: Dave Hansen Acked-by: Reinette Chatre Link: https://lkml.kernel.org/r/eb660f3c2010b79a792c573c02d01e8e841206ad.1661358182.git.reinette.chatre@intel.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/resctrl/pseudo_lock.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c index db813f819ad6..4d8398986f78 100644 --- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c +++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c @@ -420,6 +420,7 @@ static int pseudo_lock_fn(void *_rdtgrp) struct pseudo_lock_region *plr = rdtgrp->plr; u32 rmid_p, closid_p; unsigned long i; + u64 saved_msr; #ifdef CONFIG_KASAN /* * The registers used for local register variables are also used @@ -463,6 +464,7 @@ static int pseudo_lock_fn(void *_rdtgrp) * the buffer and evict pseudo-locked memory read earlier from the * cache. */ + saved_msr = __rdmsr(MSR_MISC_FEATURE_CONTROL); __wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); closid_p = this_cpu_read(pqr_state.cur_closid); rmid_p = this_cpu_read(pqr_state.cur_rmid); @@ -514,7 +516,7 @@ static int pseudo_lock_fn(void *_rdtgrp) __wrmsr(IA32_PQR_ASSOC, rmid_p, closid_p); /* Re-enable the hardware prefetcher(s) */ - wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); + wrmsrl(MSR_MISC_FEATURE_CONTROL, saved_msr); local_irq_enable(); plr->thread_done = 1; @@ -871,6 +873,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d) static int measure_cycles_lat_fn(void *_plr) { struct pseudo_lock_region *plr = _plr; + u32 saved_low, saved_high; unsigned long i; u64 start, end; void *mem_r; @@ -879,6 +882,7 @@ static int measure_cycles_lat_fn(void *_plr) /* * Disable hardware prefetchers. */ + rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); mem_r = READ_ONCE(plr->kmem); /* @@ -895,7 +899,7 @@ static int measure_cycles_lat_fn(void *_plr) end = rdtsc_ordered(); trace_pseudo_lock_mem_latency((u32)(end - start)); } - wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); + wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); local_irq_enable(); plr->thread_done = 1; wake_up_interruptible(&plr->lock_thread_wq); @@ -940,6 +944,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr, u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0; struct perf_event *miss_event, *hit_event; int hit_pmcnum, miss_pmcnum; + u32 saved_low, saved_high; unsigned int line_size; unsigned int size; unsigned long i; @@ -973,6 +978,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr, /* * Disable hardware prefetchers. */ + rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); /* Initialize rest of local variables */ @@ -1031,7 +1037,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr, */ rmb(); /* Re-enable hardware prefetchers */ - wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); + wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); local_irq_enable(); out_hit: perf_event_release_kernel(hit_event); From 68ab7690332a23231b39e43c9ecc5cfb5343dc66 Mon Sep 17 00:00:00 2001 From: Maciej Fijalkowski Date: Tue, 30 Aug 2022 14:17:05 +0200 Subject: [PATCH 159/610] xsk: Fix backpressure mechanism on Tx [ Upstream commit c00c4461689e15ac2cc3b9a595a54e4d8afd3d77 ] Commit d678cbd2f867 ("xsk: Fix handling of invalid descriptors in XSK TX batching API") fixed batch API usage against set of descriptors with invalid ones but introduced a problem when AF_XDP SW rings are smaller than HW ones. Mismatch of reported Tx'ed frames between HW generator and user space app was observed. It turned out that backpressure mechanism became a bottleneck when the amount of produced descriptors to CQ is lower than what we grabbed from XSK Tx ring. Say that 512 entries had been taken from XSK Tx ring but we had only 490 free entries in CQ. Then callsite (ZC driver) will produce only 490 entries onto HW Tx ring but 512 entries will be released from Tx ring and this is what will be seen by the user space. In order to fix this case, mix XSK Tx/CQ ring interractions by moving around internal functions and changing call order: * pull out xskq_prod_nb_free() from xskq_prod_reserve_addr_batch() up to xsk_tx_peek_release_desc_batch(); ** move xskq_cons_release_n() into xskq_cons_read_desc_batch() After doing so, algorithm can be described as follows: 1. lookup Tx entries 2. use value from 1. to reserve space in CQ (*) 3. Read from Tx ring as much descriptors as value from 2 3a. release descriptors from XSK Tx ring (**) 4. Finally produce addresses to CQ Fixes: d678cbd2f867 ("xsk: Fix handling of invalid descriptors in XSK TX batching API") Signed-off-by: Magnus Karlsson Signed-off-by: Maciej Fijalkowski Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20220830121705.8618-1-maciej.fijalkowski@intel.com Signed-off-by: Sasha Levin --- net/xdp/xsk.c | 22 +++++++++++----------- net/xdp/xsk_queue.h | 22 ++++++++++------------ 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 10c302f9c6d7..330dd498fc61 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -370,16 +370,15 @@ static u32 xsk_tx_peek_release_fallback(struct xsk_buff_pool *pool, u32 max_entr return nb_pkts; } -u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries) +u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 nb_pkts) { struct xdp_sock *xs; - u32 nb_pkts; rcu_read_lock(); if (!list_is_singular(&pool->xsk_tx_list)) { /* Fallback to the non-batched version */ rcu_read_unlock(); - return xsk_tx_peek_release_fallback(pool, max_entries); + return xsk_tx_peek_release_fallback(pool, nb_pkts); } xs = list_first_or_null_rcu(&pool->xsk_tx_list, struct xdp_sock, tx_list); @@ -388,12 +387,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries) goto out; } - max_entries = xskq_cons_nb_entries(xs->tx, max_entries); - nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, max_entries); - if (!nb_pkts) { - xs->tx->queue_empty_descs++; - goto out; - } + nb_pkts = xskq_cons_nb_entries(xs->tx, nb_pkts); /* This is the backpressure mechanism for the Tx path. Try to * reserve space in the completion queue for all packets, but @@ -401,12 +395,18 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries) * packets. This avoids having to implement any buffering in * the Tx path. */ - nb_pkts = xskq_prod_reserve_addr_batch(pool->cq, pool->tx_descs, nb_pkts); + nb_pkts = xskq_prod_nb_free(pool->cq, nb_pkts); if (!nb_pkts) goto out; - xskq_cons_release_n(xs->tx, max_entries); + nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, nb_pkts); + if (!nb_pkts) { + xs->tx->queue_empty_descs++; + goto out; + } + __xskq_cons_release(xs->tx); + xskq_prod_write_addr_batch(pool->cq, pool->tx_descs, nb_pkts); xs->sk.sk_write_space(&xs->sk); out: diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h index 491a18c1f786..cca1fce8035c 100644 --- a/net/xdp/xsk_queue.h +++ b/net/xdp/xsk_queue.h @@ -201,6 +201,11 @@ static inline bool xskq_cons_read_desc(struct xsk_queue *q, return false; } +static inline void xskq_cons_release_n(struct xsk_queue *q, u32 cnt) +{ + q->cached_cons += cnt; +} + static inline u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool, u32 max) { @@ -222,6 +227,8 @@ static inline u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff cached_cons++; } + /* Release valid plus any invalid entries */ + xskq_cons_release_n(q, cached_cons - q->cached_cons); return nb_entries; } @@ -287,11 +294,6 @@ static inline void xskq_cons_release(struct xsk_queue *q) q->cached_cons++; } -static inline void xskq_cons_release_n(struct xsk_queue *q, u32 cnt) -{ - q->cached_cons += cnt; -} - static inline bool xskq_cons_is_full(struct xsk_queue *q) { /* No barriers needed since data is not accessed */ @@ -353,21 +355,17 @@ static inline int xskq_prod_reserve_addr(struct xsk_queue *q, u64 addr) return 0; } -static inline u32 xskq_prod_reserve_addr_batch(struct xsk_queue *q, struct xdp_desc *descs, - u32 max) +static inline void xskq_prod_write_addr_batch(struct xsk_queue *q, struct xdp_desc *descs, + u32 nb_entries) { struct xdp_umem_ring *ring = (struct xdp_umem_ring *)q->ring; - u32 nb_entries, i, cached_prod; - - nb_entries = xskq_prod_nb_free(q, max); + u32 i, cached_prod; /* A, matches D */ cached_prod = q->cached_prod; for (i = 0; i < nb_entries; i++) ring->desc[cached_prod++ & q->ring_mask] = descs[i].addr; q->cached_prod = cached_prod; - - return nb_entries; } static inline int xskq_prod_reserve_desc(struct xsk_queue *q, From 0b00c6130c1aad1518327f07de811b8d68116015 Mon Sep 17 00:00:00 2001 From: Hou Tao Date: Wed, 31 Aug 2022 12:26:27 +0800 Subject: [PATCH 160/610] bpf: Disable preemption when increasing per-cpu map_locked [ Upstream commit 2775da21628738ce073a3a6a806adcbaada0f091 ] Per-cpu htab->map_locked is used to prohibit the concurrent accesses from both NMI and non-NMI contexts. But since commit 74d862b682f5 ("sched: Make migrate_disable/enable() independent of RT"), migrate_disable() is also preemptible under CONFIG_PREEMPT case, so now map_locked also disallows concurrent updates from normal contexts (e.g. userspace processes) unexpectedly as shown below: process A process B htab_map_update_elem() htab_lock_bucket() migrate_disable() /* return 1 */ __this_cpu_inc_return() /* preempted by B */ htab_map_update_elem() /* the same bucket as A */ htab_lock_bucket() migrate_disable() /* return 2, so lock fails */ __this_cpu_inc_return() return -EBUSY A fix that seems feasible is using in_nmi() in htab_lock_bucket() and only checking the value of map_locked for nmi context. But it will re-introduce dead-lock on bucket lock if htab_lock_bucket() is re-entered through non-tracing program (e.g. fentry program). One cannot use preempt_disable() to fix this issue as htab_use_raw_lock being false causes the bucket lock to be a spin lock which can sleep and does not work with preempt_disable(). Therefore, use migrate_disable() when using the spinlock instead of preempt_disable() and defer fixing concurrent updates to when the kernel has its own BPF memory allocator. Fixes: 74d862b682f5 ("sched: Make migrate_disable/enable() independent of RT") Reviewed-by: Hao Luo Signed-off-by: Hou Tao Link: https://lore.kernel.org/r/20220831042629.130006-2-houtao@huaweicloud.com Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- kernel/bpf/hashtab.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 47eebb88695e..cae858985f0c 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -161,17 +161,25 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, unsigned long *pflags) { unsigned long flags; + bool use_raw_lock; hash = hash & HASHTAB_MAP_LOCK_MASK; - migrate_disable(); + use_raw_lock = htab_use_raw_lock(htab); + if (use_raw_lock) + preempt_disable(); + else + migrate_disable(); if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) { __this_cpu_dec(*(htab->map_locked[hash])); - migrate_enable(); + if (use_raw_lock) + preempt_enable(); + else + migrate_enable(); return -EBUSY; } - if (htab_use_raw_lock(htab)) + if (use_raw_lock) raw_spin_lock_irqsave(&b->raw_lock, flags); else spin_lock_irqsave(&b->lock, flags); @@ -184,13 +192,18 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, struct bucket *b, u32 hash, unsigned long flags) { + bool use_raw_lock = htab_use_raw_lock(htab); + hash = hash & HASHTAB_MAP_LOCK_MASK; - if (htab_use_raw_lock(htab)) + if (use_raw_lock) raw_spin_unlock_irqrestore(&b->raw_lock, flags); else spin_unlock_irqrestore(&b->lock, flags); __this_cpu_dec(*(htab->map_locked[hash])); - migrate_enable(); + if (use_raw_lock) + preempt_enable(); + else + migrate_enable(); } static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node); From 0e13425104903970a5ede853082d3bbb4edec6f3 Mon Sep 17 00:00:00 2001 From: Hou Tao Date: Wed, 31 Aug 2022 12:26:28 +0800 Subject: [PATCH 161/610] bpf: Propagate error from htab_lock_bucket() to userspace [ Upstream commit 66a7a92e4d0d091e79148a4c6ec15d1da65f4280 ] In __htab_map_lookup_and_delete_batch() if htab_lock_bucket() returns -EBUSY, it will go to next bucket. Going to next bucket may not only skip the elements in current bucket silently, but also incur out-of-bound memory access or expose kernel memory to userspace if current bucket_cnt is greater than bucket_size or zero. Fixing it by stopping batch operation and returning -EBUSY when htab_lock_bucket() fails, and the application can retry or skip the busy batch as needed. Fixes: 20b6cc34ea74 ("bpf: Avoid hashtab deadlock with map_locked") Reported-by: Hao Sun Signed-off-by: Hou Tao Link: https://lore.kernel.org/r/20220831042629.130006-3-houtao@huaweicloud.com Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- kernel/bpf/hashtab.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index cae858985f0c..e7f45a966e6b 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -1671,8 +1671,11 @@ again_nocopy: /* do not grab the lock unless need it (bucket_cnt > 0). */ if (locked) { ret = htab_lock_bucket(htab, b, batch, &flags); - if (ret) - goto next_batch; + if (ret) { + rcu_read_unlock(); + bpf_enable_instrumentation(); + goto after_loop; + } } bucket_cnt = 0; From f91e25cfa5538e930ec8f91aab1168e6c94755ef Mon Sep 17 00:00:00 2001 From: Hou Tao Date: Thu, 1 Sep 2022 14:19:35 +0800 Subject: [PATCH 162/610] bpf: Use this_cpu_{inc|dec|inc_return} for bpf_task_storage_busy [ Upstream commit 197827a05e13808c60f52632e9887eede63f1c16 ] Now migrate_disable() does not disable preemption and under some architectures (e.g. arm64) __this_cpu_{inc|dec|inc_return} are neither preemption-safe nor IRQ-safe, so for fully preemptible kernel concurrent lookups or updates on the same task local storage and on the same CPU may make bpf_task_storage_busy be imbalanced, and bpf_task_storage_trylock() on the specific cpu will always fail. Fixing it by using this_cpu_{inc|dec|inc_return} when manipulating bpf_task_storage_busy. Fixes: bc235cdb423a ("bpf: Prevent deadlock from recursive bpf_task_storage_[get|delete]") Signed-off-by: Hou Tao Acked-by: Alexei Starovoitov Link: https://lore.kernel.org/r/20220901061938.3789460-2-houtao@huaweicloud.com Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- kernel/bpf/bpf_local_storage.c | 4 ++-- kernel/bpf/bpf_task_storage.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c index b305270b7a4b..de4d741d99a3 100644 --- a/kernel/bpf/bpf_local_storage.c +++ b/kernel/bpf/bpf_local_storage.c @@ -506,11 +506,11 @@ void bpf_local_storage_map_free(struct bpf_local_storage_map *smap, struct bpf_local_storage_elem, map_node))) { if (busy_counter) { migrate_disable(); - __this_cpu_inc(*busy_counter); + this_cpu_inc(*busy_counter); } bpf_selem_unlink(selem); if (busy_counter) { - __this_cpu_dec(*busy_counter); + this_cpu_dec(*busy_counter); migrate_enable(); } cond_resched_rcu(); diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c index ebfa8bc90892..6b7bfce23915 100644 --- a/kernel/bpf/bpf_task_storage.c +++ b/kernel/bpf/bpf_task_storage.c @@ -25,20 +25,20 @@ static DEFINE_PER_CPU(int, bpf_task_storage_busy); static void bpf_task_storage_lock(void) { migrate_disable(); - __this_cpu_inc(bpf_task_storage_busy); + this_cpu_inc(bpf_task_storage_busy); } static void bpf_task_storage_unlock(void) { - __this_cpu_dec(bpf_task_storage_busy); + this_cpu_dec(bpf_task_storage_busy); migrate_enable(); } static bool bpf_task_storage_trylock(void) { migrate_disable(); - if (unlikely(__this_cpu_inc_return(bpf_task_storage_busy) != 1)) { - __this_cpu_dec(bpf_task_storage_busy); + if (unlikely(this_cpu_inc_return(bpf_task_storage_busy) != 1)) { + this_cpu_dec(bpf_task_storage_busy); migrate_enable(); return false; } From d091771f511dded5d03b028c6c6559fdf34e886f Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Thu, 11 Aug 2022 08:49:07 +0800 Subject: [PATCH 163/610] Bluetooth: btusb: mediatek: fix WMT failure during runtime suspend [ Upstream commit fd3f106677bac70437dc12e76c827294ed495a44 ] WMT cmd/event doesn't follow up the generic HCI cmd/event handling, it needs constantly polling control pipe until the host received the WMT event, thus, we should require to specifically acquire PM counter on the USB to prevent the interface from entering auto suspended while WMT cmd/event in progress. Fixes: a1c49c434e15 ("Bluetooth: btusb: Add protocol support for MediaTek MT7668U USB devices") Co-developed-by: Jing Cai Signed-off-by: Jing Cai Signed-off-by: Sean Wang Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/btusb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 627436329b50..64d72ea0c310 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2435,15 +2435,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); + /* WMT cmd/event doesn't follow up the generic HCI cmd/event handling, + * it needs constantly polling control pipe until the host received the + * WMT event, thus, we should require to specifically acquire PM counter + * on the USB to prevent the interface from entering auto suspended + * while WMT cmd/event in progress. + */ + err = usb_autopm_get_interface(data->intf); + if (err < 0) + goto err_free_wc; + err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); if (err < 0) { clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags); + usb_autopm_put_interface(data->intf); goto err_free_wc; } /* Submit control IN URB on demand to process the WMT event */ err = btusb_mtk_submit_wmt_recv_urb(hdev); + + usb_autopm_put_interface(data->intf); + if (err < 0) goto err_free_wc; From 6f9484e969cb4917d7dc500a9689182e9dfc2b6a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 19 Aug 2022 08:22:32 +0300 Subject: [PATCH 164/610] wifi: rtl8xxxu: tighten bounds checking in rtl8xxxu_read_efuse() [ Upstream commit 620d5eaeb9059636864bda83ca1c68c20ede34a5 ] There some bounds checking to ensure that "map_addr" is not out of bounds before the start of the loop. But the checking needs to be done as we iterate through the loop because "map_addr" gets larger as we iterate. Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") Signed-off-by: Dan Carpenter Acked-by: Jes Sorensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/Yv8eGLdBslLAk3Ct@kili Signed-off-by: Sasha Levin --- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 774341b0005a..30a2e938d19a 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -1874,13 +1874,6 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv) /* We have 8 bits to indicate validity */ map_addr = offset * 8; - if (map_addr >= EFUSE_MAP_LEN) { - dev_warn(dev, "%s: Illegal map_addr (%04x), " - "efuse corrupt!\n", - __func__, map_addr); - ret = -EINVAL; - goto exit; - } for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { /* Check word enable condition in the section */ if (word_mask & BIT(i)) { @@ -1891,6 +1884,13 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv) ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); if (ret) goto exit; + if (map_addr >= EFUSE_MAP_LEN - 1) { + dev_warn(dev, "%s: Illegal map_addr (%04x), " + "efuse corrupt!\n", + __func__, map_addr); + ret = -EINVAL; + goto exit; + } priv->efuse_wifi.raw[map_addr++] = val8; ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); From 69995c64e50efcf6dcc33b30a1142eaa62c401c1 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 26 Aug 2022 10:38:17 +0800 Subject: [PATCH 165/610] wifi: rtw88: add missing destroy_workqueue() on error path in rtw_core_init() [ Upstream commit b0ea758b30bbdf7c4323c78b7c50c05d2e1224d5 ] Add the missing destroy_workqueue() before return from rtw_core_init() in error path. Fixes: fe101716c7c9 ("rtw88: replace tx tasklet with work queue") Signed-off-by: Yang Yingliang Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220826023817.3908255-1-yangyingliang@huawei.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtw88/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 5786995d90d4..d7b7b2cce974 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -1869,7 +1869,7 @@ int rtw_core_init(struct rtw_dev *rtwdev) ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); if (ret) { rtw_warn(rtwdev, "no firmware loaded\n"); - return ret; + goto out; } if (chip->wow_fw_name) { @@ -1879,11 +1879,15 @@ int rtw_core_init(struct rtw_dev *rtwdev) wait_for_completion(&rtwdev->fw.completion); if (rtwdev->fw.firmware) release_firmware(rtwdev->fw.firmware); - return ret; + goto out; } } return 0; + +out: + destroy_workqueue(rtwdev->tx_wq); + return ret; } EXPORT_SYMBOL(rtw_core_init); From 37005a948677c3305fab6a3354e5c2945568d7c0 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 1 Sep 2022 13:26:45 -0700 Subject: [PATCH 166/610] selftests/xsk: Avoid use-after-free on ctx [ Upstream commit af515a5587b8f45f19e11657746e0c89411b0380 ] The put lowers the reference count to 0 and frees ctx, reading it afterwards is invalid. Move the put after the uses and determine the last use by the reference count being 1. Fixes: 39e940d4abfa ("selftests/xsk: Destroy BPF resources only when ctx refcount drops to 0") Signed-off-by: Ian Rogers Signed-off-by: Daniel Borkmann Acked-by: Magnus Karlsson Link: https://lore.kernel.org/bpf/20220901202645.1463552-1-irogers@google.com Signed-off-by: Sasha Levin --- tools/lib/bpf/xsk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 42b8437b0535..2be3197914e4 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -1245,15 +1245,15 @@ void xsk_socket__delete(struct xsk_socket *xsk) ctx = xsk->ctx; umem = ctx->umem; - xsk_put_ctx(ctx, true); - - if (!ctx->refcount) { + if (ctx->refcount == 1) { xsk_delete_bpf_maps(xsk); close(ctx->prog_fd); if (ctx->has_bpf_link) close(ctx->link_fd); } + xsk_put_ctx(ctx, true); + err = xsk_get_mmap_offsets(xsk->fd, &off); if (!err) { if (xsk->rx) { From e22f6499183d7eeb53cc455f4b55fe1343094fd8 Mon Sep 17 00:00:00 2001 From: Xu Qiang Date: Thu, 25 Aug 2022 06:53:23 +0000 Subject: [PATCH 167/610] spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 70034320fdc597b8f58b4a43bb547f17c4c5557a ] Add the missing clk_disable_unprepare() before return from spi_qup_resume() in the error handling case. Fixes: 64ff247a978f (“spi: Add Qualcomm QUP SPI controller support”) Signed-off-by: Xu Qiang Link: https://lore.kernel.org/r/20220825065324.68446-1-xuqiang36@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-qup.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index d39dec6d1c91..668d79922fac 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1246,14 +1246,25 @@ static int spi_qup_resume(struct device *device) return ret; ret = clk_prepare_enable(controller->cclk); - if (ret) + if (ret) { + clk_disable_unprepare(controller->iclk); return ret; + } ret = spi_qup_set_state(controller, QUP_STATE_RESET); if (ret) - return ret; + goto disable_clk; - return spi_master_resume(master); + ret = spi_master_resume(master); + if (ret) + goto disable_clk; + + return 0; + +disable_clk: + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); + return ret; } #endif /* CONFIG_PM_SLEEP */ From fefd2269e681157afa75c0324fc7d6106d6a932d Mon Sep 17 00:00:00 2001 From: Xu Qiang Date: Thu, 25 Aug 2022 06:53:24 +0000 Subject: [PATCH 168/610] spi: qup: add missing clk_disable_unprepare on error in spi_qup_pm_resume_runtime() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 494a22765ce479c9f8ad181c5d24cffda9f534bb ] Add the missing clk_disable_unprepare() before return from spi_qup_pm_resume_runtime() in the error handling case. Fixes: dae1a7700b34 (“spi: qup: Handle clocks in pm_runtime suspend and resume”) Signed-off-by: Xu Qiang Link: https://lore.kernel.org/r/20220825065324.68446-2-xuqiang36@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-qup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 668d79922fac..f3877eeb3da6 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1199,8 +1199,10 @@ static int spi_qup_pm_resume_runtime(struct device *device) return ret; ret = clk_prepare_enable(controller->cclk); - if (ret) + if (ret) { + clk_disable_unprepare(controller->iclk); return ret; + } /* Disable clocks auto gaiting */ config = readl_relaxed(controller->base + QUP_CONFIG); From 36c484bac9edfde09d0de3fe2ccf7ef5d497ca74 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 31 Aug 2022 19:12:36 +0300 Subject: [PATCH 169/610] wifi: rtl8xxxu: Fix skb misuse in TX queue selection [ Upstream commit edd5747aa12ed61a5ecbfa58d3908623fddbf1e8 ] rtl8xxxu_queue_select() selects the wrong TX queues because it's reading memory from the wrong address. It expects to find ieee80211_hdr at skb->data, but that's not the case after skb_push(). Move the call to rtl8xxxu_queue_select() before the call to skb_push(). Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") Signed-off-by: Bitterblue Smith Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/7fa4819a-4f20-b2af-b7a6-8ee01ac49295@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 30a2e938d19a..395c31060950 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4984,6 +4984,8 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, if (control && control->sta) sta = control->sta; + queue = rtl8xxxu_queue_select(hw, skb); + tx_desc = skb_push(skb, tx_desc_size); memset(tx_desc, 0, tx_desc_size); @@ -4996,7 +4998,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, is_broadcast_ether_addr(ieee80211_get_DA(hdr))) tx_desc->txdw0 |= TXDESC_BROADMULTICAST; - queue = rtl8xxxu_queue_select(hw, skb); tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT); if (tx_info->control.hw_key) { From 4ce47c5545d2ec52207dc2f4a1f9c4b8d5f54516 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 8 Sep 2022 14:18:03 +0200 Subject: [PATCH 170/610] spi: meson-spicc: do not rely on busy flag in pow2 clk ops [ Upstream commit 36acf80fc0c4b5ebe6fa010b524d442ee7f08fd3 ] Since [1], controller's busy flag isn't set anymore when the __spi_transfer_message_noqueue() is used instead of the __spi_pump_transfer_message() logic for spi_sync transfers. Since the pow2 clock ops were limited to only be available when a transfer is ongoing (between prepare_transfer_hardware and unprepare_transfer_hardware callbacks), the only way to track this down is to check for the controller cur_msg. [1] ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync") Fixes: 09992025dacd ("spi: meson-spicc: add local pow2 clock ops to preserve rate between messages") Fixes: ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync") Reported-by: Markus Schneider-Pargmann Signed-off-by: Neil Armstrong Tested-by: Markus Schneider-Pargmann Link: https://lore.kernel.org/r/20220908121803.919943-1-narmstrong@baylibre.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-meson-spicc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c index e4cb52e1fe26..6974a1c947aa 100644 --- a/drivers/spi/spi-meson-spicc.c +++ b/drivers/spi/spi-meson-spicc.c @@ -537,7 +537,7 @@ static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw, struct clk_divider *divider = to_clk_divider(hw); struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); - if (!spicc->master->cur_msg || !spicc->master->busy) + if (!spicc->master->cur_msg) return 0; return clk_divider_ops.recalc_rate(hw, parent_rate); @@ -549,7 +549,7 @@ static int meson_spicc_pow2_determine_rate(struct clk_hw *hw, struct clk_divider *divider = to_clk_divider(hw); struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); - if (!spicc->master->cur_msg || !spicc->master->busy) + if (!spicc->master->cur_msg) return -EINVAL; return clk_divider_ops.determine_rate(hw, req); @@ -561,7 +561,7 @@ static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate, struct clk_divider *divider = to_clk_divider(hw); struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider); - if (!spicc->master->cur_msg || !spicc->master->busy) + if (!spicc->master->cur_msg) return -EINVAL; return clk_divider_ops.set_rate(hw, rate, parent_rate); From 5d9222c68022a3cce919dc7ccd93b28aebadabfd Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Sat, 10 Sep 2022 11:01:20 +0000 Subject: [PATCH 171/610] bpf: btf: fix truncated last_member_type_id in btf_struct_resolve [ Upstream commit a37a32583e282d8d815e22add29bc1e91e19951a ] When trying to finish resolving a struct member, btf_struct_resolve saves the member type id in a u16 temporary variable. This truncates the 32 bit type id value if it exceeds UINT16_MAX. As a result, structs that have members with type ids > UINT16_MAX and which need resolution will fail with a message like this: [67414] STRUCT ff_device size=120 vlen=12 effect_owners type_id=67434 bits_offset=960 Member exceeds struct_size Fix this by changing the type of last_member_type_id to u32. Fixes: a0791f0df7d2 ("bpf: fix BTF limits") Reviewed-by: Stanislav Fomichev Signed-off-by: Lorenz Bauer Link: https://lore.kernel.org/r/20220910110120.339242-1-oss@lmb.io Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- kernel/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 3cfba41a0829..7cb13b9f69a6 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -2983,7 +2983,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env, if (v->next_member) { const struct btf_type *last_member_type; const struct btf_member *last_member; - u16 last_member_type_id; + u32 last_member_type_id; last_member = btf_type_member(v->t) + v->next_member - 1; last_member_type_id = last_member->type; From 9973f78c19f355f4f487a35fdb44790b21e67d16 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 2 Sep 2022 14:48:32 +0300 Subject: [PATCH 172/610] wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration [ Upstream commit e963a19c64ac0d2f8785d36a27391abd91ac77aa ] Found by comparing with the vendor driver. Currently this affects only the RTL8192EU, which is the only gen2 chip with 2 TX paths supported by this driver. It's unclear what kind of effect the mistake had in practice, since I don't have any RTL8192EU devices to test it. Fixes: e1547c535ede ("rtl8xxxu: First stab at adding IQK calibration for 8723bu parts") Signed-off-by: Bitterblue Smith Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/30a59f3a-cfa9-8379-7af0-78a8f4c77cfd@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 395c31060950..a74ded84c2ac 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -2925,12 +2925,12 @@ bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, } if (!(simubitmap & 0x30) && priv->tx_paths > 1) { - /* path B RX OK */ + /* path B TX OK */ for (i = 4; i < 6; i++) result[3][i] = result[c1][i]; } - if (!(simubitmap & 0x30) && priv->tx_paths > 1) { + if (!(simubitmap & 0xc0) && priv->tx_paths > 1) { /* path B RX OK */ for (i = 6; i < 8; i++) result[3][i] = result[c1][i]; From 5dc095a37fbdb702d928cf57d2441da5b3898432 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 2 Sep 2022 16:15:30 +0300 Subject: [PATCH 173/610] wifi: rtl8xxxu: Remove copy-paste leftover in gen2_update_rate_mask [ Upstream commit d5350756c03cdf18696295c6b11d7acc4dbf825c ] It looks like a leftover from copying rtl8xxxu_update_rate_mask, which is used with the gen1 chips. It wasn't causing any problems for my RTL8188FU test device, but it's clearly a mistake, so remove it. Fixes: f653e69009c6 ("rtl8xxxu: Implement basic 8723b specific update_rate_mask() function") Signed-off-by: Bitterblue Smith Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/d5544fe8-9798-28f1-54bd-6839a1974b10@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index a74ded84c2ac..fb2a5fc1a4e6 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4338,15 +4338,14 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, h2c.b_macid_cfg.ramask2 = (ramask >> 16) & 0xff; h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff; - h2c.ramask.arg = 0x80; h2c.b_macid_cfg.data1 = rateid; if (sgi) h2c.b_macid_cfg.data1 |= BIT(7); h2c.b_macid_cfg.data2 = bw; - dev_dbg(&priv->udev->dev, "%s: rate mask %08x, arg %02x, size %zi\n", - __func__, ramask, h2c.ramask.arg, sizeof(h2c.b_macid_cfg)); + dev_dbg(&priv->udev->dev, "%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n", + __func__, ramask, rateid, sgi, sizeof(h2c.b_macid_cfg)); rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_macid_cfg)); } From 817e8b75ae0665f38208b8c15796e7d02de72b5f Mon Sep 17 00:00:00 2001 From: YN Chen Date: Sat, 23 Jul 2022 05:59:23 +0800 Subject: [PATCH 174/610] wifi: mt76: sdio: fix transmitting packet hangs [ Upstream commit 250b1827205846ff346a76044955cb79d4963f70 ] Fix transmitting packets hangs with continuing to pull the pending packet from mac80211 queues when receiving Tx status notification from the device. Fixes: aac5104bf631 ("mt76: sdio: do not run mt76_txq_schedule directly") Acked-by: Sean Wang Signed-off-by: YN Chen Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c index 783a15635ec5..9e639d0b9c63 100644 --- a/drivers/net/wireless/mediatek/mt76/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/sdio.c @@ -213,7 +213,7 @@ static void mt76s_status_worker(struct mt76_worker *w) } while (nframes > 0); if (resched) - mt76_worker_schedule(&dev->sdio.txrx_worker); + mt76_worker_schedule(&dev->tx_worker); } static void mt76s_tx_status_data(struct work_struct *work) From dea9093f24d61a987e476b434bdde2d994a04957 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 25 Jul 2022 10:26:40 +0200 Subject: [PATCH 175/610] wifi: mt76: mt7615: add mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload [ Upstream commit 765c69d477a44c088e5d19e7758dfa4db418e3ba ] Similar to mt7921 driver, introduce mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload in order to avoid sending mcu commands while the device is in low-power state. Fixes: d4b98c63d7a77 ("mt76: mt7615: add support for rx decapsulation offload") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index 7c52a4d85cea..8f1338dae211 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -1186,12 +1186,16 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw, struct mt7615_dev *dev = mt7615_hw_dev(hw); struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv; + mt7615_mutex_acquire(dev); + if (enabled) set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags); else clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags); mt7615_mcu_set_sta_decap_offload(dev, vif, sta); + + mt7615_mutex_release(dev); } #ifdef CONFIG_PM From 57d4f2f8a67b9d810a2c0768d2c6a8584357a4af Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Thu, 18 Aug 2022 10:44:07 +0800 Subject: [PATCH 176/610] wifi: mt76: mt7915: do not check state before configuring implicit beamform [ Upstream commit d2b5bb6dfab29fe32bedefaade88dcd182c03a00 ] Do not need to check running state before configuring implicit Tx beamform. It is okay to configure implicit Tx beamform in run time. Noted that the existing connected stations will be applied for new configuration only if they reconnected to the interface. Fixes: 6d6dc980e07d ("mt76: mt7915: add implicit Tx beamforming support") Signed-off-by: Howard Hsu Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 64048243e34b..31c1d4bc78dd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -12,9 +12,9 @@ mt7915_implicit_txbf_set(void *data, u64 val) { struct mt7915_dev *dev = data; - if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) - return -EBUSY; - + /* The existing connected stations shall reconnect to apply + * new implicit txbf configuration. + */ dev->ibf = !!val; return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE); From ee7c5e814fb2b5564852482b4312a5714be12ecb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 13 Sep 2022 16:08:13 -0700 Subject: [PATCH 177/610] Bluetooth: RFCOMM: Fix possible deadlock on socket shutdown/release [ Upstream commit 812e92b824c1db16c9519f8624d48a9901a0d38f ] Due to change to switch to use lock_sock inside rfcomm_sk_state_change the socket shutdown/release procedure can cause a deadlock: rfcomm_sock_shutdown(): lock_sock(); __rfcomm_sock_close(): rfcomm_dlc_close(): __rfcomm_dlc_close(): rfcomm_dlc_lock(); rfcomm_sk_state_change(): lock_sock(); To fix this when the call __rfcomm_sock_close is now done without holding the lock_sock since rfcomm_dlc_lock exists to protect the dlc data there is no need to use lock_sock in that code path. Link: https://lore.kernel.org/all/CAD+dNTsbuU4w+Y_P7o+VEN7BYCAbZuwZx2+tH+OTzCdcZF82YA@mail.gmail.com/ Fixes: b7ce436a5d79 ("Bluetooth: switch to lock_sock in RFCOMM") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/rfcomm/sock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 4bf4ea6cbb5e..21e24da4847f 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -902,7 +902,10 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how) lock_sock(sk); if (!sk->sk_shutdown) { sk->sk_shutdown = SHUTDOWN_MASK; + + release_sock(sk); __rfcomm_sock_close(sk); + lock_sock(sk); if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && !(current->flags & PF_EXITING)) From a0f15af17b7dadca634b2e7e7a17f6c4dce1289b Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Thu, 8 Sep 2022 13:55:13 +0000 Subject: [PATCH 178/610] net: fs_enet: Fix wrong check in do_pd_setup [ Upstream commit ec3f06b542a960806a81345042e4eee3f8c5dec4 ] Should check of_iomap return value 'fep->fec.fecp' instead of 'fep->fcc.fccp' Fixes: 976de6a8c304 ("fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.") Signed-off-by: Zheng Yongjun Reviewed-by: Christophe Leroy Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c index 99fe2c210d0f..61f4b6e50d29 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c @@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep) return -EINVAL; fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0); - if (!fep->fcc.fccp) + if (!fep->fec.fecp) return -EINVAL; return 0; From c087c35292ead86ead107a602f17b059f4375731 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 12 Sep 2022 14:38:55 +0100 Subject: [PATCH 179/610] bpf: Ensure correct locking around vulnerable function find_vpid() [ Upstream commit 83c10cc362d91c0d8d25e60779ee52fdbbf3894d ] The documentation for find_vpid() clearly states: "Must be called with the tasklist_lock or rcu_read_lock() held." Presently we do neither for find_vpid() instance in bpf_task_fd_query(). Add proper rcu_read_lock/unlock() to fix the issue. Fixes: 41bdc4b40ed6f ("bpf: introduce bpf subcommand BPF_TASK_FD_QUERY") Signed-off-by: Lee Jones Signed-off-by: Daniel Borkmann Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20220912133855.1218900-1-lee@kernel.org Signed-off-by: Sasha Levin --- kernel/bpf/syscall.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 99ce46f51889..aea9852f1c22 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -4100,7 +4100,9 @@ static int bpf_task_fd_query(const union bpf_attr *attr, if (attr->task_fd_query.flags != 0) return -EINVAL; + rcu_read_lock(); task = get_pid_task(find_vpid(pid), PIDTYPE_PID); + rcu_read_unlock(); if (!task) return -ENOENT; From b8917dce2134739b39bc0a5648b18427f2cad569 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Mon, 29 Aug 2022 23:58:12 +0900 Subject: [PATCH 180/610] Bluetooth: hci_{ldisc,serdev}: check percpu_init_rwsem() failure [ Upstream commit 3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1 ] syzbot is reporting NULL pointer dereference at hci_uart_tty_close() [1], for rcu_sync_enter() is called without rcu_sync_init() due to hci_uart_tty_open() ignoring percpu_init_rwsem() failure. While we are at it, fix that hci_uart_register_device() ignores percpu_init_rwsem() failure and hci_uart_unregister_device() does not call percpu_free_rwsem(). Link: https://syzkaller.appspot.com/bug?extid=576dfca25381fb6fbc5f [1] Reported-by: syzbot Signed-off-by: Tetsuo Handa Fixes: 67d2f8781b9f00d1 ("Bluetooth: hci_ldisc: Allow sleeping while proto locks are held.") Fixes: d73e172816652772 ("Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/hci_ldisc.c | 7 +++++-- drivers/bluetooth/hci_serdev.c | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 5ed2cfa7da1d..2d960a5e3679 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -490,6 +490,11 @@ static int hci_uart_tty_open(struct tty_struct *tty) BT_ERR("Can't allocate control structure"); return -ENFILE; } + if (percpu_init_rwsem(&hu->proto_lock)) { + BT_ERR("Can't allocate semaphore structure"); + kfree(hu); + return -ENOMEM; + } tty->disc_data = hu; hu->tty = tty; @@ -502,8 +507,6 @@ static int hci_uart_tty_open(struct tty_struct *tty) INIT_WORK(&hu->init_ready, hci_uart_init_work); INIT_WORK(&hu->write_work, hci_uart_write_work); - percpu_init_rwsem(&hu->proto_lock); - /* Flush any pending characters in the driver */ tty_driver_flush_buffer(tty); diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c index 4cda890ce647..649d112eea78 100644 --- a/drivers/bluetooth/hci_serdev.c +++ b/drivers/bluetooth/hci_serdev.c @@ -301,11 +301,12 @@ int hci_uart_register_device(struct hci_uart *hu, serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops); + if (percpu_init_rwsem(&hu->proto_lock)) + return -ENOMEM; + err = serdev_device_open(hu->serdev); if (err) - return err; - - percpu_init_rwsem(&hu->proto_lock); + goto err_rwsem; err = p->open(hu); if (err) @@ -378,6 +379,8 @@ err_alloc: p->close(hu); err_open: serdev_device_close(hu->serdev); +err_rwsem: + percpu_free_rwsem(&hu->proto_lock); return err; } EXPORT_SYMBOL_GPL(hci_uart_register_device); @@ -399,5 +402,6 @@ void hci_uart_unregister_device(struct hci_uart *hu) clear_bit(HCI_UART_PROTO_READY, &hu->flags); serdev_device_close(hu->serdev); } + percpu_free_rwsem(&hu->proto_lock); } EXPORT_SYMBOL_GPL(hci_uart_unregister_device); From 9c39ca418ba366caafb73c663eda93a09970681c Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Fri, 16 Sep 2022 11:29:40 +0200 Subject: [PATCH 181/610] netfilter: conntrack: fix the gc rescheduling delay [ Upstream commit 95eabdd207024312876d0ebed90b4c977e050e85 ] Commit 2cfadb761d3d ("netfilter: conntrack: revisit gc autotuning") changed the eviction rescheduling to the use average expiry of scanned entries (within 1-60s) by doing: for (...) { expires = clamp(nf_ct_expires(tmp), ...); next_run += expires; next_run /= 2; } The issue is the above will make the average ('next_run' here) more dependent on the last expiration values than the firsts (for sets > 2). Depending on the expiration values used to compute the average, the result can be quite different than what's expected. To fix this we can do the following: for (...) { expires = clamp(nf_ct_expires(tmp), ...); next_run += (expires - next_run) / ++count; } Fixes: 2cfadb761d3d ("netfilter: conntrack: revisit gc autotuning") Cc: Florian Westphal Signed-off-by: Antoine Tenart Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin --- net/netfilter/nf_conntrack_core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 31399c53dfb1..ee72da164190 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -67,6 +67,7 @@ struct conntrack_gc_work { struct delayed_work dwork; u32 next_bucket; u32 avg_timeout; + u32 count; u32 start_time; bool exiting; bool early_drop; @@ -1439,6 +1440,7 @@ static void gc_worker(struct work_struct *work) unsigned int expired_count = 0; unsigned long next_run; s32 delta_time; + long count; gc_work = container_of(work, struct conntrack_gc_work, dwork.work); @@ -1448,10 +1450,12 @@ static void gc_worker(struct work_struct *work) if (i == 0) { gc_work->avg_timeout = GC_SCAN_INTERVAL_INIT; + gc_work->count = 1; gc_work->start_time = start_time; } next_run = gc_work->avg_timeout; + count = gc_work->count; end_time = start_time + GC_SCAN_MAX_DURATION; @@ -1471,8 +1475,8 @@ static void gc_worker(struct work_struct *work) hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[i], hnnode) { struct nf_conntrack_net *cnet; - unsigned long expires; struct net *net; + long expires; tmp = nf_ct_tuplehash_to_ctrack(h); @@ -1486,6 +1490,7 @@ static void gc_worker(struct work_struct *work) gc_work->next_bucket = i; gc_work->avg_timeout = next_run; + gc_work->count = count; delta_time = nfct_time_stamp - gc_work->start_time; @@ -1501,8 +1506,8 @@ static void gc_worker(struct work_struct *work) } expires = clamp(nf_ct_expires(tmp), GC_SCAN_INTERVAL_MIN, GC_SCAN_INTERVAL_CLAMP); + expires = (expires - (long)next_run) / ++count; next_run += expires; - next_run /= 2u; if (nf_conntrack_max95 == 0 || gc_worker_skip_ct(tmp)) continue; @@ -1540,6 +1545,7 @@ static void gc_worker(struct work_struct *work) delta_time = nfct_time_stamp - end_time; if (delta_time > 0 && i < hashsz) { gc_work->avg_timeout = next_run; + gc_work->count = count; gc_work->next_bucket = i; next_run = 0; goto early_exit; From 5a6827cdc258ea127befa66b736652d0ec584b8f Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Fri, 16 Sep 2022 11:29:41 +0200 Subject: [PATCH 182/610] netfilter: conntrack: revisit the gc initial rescheduling bias [ Upstream commit 2aa192757005f130b2dd3547dda6e462e761199f ] The previous commit changed the way the rescheduling delay is computed which has a side effect: the bias is now represented as much as the other entries in the rescheduling delay which makes the logic to kick in only with very large sets, as the initial interval is very large (INT_MAX). Revisit the GC initial bias to allow more frequent GC for smaller sets while still avoiding wakeups when a machine is mostly idle. We're moving from a large initial value to pretending we have 100 entries expiring at the upper bound. This way only a few entries having a small timeout won't impact much the rescheduling delay and non-idle machines will have enough entries to lower the delay when needed. This also improves readability as the initial bias is now linked to what is computed instead of being an arbitrary large value. Fixes: 2cfadb761d3d ("netfilter: conntrack: revisit gc autotuning") Suggested-by: Florian Westphal Signed-off-by: Antoine Tenart Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin --- net/netfilter/nf_conntrack_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ee72da164190..9da5ee6c50cd 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -86,10 +86,12 @@ static DEFINE_MUTEX(nf_conntrack_mutex); /* clamp timeouts to this value (TCP unacked) */ #define GC_SCAN_INTERVAL_CLAMP (300ul * HZ) -/* large initial bias so that we don't scan often just because we have - * three entries with a 1s timeout. +/* Initial bias pretending we have 100 entries at the upper bound so we don't + * wakeup often just because we have three entries with a 1s timeout while still + * allowing non-idle machines to wakeup more often when needed. */ -#define GC_SCAN_INTERVAL_INIT INT_MAX +#define GC_SCAN_INITIAL_COUNT 100 +#define GC_SCAN_INTERVAL_INIT GC_SCAN_INTERVAL_MAX #define GC_SCAN_MAX_DURATION msecs_to_jiffies(10) #define GC_SCAN_EXPIRED_MAX (64000u / HZ) @@ -1450,7 +1452,7 @@ static void gc_worker(struct work_struct *work) if (i == 0) { gc_work->avg_timeout = GC_SCAN_INTERVAL_INIT; - gc_work->count = 1; + gc_work->count = GC_SCAN_INITIAL_COUNT; gc_work->start_time = start_time; } From 3e2b805a68ab1eef8d09f831160baba988d63965 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Manzano Date: Thu, 22 Sep 2022 10:35:14 +0300 Subject: [PATCH 183/610] wifi: ath11k: fix number of VHT beamformee spatial streams [ Upstream commit 55b5ee3357d7bb98ee578cf9b84a652e7a1bc199 ] The number of spatial streams used when acting as a beamformee in VHT mode are reported by the firmware as 7 (8 sts - 1) both in IPQ6018 and IPQ8074 which respectively have 2 and 4 sts each. So the firmware should report 1 (2 - 1) and 3 (4 - 1). Fix this by checking that the number of VHT beamformee sts reported by the firmware is not greater than the number of receiving antennas - 1. The fix is based on the same approach used in this same function for sanitizing the number of sounding dimensions reported by the firmware. Without this change, acting as a beamformee in VHT mode is not working properly. Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Signed-off-by: Jesus Fernandez Manzano Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220616173947.21901-1-jesus.manzano@galgus.net Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index c7ee373a9d2c..ae6e14fe03c7 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -3684,6 +3684,8 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif) if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) { nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + if (nsts > (ar->num_rx_chains - 1)) + nsts = ar->num_rx_chains - 1; value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET); } @@ -3724,7 +3726,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif) static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) { bool subfer, subfee; - int sound_dim = 0; + int sound_dim = 0, nsts = 0; subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)); subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)); @@ -3734,6 +3736,11 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) subfer = false; } + if (ar->num_rx_chains < 2) { + *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); + subfee = false; + } + /* If SU Beaformer is not set, then disable MU Beamformer Capability */ if (!subfer) *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); @@ -3746,7 +3753,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; *vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; - /* TODO: Need to check invalid STS and Sound_dim values set by FW? */ + nsts = (*vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); + nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + *vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; /* Enable Sounding Dimension Field only if SU BF is enabled */ if (subfer) { @@ -3758,9 +3767,15 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) *vht_cap |= sound_dim; } - /* Use the STS advertised by FW unless SU Beamformee is not supported*/ - if (!subfee) - *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); + /* Enable Beamformee STS Field only if SU BF is enabled */ + if (subfee) { + if (nsts > (ar->num_rx_chains - 1)) + nsts = ar->num_rx_chains - 1; + + nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; + *vht_cap |= nsts; + } } static struct ieee80211_sta_vht_cap From 3c27a13807988fe4ef2f643575ed70a1361e8677 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 21 Sep 2022 20:10:10 -0700 Subject: [PATCH 184/610] x86/microcode/AMD: Track patch allocation size explicitly [ Upstream commit 712f210a457d9c32414df246a72781550bc23ef6 ] In preparation for reducing the use of ksize(), record the actual allocation size for later memcpy(). This avoids copying extra (uninitialized!) bytes into the patch buffer when the requested allocation size isn't exactly the size of a kmalloc bucket. Additionally, fix potential future issues where runtime bounds checking will notice that the buffer was allocated to a smaller value than returned by ksize(). Fixes: 757885e94a22 ("x86, microcode, amd: Early microcode patch loading support for AMD") Suggested-by: Daniel Micay Signed-off-by: Kees Cook Signed-off-by: Borislav Petkov Link: https://lore.kernel.org/lkml/CA+DvKQ+bp7Y7gmaVhacjv9uF6Ar-o4tet872h4Q8RPYPJjcJQA@mail.gmail.com/ Signed-off-by: Sasha Levin --- arch/x86/include/asm/microcode.h | 1 + arch/x86/kernel/cpu/microcode/amd.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index fcbfe94903bb..d130d21f4862 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -9,6 +9,7 @@ struct ucode_patch { struct list_head plist; void *data; /* Intel uses only this one */ + unsigned int size; u32 patch_id; u16 equiv_cpu; }; diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 3d4a48336084..5a16844b99d3 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -782,6 +782,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover, kfree(patch); return -EINVAL; } + patch->size = *patch_size; mc_hdr = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE); proc_id = mc_hdr->processor_rev_id; @@ -863,7 +864,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) return ret; memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); - memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE)); + memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); return ret; } From 6b941151865e0f12a1df43340ba76654988bac57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luciano=20Le=C3=A3o?= Date: Thu, 22 Sep 2022 17:00:54 -0300 Subject: [PATCH 185/610] x86/cpu: Include the header of init_ia32_feat_ctl()'s prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 30ea703a38ef76ca119673cd8bdd05c6e068e2ac ] Include the header containing the prototype of init_ia32_feat_ctl(), solving the following warning: $ make W=1 arch/x86/kernel/cpu/feat_ctl.o arch/x86/kernel/cpu/feat_ctl.c:112:6: warning: no previous prototype for ‘init_ia32_feat_ctl’ [-Wmissing-prototypes] 112 | void init_ia32_feat_ctl(struct cpuinfo_x86 *c) This warning appeared after commit 5d5103595e9e5 ("x86/cpu: Reinitialize IA32_FEAT_CTL MSR on BSP during wakeup") had moved the function init_ia32_feat_ctl()'s prototype from arch/x86/kernel/cpu/cpu.h to arch/x86/include/asm/cpu.h. Note that, before the commit mentioned above, the header include "cpu.h" (arch/x86/kernel/cpu/cpu.h) was added by commit 0e79ad863df43 ("x86/cpu: Fix a -Wmissing-prototypes warning for init_ia32_feat_ctl()") solely to fix init_ia32_feat_ctl()'s missing prototype. So, the header include "cpu.h" is no longer necessary. [ bp: Massage commit message. ] Fixes: 5d5103595e9e5 ("x86/cpu: Reinitialize IA32_FEAT_CTL MSR on BSP during wakeup") Signed-off-by: Luciano Leão Signed-off-by: Borislav Petkov Reviewed-by: Nícolas F. R. A. Prado Link: https://lore.kernel.org/r/20220922200053.1357470-1-lucianorsleao@gmail.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/feat_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c index da696eb4821a..e77032c5f85c 100644 --- a/arch/x86/kernel/cpu/feat_ctl.c +++ b/arch/x86/kernel/cpu/feat_ctl.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include #include -#include "cpu.h" #undef pr_fmt #define pr_fmt(fmt) "x86/cpu: " fmt From daa5239ea49ff336460ead9f86c6c6c4e9557030 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Sat, 24 Sep 2022 20:13:08 +0800 Subject: [PATCH 186/610] spi: dw: Fix PM disable depth imbalance in dw_spi_bt1_probe [ Upstream commit 618d815fc93477b1675878f3c04ff32657cc18b4 ] The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. Fixes:abf00907538e2 ("spi: dw: Add Baikal-T1 SPI Controller glue driver") Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20220924121310.78331-3-zhangqilong3@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw-bt1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c index 5be6b7b80c21..7e3ff54f6616 100644 --- a/drivers/spi/spi-dw-bt1.c +++ b/drivers/spi/spi-dw-bt1.c @@ -293,8 +293,10 @@ static int dw_spi_bt1_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); ret = dw_spi_add_host(&pdev->dev, dws); - if (ret) + if (ret) { + pm_runtime_disable(&pdev->dev); goto err_disable_clk; + } platform_set_drvdata(pdev, dwsbt1); From 44f1dc2e821dd49e62629b6406a53e14b16d7700 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Sat, 24 Sep 2022 20:13:09 +0800 Subject: [PATCH 187/610] spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe [ Upstream commit 29f65f2171c85a9633daa380df14009a365f42f2 ] The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. Fixes:db91841b58f9a ("spi/omap100k: Convert to runtime PM") Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20220924121310.78331-4-zhangqilong3@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-omap-100k.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 20b047172965..061f7394e5b9 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -412,6 +412,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev) return status; err_fck: + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(spi100k->fck); err_ick: clk_disable_unprepare(spi100k->ick); From 9233ab8198d8faea0f1b7117a0d9e405536a2aad Mon Sep 17 00:00:00 2001 From: Liu Jian Date: Wed, 7 Sep 2022 15:13:11 +0800 Subject: [PATCH 188/610] skmsg: Schedule psock work if the cached skb exists on the psock [ Upstream commit bec217197b412d74168c6a42fc0f76d0cc9cad00 ] In sk_psock_backlog function, for ingress direction skb, if no new data packet arrives after the skb is cached, the cached skb does not have a chance to be added to the receive queue of psock. As a result, the cached skb cannot be received by the upper-layer application. Fix this by reschedule the psock work to dispose the cached skb in sk_msg_recvmsg function. Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: Liu Jian Signed-off-by: Daniel Borkmann Acked-by: John Fastabend Link: https://lore.kernel.org/bpf/20220907071311.60534-1-liujian56@huawei.com Signed-off-by: Sasha Levin --- net/core/skmsg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 054073c7cbb9..736d8b035a67 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -435,8 +435,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, if (copied + copy > len) copy = len - copied; copy = copy_page_to_iter(page, sge->offset, copy, iter); - if (!copy) - return copied ? copied : -EFAULT; + if (!copy) { + copied = copied ? copied : -EFAULT; + goto out; + } copied += copy; if (likely(!peek)) { @@ -456,7 +458,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, * didn't copy the entire length lets just break. */ if (copy != sge->length) - return copied; + goto out; sk_msg_iter_var_next(i); } @@ -478,7 +480,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, } msg_rx = sk_psock_peek_msg(psock); } - +out: + if (psock->work_state.skb && copied > 0) + schedule_work(&psock->work); return copied; } EXPORT_SYMBOL_GPL(sk_msg_recvmsg); From 1331d3e1f9b5060e159fba8c6fb3285ee5aa2857 Mon Sep 17 00:00:00 2001 From: Asmaa Mnebhi Date: Mon, 26 Sep 2022 15:45:04 -0400 Subject: [PATCH 189/610] i2c: mlxbf: support lock mechanism [ Upstream commit 86067ccfa1424a26491542d6f6d7546d40b61a10 ] Linux is not the only entity using the BlueField I2C busses so support a lock mechanism provided by hardware to avoid issues when multiple entities are trying to access the same bus. The lock is acquired whenever written explicitely or the lock register is read. So make sure it is always released at the end of a successful or failed transaction. Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) Reviewed-by: Khalil Blaiech Signed-off-by: Asmaa Mnebhi Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-mlxbf.c | 44 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index ad5efd7497d1..0e840eba4fd6 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c @@ -306,6 +306,7 @@ static u64 mlxbf_i2c_corepll_frequency; * exact. */ #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000) /* 300ms */ +#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */ /* Encapsulates timing parameters. */ struct mlxbf_i2c_timings { @@ -514,6 +515,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv) return false; } +/* + * wait for the lock to be released before acquiring it. + */ +static bool mlxbf_i2c_smbus_master_lock(struct mlxbf_i2c_priv *priv) +{ + if (mlxbf_smbus_poll(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW, + MLXBF_I2C_MASTER_LOCK_BIT, true, + MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT)) + return true; + + return false; +} + +static void mlxbf_i2c_smbus_master_unlock(struct mlxbf_i2c_priv *priv) +{ + /* Clear the gw to clear the lock */ + writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW); +} + static bool mlxbf_i2c_smbus_transaction_success(u32 master_status, u32 cause_status) { @@ -705,10 +725,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, slave = request->slave & GENMASK(6, 0); addr = slave << 1; - /* First of all, check whether the HW is idle. */ - if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) + /* + * Try to acquire the smbus gw lock before any reads of the GW register since + * a read sets the lock. + */ + if (WARN_ON(!mlxbf_i2c_smbus_master_lock(priv))) return -EBUSY; + /* Check whether the HW is idle */ + if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) { + ret = -EBUSY; + goto out_unlock; + } + /* Set first byte. */ data_desc[data_idx++] = addr; @@ -732,8 +761,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, write_en = 1; write_len += operation->length; if (data_idx + operation->length > - MLXBF_I2C_MASTER_DATA_DESC_SIZE) - return -ENOBUFS; + MLXBF_I2C_MASTER_DATA_DESC_SIZE) { + ret = -ENOBUFS; + goto out_unlock; + } memcpy(data_desc + data_idx, operation->buffer, operation->length); data_idx += operation->length; @@ -765,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en, pec_en, 0); if (ret) - return ret; + goto out_unlock; } if (read_en) { @@ -792,6 +823,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM); } +out_unlock: + mlxbf_i2c_smbus_master_unlock(priv); + return ret; } From 397e880acf441dd15e4bdbb14b4c36d3f358afab Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 26 Sep 2022 15:44:42 -0700 Subject: [PATCH 190/610] Bluetooth: hci_core: Fix not handling link timeouts propertly [ Upstream commit 116523c8fac05d1d26f748fee7919a4ec5df67ea ] Change that introduced the use of __check_timeout did not account for link types properly, it always assumes ACL_LINK is used thus causing hdev->acl_last_tx to be used even in case of LE_LINK and then again uses ACL_LINK with hci_link_tx_to. To fix this __check_timeout now takes the link type as parameter and then procedure to use the right last_tx based on the link type and pass it to hci_link_tx_to. Fixes: 1b1d29e51499 ("Bluetooth: Make use of __check_timeout on hci_sched_le") Signed-off-by: Luiz Augusto von Dentz Tested-by: David Beinder Signed-off-by: Sasha Levin --- net/bluetooth/hci_core.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cdca53732304..396696241d17 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4673,15 +4673,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); } -static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) +static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type) { - if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { - /* ACL tx timeout must be longer than maximum - * link supervision timeout (40.9 seconds) */ - if (!cnt && time_after(jiffies, hdev->acl_last_tx + - HCI_ACL_TX_TIMEOUT)) - hci_link_tx_to(hdev, ACL_LINK); + unsigned long last_tx; + + if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) + return; + + switch (type) { + case LE_LINK: + last_tx = hdev->le_last_tx; + break; + default: + last_tx = hdev->acl_last_tx; + break; } + + /* tx timeout must be longer than maximum link supervision timeout + * (40.9 seconds) + */ + if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT)) + hci_link_tx_to(hdev, type); } /* Schedule SCO */ @@ -4739,7 +4751,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) struct sk_buff *skb; int quote; - __check_timeout(hdev, cnt); + __check_timeout(hdev, cnt, ACL_LINK); while (hdev->acl_cnt && (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { @@ -4782,8 +4794,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) int quote; u8 type; - __check_timeout(hdev, cnt); - BT_DBG("%s", hdev->name); if (hdev->dev_type == HCI_AMP) @@ -4791,6 +4801,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) else type = ACL_LINK; + __check_timeout(hdev, cnt, type); + while (hdev->block_cnt > 0 && (chan = hci_chan_sent(hdev, type, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; @@ -4864,7 +4876,7 @@ static void hci_sched_le(struct hci_dev *hdev) cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; - __check_timeout(hdev, cnt); + __check_timeout(hdev, cnt, LE_LINK); tmp = cnt; while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { From 7d98b26684cb2390729525b341ea099f0badbe18 Mon Sep 17 00:00:00 2001 From: Liu Jian Date: Sat, 24 Sep 2022 16:01:57 +0800 Subject: [PATCH 191/610] xfrm: Reinject transport-mode packets through workqueue [ Upstream commit 4f4920669d21e1060b7243e5118dc3b71ced1276 ] The following warning is displayed when the tcp6-multi-diffip11 stress test case of the LTP test suite is tested: watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [ns-tcpserver:48198] CPU: 0 PID: 48198 Comm: ns-tcpserver Kdump: loaded Not tainted 6.0.0-rc6+ #39 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : des3_ede_encrypt+0x27c/0x460 [libdes] lr : 0x3f sp : ffff80000ceaa1b0 x29: ffff80000ceaa1b0 x28: ffff0000df056100 x27: ffff0000e51e5280 x26: ffff80004df75030 x25: ffff0000e51e4600 x24: 000000000000003b x23: 0000000000802080 x22: 000000000000003d x21: 0000000000000038 x20: 0000000080000020 x19: 000000000000000a x18: 0000000000000033 x17: ffff0000e51e4780 x16: ffff80004e2d1448 x15: ffff80004e2d1248 x14: ffff0000e51e4680 x13: ffff80004e2d1348 x12: ffff80004e2d1548 x11: ffff80004e2d1848 x10: ffff80004e2d1648 x9 : ffff80004e2d1748 x8 : ffff80004e2d1948 x7 : 000000000bcaf83d x6 : 000000000000001b x5 : ffff80004e2d1048 x4 : 00000000761bf3bf x3 : 000000007f1dd0a3 x2 : ffff0000e51e4780 x1 : ffff0000e3b9a2f8 x0 : 00000000db44e872 Call trace: des3_ede_encrypt+0x27c/0x460 [libdes] crypto_des3_ede_encrypt+0x1c/0x30 [des_generic] crypto_cbc_encrypt+0x148/0x190 crypto_skcipher_encrypt+0x2c/0x40 crypto_authenc_encrypt+0xc8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp6_output_tail+0x1c8/0x5d0 [esp6] esp6_output+0x120/0x278 [esp6] xfrm_output_one+0x458/0x4ec xfrm_output_resume+0x6c/0x1f0 xfrm_output+0xac/0x4ac __xfrm6_output+0x130/0x270 xfrm6_output+0x60/0xec ip6_xmit+0x2ec/0x5bc inet6_csk_xmit+0xbc/0x10c __tcp_transmit_skb+0x460/0x8c0 tcp_write_xmit+0x348/0x890 __tcp_push_pending_frames+0x44/0x110 tcp_rcv_established+0x3c8/0x720 tcp_v6_do_rcv+0xdc/0x4a0 tcp_v6_rcv+0xc24/0xcb0 ip6_protocol_deliver_rcu+0xf0/0x574 ip6_input_finish+0x48/0x7c ip6_input+0x48/0xc0 ip6_rcv_finish+0x80/0x9c xfrm_trans_reinject+0xb0/0xf4 tasklet_action_common.constprop.0+0xf8/0x134 tasklet_action+0x30/0x3c __do_softirq+0x128/0x368 do_softirq+0xb4/0xc0 __local_bh_enable_ip+0xb0/0xb4 put_cpu_fpsimd_context+0x40/0x70 kernel_neon_end+0x20/0x40 sha1_base_do_update.constprop.0.isra.0+0x11c/0x140 [sha1_ce] sha1_ce_finup+0x94/0x110 [sha1_ce] crypto_shash_finup+0x34/0xc0 hmac_finup+0x48/0xe0 crypto_shash_finup+0x34/0xc0 shash_digest_unaligned+0x74/0x90 crypto_shash_digest+0x4c/0x9c shash_ahash_digest+0xc8/0xf0 shash_async_digest+0x28/0x34 crypto_ahash_digest+0x48/0xcc crypto_authenc_genicv+0x88/0xcc [authenc] crypto_authenc_encrypt+0xd8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp6_output_tail+0x1c8/0x5d0 [esp6] esp6_output+0x120/0x278 [esp6] xfrm_output_one+0x458/0x4ec xfrm_output_resume+0x6c/0x1f0 xfrm_output+0xac/0x4ac __xfrm6_output+0x130/0x270 xfrm6_output+0x60/0xec ip6_xmit+0x2ec/0x5bc inet6_csk_xmit+0xbc/0x10c __tcp_transmit_skb+0x460/0x8c0 tcp_write_xmit+0x348/0x890 __tcp_push_pending_frames+0x44/0x110 tcp_push+0xb4/0x14c tcp_sendmsg_locked+0x71c/0xb64 tcp_sendmsg+0x40/0x6c inet6_sendmsg+0x4c/0x80 sock_sendmsg+0x5c/0x6c __sys_sendto+0x128/0x15c __arm64_sys_sendto+0x30/0x40 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x170/0x194 do_el0_svc+0x38/0x4c el0_svc+0x28/0xe0 el0t_64_sync_handler+0xbc/0x13c el0t_64_sync+0x180/0x184 Get softirq info by bcc tool: ./softirqs -NT 10 Tracing soft irq event time... Hit Ctrl-C to end. 15:34:34 SOFTIRQ TOTAL_nsecs block 158990 timer 20030920 sched 46577080 net_rx 676746820 tasklet 9906067650 15:34:45 SOFTIRQ TOTAL_nsecs block 86100 sched 38849790 net_rx 676532470 timer 1163848790 tasklet 9409019620 15:34:55 SOFTIRQ TOTAL_nsecs sched 58078450 net_rx 475156720 timer 533832410 tasklet 9431333300 The tasklet software interrupt takes too much time. Therefore, the xfrm_trans_reinject executor is changed from tasklet to workqueue. Add add spin lock to protect the queue. This reduces the processing flow of the tcp_sendmsg function in this scenario. Fixes: acf568ee859f0 ("xfrm: Reinject transport-mode packets through tasklet") Signed-off-by: Liu Jian Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/xfrm/xfrm_input.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 5f34bc378fdc..3d8668d62e63 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -24,7 +24,8 @@ #include "xfrm_inout.h" struct xfrm_trans_tasklet { - struct tasklet_struct tasklet; + struct work_struct work; + spinlock_t queue_lock; struct sk_buff_head queue; }; @@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) } EXPORT_SYMBOL(xfrm_input_resume); -static void xfrm_trans_reinject(struct tasklet_struct *t) +static void xfrm_trans_reinject(struct work_struct *work) { - struct xfrm_trans_tasklet *trans = from_tasklet(trans, t, tasklet); + struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work); struct sk_buff_head queue; struct sk_buff *skb; __skb_queue_head_init(&queue); + spin_lock_bh(&trans->queue_lock); skb_queue_splice_init(&trans->queue, &queue); + spin_unlock_bh(&trans->queue_lock); + local_bh_disable(); while ((skb = __skb_dequeue(&queue))) XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net, NULL, skb); + local_bh_enable(); } int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb, @@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb, XFRM_TRANS_SKB_CB(skb)->finish = finish; XFRM_TRANS_SKB_CB(skb)->net = net; + spin_lock_bh(&trans->queue_lock); __skb_queue_tail(&trans->queue, skb); - tasklet_schedule(&trans->tasklet); + spin_unlock_bh(&trans->queue_lock); + schedule_work(&trans->work); return 0; } EXPORT_SYMBOL(xfrm_trans_queue_net); @@ -817,7 +824,8 @@ void __init xfrm_input_init(void) struct xfrm_trans_tasklet *trans; trans = &per_cpu(xfrm_trans_tasklet, i); + spin_lock_init(&trans->queue_lock); __skb_queue_head_init(&trans->queue); - tasklet_setup(&trans->tasklet, xfrm_trans_reinject); + INIT_WORK(&trans->work, xfrm_trans_reinject); } } From 1454a26cb1ab4388dc828a5a6a9abd594372ef40 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 21 Sep 2022 13:07:31 +0200 Subject: [PATCH 192/610] netfilter: nft_fib: Fix for rpath check with VRF devices [ Upstream commit 2a8a7c0eaa8747c16aa4a48d573aa920d5c00a5c ] Analogous to commit b575b24b8eee3 ("netfilter: Fix rpfilter dropping vrf packets by mistake") but for nftables fib expression: Add special treatment of VRF devices so that typical reverse path filtering via 'fib saddr . iif oif' expression works as expected. Fixes: f6d0cbcf09c50 ("netfilter: nf_tables: add fib expression") Signed-off-by: Phil Sutter Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin --- net/ipv4/netfilter/nft_fib_ipv4.c | 3 +++ net/ipv6/netfilter/nft_fib_ipv6.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c index 03df986217b7..9e6f0f1275e2 100644 --- a/net/ipv4/netfilter/nft_fib_ipv4.c +++ b/net/ipv4/netfilter/nft_fib_ipv4.c @@ -83,6 +83,9 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, else oif = NULL; + if (priv->flags & NFTA_FIB_F_IIF) + fl4.flowi4_oif = l3mdev_master_ifindex_rcu(oif); + if (nft_hook(pkt) == NF_INET_PRE_ROUTING && nft_fib_is_loopback(pkt->skb, nft_in(pkt))) { nft_fib_store_result(dest, priv, nft_in(pkt)); diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c index 92f3235fa287..602743f6dcee 100644 --- a/net/ipv6/netfilter/nft_fib_ipv6.c +++ b/net/ipv6/netfilter/nft_fib_ipv6.c @@ -37,6 +37,9 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv, if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) { lookup_flags |= RT6_LOOKUP_F_IFACE; fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev); + } else if ((priv->flags & NFTA_FIB_F_IIF) && + (netif_is_l3_master(dev) || netif_is_l3_slave(dev))) { + fl6->flowi6_oif = dev->ifindex; } if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST) @@ -193,7 +196,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL)) goto put_rt_err; - if (oif && oif != rt->rt6i_idev->dev) + if (oif && oif != rt->rt6i_idev->dev && + l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) != oif->ifindex) goto put_rt_err; nft_fib_store_result(dest, priv, rt->rt6i_idev->dev); From 432eecffcf1ba5b1a379dbb651d3e820e4ddb928 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Tue, 27 Sep 2022 13:21:17 +0200 Subject: [PATCH 193/610] spi: s3c64xx: Fix large transfers with DMA [ Upstream commit 1224e29572f655facfcd850cf0f0a4784f36a903 ] The COUNT_VALUE in the PACKET_CNT register is 16-bit so the maximum value is 65535. Asking the driver to transfer a larger size currently leads to the DMA transfer timing out. Implement ->max_transfer_size() and have the core split the transfer as needed. Fixes: 230d42d422e7 ("spi: Add s3c64xx SPI Controller driver") Signed-off-by: Vincent Whitchurch Link: https://lore.kernel.org/r/20220927112117.77599-5-vincent.whitchurch@axis.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-s3c64xx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 8755cd85e83c..90c70d53e85e 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -85,6 +85,7 @@ #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) #define S3C64XX_SPI_PACKET_CNT_EN (1<<16) +#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0) #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) @@ -661,6 +662,13 @@ static int s3c64xx_spi_prepare_message(struct spi_master *master, return 0; } +static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi) +{ + struct spi_controller *ctlr = spi->controller; + + return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX; +} + static int s3c64xx_spi_transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) @@ -1130,6 +1138,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; master->prepare_message = s3c64xx_spi_prepare_message; master->transfer_one = s3c64xx_spi_transfer_one; + master->max_transfer_size = s3c64xx_spi_max_transfer_size; master->num_chipselect = sci->num_cs; master->dma_alignment = 8; master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | From 5dbdd690ed83fa719498f23f6586db2ef22f0b66 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 18 Sep 2022 15:42:25 +0300 Subject: [PATCH 194/610] wifi: rtl8xxxu: Fix AIFS written to REG_EDCA_*_PARAM [ Upstream commit 5574d3290449916397f3092dcd2bac92415498e1 ] ieee80211_tx_queue_params.aifs is not supposed to be written directly to the REG_EDCA_*_PARAM registers. Instead process it like the vendor drivers do. It's kinda hacky but it works. This change boosts the download speed and makes it more stable. Tested with RTL8188FU but all the other supported chips should also benefit. Fixes: 26f1fad29ad9 ("New driver: rtl8xxxu (mac80211)") Signed-off-by: Bitterblue Smith Acked-by: Jes Sorensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/038cc03f-3567-77ba-a7bd-c4930e3b2fad@gmail.com Signed-off-by: Sasha Levin --- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index fb2a5fc1a4e6..e74c885a04e5 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -4507,6 +4507,53 @@ rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta) return network_type; } +static void rtl8xxxu_set_aifs(struct rtl8xxxu_priv *priv, u8 slot_time) +{ + u32 reg_edca_param[IEEE80211_NUM_ACS] = { + [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM, + [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM, + [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM, + [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM, + }; + u32 val32; + u16 wireless_mode = 0; + u8 aifs, aifsn, sifs; + int i; + + if (priv->vif) { + struct ieee80211_sta *sta; + + rcu_read_lock(); + sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid); + if (sta) + wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta); + rcu_read_unlock(); + } + + if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ || + (wireless_mode & WIRELESS_MODE_N_24G)) + sifs = 16; + else + sifs = 10; + + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + val32 = rtl8xxxu_read32(priv, reg_edca_param[i]); + + /* It was set in conf_tx. */ + aifsn = val32 & 0xff; + + /* aifsn not set yet or already fixed */ + if (aifsn < 2 || aifsn > 15) + continue; + + aifs = aifsn * slot_time + sifs; + + val32 &= ~0xff; + val32 |= aifs; + rtl8xxxu_write32(priv, reg_edca_param[i], val32); + } +} + static void rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changed) @@ -4592,6 +4639,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, else val8 = 20; rtl8xxxu_write8(priv, REG_SLOT, val8); + + rtl8xxxu_set_aifs(priv, val8); } if (changed & BSS_CHANGED_BSSID) { From e28a4e7f0296824c61a81e7fd54ab48bad3e75ad Mon Sep 17 00:00:00 2001 From: Junichi Uekawa Date: Wed, 28 Sep 2022 15:45:38 +0900 Subject: [PATCH 195/610] vhost/vsock: Use kvmalloc/kvfree for larger packets. [ Upstream commit 0e3f72931fc47bb81686020cc643cde5d9cd0bb8 ] When copying a large file over sftp over vsock, data size is usually 32kB, and kmalloc seems to fail to try to allocate 32 32kB regions. vhost-5837: page allocation failure: order:4, mode:0x24040c0 Call Trace: [] dump_stack+0x97/0xdb [] warn_alloc_failed+0x10f/0x138 [] ? __alloc_pages_direct_compact+0x38/0xc8 [] __alloc_pages_nodemask+0x84c/0x90d [] alloc_kmem_pages+0x17/0x19 [] kmalloc_order_trace+0x2b/0xdb [] __kmalloc+0x177/0x1f7 [] ? copy_from_iter+0x8d/0x31d [] vhost_vsock_handle_tx_kick+0x1fa/0x301 [vhost_vsock] [] vhost_worker+0xf7/0x157 [vhost] [] kthread+0xfd/0x105 [] ? vhost_dev_set_owner+0x22e/0x22e [vhost] [] ? flush_kthread_worker+0xf3/0xf3 [] ret_from_fork+0x4e/0x80 [] ? flush_kthread_worker+0xf3/0xf3 Work around by doing kvmalloc instead. Fixes: 433fc58e6bf2 ("VSOCK: Introduce vhost_vsock.ko") Signed-off-by: Junichi Uekawa Reviewed-by: Stefano Garzarella Acked-by: Michael S. Tsirkin Link: https://lore.kernel.org/r/20220928064538.667678-1-uekawa@chromium.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/vhost/vsock.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index dcb1585819a1..97bfe499222b 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -393,7 +393,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq, return NULL; } - pkt->buf = kmalloc(pkt->len, GFP_KERNEL); + pkt->buf = kvmalloc(pkt->len, GFP_KERNEL); if (!pkt->buf) { kfree(pkt); return NULL; diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index ec2c2afbf0d0..3a12aee33e92 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -1342,7 +1342,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt); void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt) { - kfree(pkt->buf); + kvfree(pkt->buf); kfree(pkt); } EXPORT_SYMBOL_GPL(virtio_transport_free_pkt); From 6f1991a940b90753b34570f093a21dba366e8cc0 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 28 Sep 2022 11:12:36 -0700 Subject: [PATCH 196/610] eth: alx: take rtnl_lock on resume [ Upstream commit 6ad1c94e1e7e374d88f0cfd77936dddb8339aaba ] Zbynek reports that alx trips an rtnl assertion on resume: RTNL: assertion failed at net/core/dev.c (2891) RIP: 0010:netif_set_real_num_tx_queues+0x1ac/0x1c0 Call Trace: __alx_open+0x230/0x570 [alx] alx_resume+0x54/0x80 [alx] ? pci_legacy_resume+0x80/0x80 dpm_run_callback+0x4a/0x150 device_resume+0x8b/0x190 async_resume+0x19/0x30 async_run_entry_fn+0x30/0x130 process_one_work+0x1e5/0x3b0 indeed the driver does not hold rtnl_lock during its internal close and re-open functions during suspend/resume. Note that this is not a huge bug as the driver implements its own locking, and does not implement changing the number of queues, but we need to silence the splat. Fixes: 4a5fe57e7751 ("alx: use fine-grained locking instead of RTNL") Reported-and-tested-by: Zbynek Michl Reviewed-by: Niels Dossche Link: https://lore.kernel.org/r/20220928181236.1053043-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/atheros/alx/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 98a8698a3201..2ac5253ff89a 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -1912,11 +1912,14 @@ static int alx_suspend(struct device *dev) if (!netif_running(alx->dev)) return 0; + + rtnl_lock(); netif_device_detach(alx->dev); mutex_lock(&alx->mtx); __alx_stop(alx); mutex_unlock(&alx->mtx); + rtnl_unlock(); return 0; } @@ -1927,6 +1930,7 @@ static int alx_resume(struct device *dev) struct alx_hw *hw = &alx->hw; int err; + rtnl_lock(); mutex_lock(&alx->mtx); alx_reset_phy(hw); @@ -1943,6 +1947,7 @@ static int alx_resume(struct device *dev) unlock: mutex_unlock(&alx->mtx); + rtnl_unlock(); return err; } From 7bfa18b05f381162c9d38192bbf0179f1142dd38 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Wed, 28 Sep 2022 21:39:38 +0800 Subject: [PATCH 197/610] mISDN: fix use-after-free bugs in l1oip timer handlers [ Upstream commit 2568a7e0832ee30b0a351016d03062ab4e0e0a3f ] The l1oip_cleanup() traverses the l1oip_ilist and calls release_card() to cleanup module and stack. However, release_card() calls del_timer() to delete the timers such as keep_tl and timeout_tl. If the timer handler is running, the del_timer() will not stop it and result in UAF bugs. One of the processes is shown below: (cleanup routine) | (timer handler) release_card() | l1oip_timeout() ... | del_timer() | ... ... | kfree(hc) //FREE | | hc->timeout_on = 0 //USE Fix by calling del_timer_sync() in release_card(), which makes sure the timer handlers have finished before the resources, such as l1oip and so on, have been deallocated. What's more, the hc->workq and hc->socket_thread can kick those timers right back in. We add a bool flag to show if card is released. Then, check this flag in hc->workq and hc->socket_thread. Fixes: 3712b42d4b1b ("Add layer1 over IP support") Signed-off-by: Duoming Zhou Reviewed-by: Leon Romanovsky Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/isdn/mISDN/l1oip.h | 1 + drivers/isdn/mISDN/l1oip_core.c | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h index 7ea10db20e3a..48133d022812 100644 --- a/drivers/isdn/mISDN/l1oip.h +++ b/drivers/isdn/mISDN/l1oip.h @@ -59,6 +59,7 @@ struct l1oip { int bundle; /* bundle channels in one frm */ int codec; /* codec to use for transmis. */ int limit; /* limit number of bchannels */ + bool shutdown; /* if card is released */ /* timer */ struct timer_list keep_tl; diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 2c40412466e6..a77195e378b7 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame; /* restart timer */ - if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) + if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown) mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ); else hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; @@ -601,7 +601,9 @@ multiframe: goto multiframe; /* restart timer */ - if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) { + if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || + !hc->timeout_on) && + !hc->shutdown) { hc->timeout_on = 1; mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ); } else /* only adjust timer */ @@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc) { int ch; - if (timer_pending(&hc->keep_tl)) - del_timer(&hc->keep_tl); + hc->shutdown = true; - if (timer_pending(&hc->timeout_tl)) - del_timer(&hc->timeout_tl); + del_timer_sync(&hc->keep_tl); + del_timer_sync(&hc->timeout_tl); cancel_work_sync(&hc->workq); From 19d636b663e0e92951bba5fced929ca7fd25c552 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Wed, 28 Sep 2022 14:10:13 -0400 Subject: [PATCH 198/610] sctp: handle the error returned from sctp_auth_asoc_init_active_key [ Upstream commit 022152aaebe116a25c39818a07e175a8cd3c1e11 ] When it returns an error from sctp_auth_asoc_init_active_key(), the active_key is actually not updated. The old sh_key will be freeed while it's still used as active key in asoc. Then an use-after-free will be triggered when sending patckets, as found by syzbot: sctp_auth_shkey_hold+0x22/0xa0 net/sctp/auth.c:112 sctp_set_owner_w net/sctp/socket.c:132 [inline] sctp_sendmsg_to_asoc+0xbd5/0x1a20 net/sctp/socket.c:1863 sctp_sendmsg+0x1053/0x1d50 net/sctp/socket.c:2025 inet_sendmsg+0x99/0xe0 net/ipv4/af_inet.c:819 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734 This patch is to fix it by not replacing the sh_key when it returns errors from sctp_auth_asoc_init_active_key() in sctp_auth_set_key(). For sctp_auth_set_active_key(), old active_key_id will be set back to asoc->active_key_id when the same thing happens. Fixes: 58acd1009226 ("sctp: update active_key for asoc when old key is being replaced") Reported-by: syzbot+a236dd8e9622ed8954a3@syzkaller.appspotmail.com Signed-off-by: Xin Long Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sctp/auth.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/net/sctp/auth.c b/net/sctp/auth.c index db6b7373d16c..34964145514e 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -863,12 +863,17 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, } list_del_init(&shkey->key_list); - sctp_auth_shkey_release(shkey); list_add(&cur_key->key_list, sh_keys); - if (asoc && asoc->active_key_id == auth_key->sca_keynumber) - sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL); + if (asoc && asoc->active_key_id == auth_key->sca_keynumber && + sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) { + list_del_init(&cur_key->key_list); + sctp_auth_shkey_release(cur_key); + list_add(&shkey->key_list, sh_keys); + return -ENOMEM; + } + sctp_auth_shkey_release(shkey); return 0; } @@ -902,8 +907,13 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep, return -EINVAL; if (asoc) { + __u16 active_key_id = asoc->active_key_id; + asoc->active_key_id = key_id; - sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL); + if (sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) { + asoc->active_key_id = active_key_id; + return -ENOMEM; + } } else ep->active_key_id = key_id; From 49d429760df7fd662dd24d54c7325d5b2fd78697 Mon Sep 17 00:00:00 2001 From: Neal Cardwell Date: Wed, 28 Sep 2022 16:03:31 -0400 Subject: [PATCH 199/610] tcp: fix tcp_cwnd_validate() to not forget is_cwnd_limited [ Upstream commit f4ce91ce12a7c6ead19b128ffa8cff6e3ded2a14 ] This commit fixes a bug in the tracking of max_packets_out and is_cwnd_limited. This bug can cause the connection to fail to remember that is_cwnd_limited is true, causing the connection to fail to grow cwnd when it should, causing throughput to be lower than it should be. The following event sequence is an example that triggers the bug: (a) The connection is cwnd_limited, but packets_out is not at its peak due to TSO deferral deciding not to send another skb yet. In such cases the connection can advance max_packets_seq and set tp->is_cwnd_limited to true and max_packets_out to a small number. (b) Then later in the round trip the connection is pacing-limited (not cwnd-limited), and packets_out is larger. In such cases the connection would raise max_packets_out to a bigger number but (unexpectedly) flip tp->is_cwnd_limited from true to false. This commit fixes that bug. One straightforward fix would be to separately track (a) the next window after max_packets_out reaches a maximum, and (b) the next window after tp->is_cwnd_limited is set to true. But this would require consuming an extra u32 sequence number. Instead, to save space we track only the most important information. Specifically, we track the strongest available signal of the degree to which the cwnd is fully utilized: (1) If the connection is cwnd-limited then we remember that fact for the current window. (2) If the connection not cwnd-limited then we track the maximum number of outstanding packets in the current window. In particular, note that the new logic cannot trigger the buggy (a)/(b) sequence above because with the new logic a condition where tp->packets_out > tp->max_packets_out can only trigger an update of tp->is_cwnd_limited if tp->is_cwnd_limited is false. This first showed up in a testing of a BBRv2 dev branch, but this buggy behavior highlighted a general issue with the tcp_cwnd_validate() logic that can cause cwnd to fail to increase at the proper rate for any TCP congestion control, including Reno or CUBIC. Fixes: ca8a22634381 ("tcp: make cwnd-limited checks measurement-based, and gentler") Signed-off-by: Neal Cardwell Signed-off-by: Kevin(Yudong) Yang Signed-off-by: Yuchung Cheng Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/linux/tcp.h | 2 +- include/net/tcp.h | 5 ++++- net/ipv4/tcp.c | 2 ++ net/ipv4/tcp_output.c | 19 ++++++++++++------- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 48d8a363319e..a7ebadf83c68 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -265,7 +265,7 @@ struct tcp_sock { u32 packets_out; /* Packets which are "in flight" */ u32 retrans_out; /* Retransmitted packets out */ u32 max_packets_out; /* max packets_out in last window */ - u32 max_packets_seq; /* right edge of max_packets_out flight */ + u32 cwnd_usage_seq; /* right edge of cwnd usage tracking flight */ u16 urg_data; /* Saved octet of OOB data and control flags */ u8 ecn_flags; /* ECN status bits. */ diff --git a/include/net/tcp.h b/include/net/tcp.h index d3646645cb9e..d2de3b7788a9 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1281,11 +1281,14 @@ static inline bool tcp_is_cwnd_limited(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); + if (tp->is_cwnd_limited) + return true; + /* If in slow start, ensure cwnd grows to twice what was ACKed. */ if (tcp_in_slow_start(tp)) return tcp_snd_cwnd(tp) < 2 * tp->max_packets_out; - return tp->is_cwnd_limited; + return false; } /* BBR congestion control needs pacing. diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4f6b897ccf23..b604c7664350 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3025,6 +3025,8 @@ int tcp_disconnect(struct sock *sk, int flags) tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tcp_snd_cwnd_set(tp, TCP_INIT_CWND); tp->snd_cwnd_cnt = 0; + tp->is_cwnd_limited = 0; + tp->max_packets_out = 0; tp->window_clamp = 0; tp->delivered = 0; tp->delivered_ce = 0; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ed2e1836c0c0..33ba1268a111 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1878,15 +1878,20 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; struct tcp_sock *tp = tcp_sk(sk); - /* Track the maximum number of outstanding packets in each - * window, and remember whether we were cwnd-limited then. + /* Track the strongest available signal of the degree to which the cwnd + * is fully utilized. If cwnd-limited then remember that fact for the + * current window. If not cwnd-limited then track the maximum number of + * outstanding packets in the current window. (If cwnd-limited then we + * chose to not update tp->max_packets_out to avoid an extra else + * clause with no functional impact.) */ - if (!before(tp->snd_una, tp->max_packets_seq) || - tp->packets_out > tp->max_packets_out || - is_cwnd_limited) { - tp->max_packets_out = tp->packets_out; - tp->max_packets_seq = tp->snd_nxt; + if (!before(tp->snd_una, tp->cwnd_usage_seq) || + is_cwnd_limited || + (!tp->is_cwnd_limited && + tp->packets_out > tp->max_packets_out)) { tp->is_cwnd_limited = is_cwnd_limited; + tp->max_packets_out = tp->packets_out; + tp->cwnd_usage_seq = tp->snd_nxt; } if (tcp_is_cwnd_limited(sk)) { From c91b922b4170caef934c7e79c4a0f4faad184baf Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 30 Sep 2022 13:34:08 +0200 Subject: [PATCH 200/610] spi: Ensure that sg_table won't be used after being freed [ Upstream commit 8e9204cddcc3fea9affcfa411715ba4f66e97587 ] SPI code checks for non-zero sgt->orig_nents to determine if the buffer has been DMA-mapped. Ensure that sg_table is really zeroed after free to avoid potential NULL pointer dereference if the given SPI xfer object is reused again without being DMA-mapped. Fixes: 0c17ba73c08f ("spi: Fix cache corruption due to DMA/PIO overlap") Signed-off-by: Marek Szyprowski Link: https://lore.kernel.org/r/20220930113408.19720-1-m.szyprowski@samsung.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 556d65af5e23..06dd1be54925 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1007,6 +1007,8 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev, if (sgt->orig_nents) { dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir); sg_free_table(sgt); + sgt->orig_nents = 0; + sgt->nents = 0; } } From f828333ca90f66adb0289d617b96546ae695b463 Mon Sep 17 00:00:00 2001 From: Oleksandr Shamray Date: Thu, 29 Sep 2022 15:16:42 +0300 Subject: [PATCH 201/610] hwmon: (pmbus/mp2888) Fix sensors readouts for MPS Multi-phase mp2888 controller [ Upstream commit 525dd5aed67a2f4f7278116fb92a24e6a53e2622 ] Fix scale factors for reading MPS Multi-phase mp2888 controller. Fixed sensors: - PIN/POUT: based on vendor documentation, set bscale factor 0.5W/LSB - IOUT: based on vendor documentation, set scale factor 0.25 A/LSB Fixes: e4db7719d037 ("hwmon: (pmbus) Add support for MPS Multi-phase mp2888 controller") Signed-off-by: Oleksandr Shamray Reviewed-by: Vadim Pasternak Link: https://lore.kernel.org/r/20220929121642.63051-1-oleksandrs@nvidia.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/pmbus/mp2888.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/hwmon/pmbus/mp2888.c b/drivers/hwmon/pmbus/mp2888.c index 8ecd4adfef40..24e5194706cf 100644 --- a/drivers/hwmon/pmbus/mp2888.c +++ b/drivers/hwmon/pmbus/mp2888.c @@ -34,7 +34,7 @@ struct mp2888_data { int curr_sense_gain; }; -#define to_mp2888_data(x) container_of(x, struct mp2888_data, info) +#define to_mp2888_data(x) container_of(x, struct mp2888_data, info) static int mp2888_read_byte_data(struct i2c_client *client, int page, int reg) { @@ -109,7 +109,7 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page, * - Kcs is the DrMOS current sense gain of power stage, which is obtained from the * register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS * (data->curr_sense_gain): - * 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. + * 00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A. * - Rcs is the internal phase current sense resistor. This parameter depends on hardware * assembly. By default it is set to 1kΩ. In case of different assembly, user should * scale this parameter by dividing it by Rcs. @@ -118,10 +118,9 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page, * because sampling of current occurrence of bit weight has a big deviation, especially for * light load. */ - ret = DIV_ROUND_CLOSEST(ret * 100 - 9800, data->curr_sense_gain); - ret = (data->phase_curr_resolution) ? ret * 2 : ret; + ret = DIV_ROUND_CLOSEST(ret * 200 - 19600, data->curr_sense_gain); /* Scale according to total current resolution. */ - ret = (data->total_curr_resolution) ? ret * 8 : ret * 4; + ret = (data->total_curr_resolution) ? ret * 2 : ret; return ret; } @@ -212,7 +211,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase, ret = pmbus_read_word_data(client, page, phase, reg); if (ret < 0) return ret; - ret = data->total_curr_resolution ? ret * 2 : ret; + ret = data->total_curr_resolution ? ret : DIV_ROUND_CLOSEST(ret, 2); break; case PMBUS_POUT_OP_WARN_LIMIT: ret = pmbus_read_word_data(client, page, phase, reg); @@ -223,7 +222,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase, * set 1. Actual power is reported with 0.5W or 1W respectively resolution. Scaling * is needed to match both. */ - ret = data->total_curr_resolution ? ret * 4 : ret * 2; + ret = data->total_curr_resolution ? ret * 2 : ret; break; /* * The below registers are not implemented by device or implemented not according to the From 30bfa5aa7228eb1e67663d67e553627e572cc717 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Thu, 29 Sep 2022 00:25:37 +0900 Subject: [PATCH 202/610] net: rds: don't hold sock lock when cancelling work from rds_tcp_reset_callbacks() [ Upstream commit a91b750fd6629354460282bbf5146c01b05c4859 ] syzbot is reporting lockdep warning at rds_tcp_reset_callbacks() [1], for commit ac3615e7f3cffe2a ("RDS: TCP: Reduce code duplication in rds_tcp_reset_callbacks()") added cancel_delayed_work_sync() into a section protected by lock_sock() without realizing that rds_send_xmit() might call lock_sock(). We don't need to protect cancel_delayed_work_sync() using lock_sock(), for even if rds_{send,recv}_worker() re-queued this work while __flush_work() from cancel_delayed_work_sync() was waiting for this work to complete, retried rds_{send,recv}_worker() is no-op due to the absence of RDS_CONN_UP bit. Link: https://syzkaller.appspot.com/bug?extid=78c55c7bc6f66e53dce2 [1] Reported-by: syzbot Co-developed-by: Hillf Danton Signed-off-by: Hillf Danton Signed-off-by: Tetsuo Handa Tested-by: syzbot Fixes: ac3615e7f3cffe2a ("RDS: TCP: Reduce code duplication in rds_tcp_reset_callbacks()") Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/rds/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 5327d130c4b5..b560d06e6d96 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -166,10 +166,10 @@ void rds_tcp_reset_callbacks(struct socket *sock, */ atomic_set(&cp->cp_state, RDS_CONN_RESETTING); wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags)); - lock_sock(osock->sk); /* reset receive side state for rds_tcp_data_recv() for osock */ cancel_delayed_work_sync(&cp->cp_send_w); cancel_delayed_work_sync(&cp->cp_recv_w); + lock_sock(osock->sk); if (tc->t_tinc) { rds_inc_put(&tc->t_tinc->ti_inc); tc->t_tinc = NULL; From 0b6516a4e3eb0e2dc88a538458f3f732940f44fd Mon Sep 17 00:00:00 2001 From: Jianglei Nie Date: Fri, 30 Sep 2022 14:28:43 +0800 Subject: [PATCH 203/610] bnx2x: fix potential memory leak in bnx2x_tpa_stop() [ Upstream commit b43f9acbb8942b05252be83ac25a81cec70cc192 ] bnx2x_tpa_stop() allocates a memory chunk from new_data with bnx2x_frag_alloc(). The new_data should be freed when gets some error. But when "pad + len > fp->rx_buf_size" is true, bnx2x_tpa_stop() returns without releasing the new_data, which will lead to a memory leak. We should free the new_data with bnx2x_frag_free() when "pad + len > fp->rx_buf_size" is true. Fixes: 07b0f00964def8af9321cfd6c4a7e84f6362f728 ("bnx2x: fix possible panic under memory stress") Signed-off-by: Jianglei Nie Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 198e041d8410..4f669e7c7558 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -788,6 +788,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, BNX2X_ERR("skb_put is about to fail... pad %d len %d rx_buf_size %d\n", pad, len, fp->rx_buf_size); bnx2x_panic(); + bnx2x_frag_free(fp, new_data); return; } #endif From dc4e9cd6d6a6493b7b195700b39042d484a5d850 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Sat, 1 Oct 2022 13:57:13 +0300 Subject: [PATCH 204/610] net: wwan: iosm: Call mutex_init before locking it [ Upstream commit ba0fbdb95da5ddd8db457ce6ba09d16dd979a294 ] wwan_register_ops calls wwan_create_default_link, which ends up in the ipc_wwan_newlink callback that locks ipc_wwan->if_mutex. However, this mutex is not yet initialized by that point. Fix it by moving mutex_init above the wwan_register_ops call. This also makes the order of operations in ipc_wwan_init symmetric to ipc_wwan_deinit. Fixes: 83068395bbfc ("net: iosm: create default link via WWAN core") Signed-off-by: Maxim Mikityanskiy Reviewed-by: M Chetan Kumar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/wwan/iosm/iosm_ipc_wwan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c index b571d9cedba4..92f064a8f837 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c +++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c @@ -322,15 +322,16 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev) ipc_wwan->dev = dev; ipc_wwan->ipc_imem = ipc_imem; + mutex_init(&ipc_wwan->if_mutex); + /* WWAN core will create a netdev for the default IP MUX channel */ if (wwan_register_ops(ipc_wwan->dev, &iosm_wwan_ops, ipc_wwan, IP_MUX_SESSION_DEFAULT)) { + mutex_destroy(&ipc_wwan->if_mutex); kfree(ipc_wwan); return NULL; } - mutex_init(&ipc_wwan->if_mutex); - return ipc_wwan; } From 77bfd26cbb61a9f49ecb83729f0fd1352c17ddd8 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 2 Oct 2022 01:43:44 +0900 Subject: [PATCH 205/610] net/ieee802154: reject zero-sized raw_sendmsg() [ Upstream commit 3a4d061c699bd3eedc80dc97a4b2a2e1af83c6f5 ] syzbot is hitting skb_assert_len() warning at raw_sendmsg() for ieee802154 socket. What commit dc633700f00f726e ("net/af_packet: check len when min_header_len equals to 0") does also applies to ieee802154 socket. Link: https://syzkaller.appspot.com/bug?extid=5ea725c25d06fb9114c4 Reported-by: syzbot Fixes: fd1894224407c484 ("bpf: Don't redirect packets with invalid pkt_len") Signed-off-by: Tetsuo Handa Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ieee802154/socket.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c index fd5862f9e26a..f160cfc3e8f0 100644 --- a/net/ieee802154/socket.c +++ b/net/ieee802154/socket.c @@ -251,6 +251,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) return -EOPNOTSUPP; } + if (!size) + return -EINVAL; + lock_sock(sk); if (!sk->sk_bound_dev_if) dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); From 7aef5082c56e49c785271649d1f486544d33ef61 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 1 Oct 2022 13:51:02 -0700 Subject: [PATCH 206/610] once: add DO_ONCE_SLOW() for sleepable contexts [ Upstream commit 62c07983bef9d3e78e71189441e1a470f0d1e653 ] Christophe Leroy reported a ~80ms latency spike happening at first TCP connect() time. This is because __inet_hash_connect() uses get_random_once() to populate a perturbation table which became quite big after commit 4c2c8f03a5ab ("tcp: increase source port perturb table to 2^16") get_random_once() uses DO_ONCE(), which block hard irqs for the duration of the operation. This patch adds DO_ONCE_SLOW() which uses a mutex instead of a spinlock for operations where we prefer to stay in process context. Then __inet_hash_connect() can use get_random_slow_once() to populate its perturbation table. Fixes: 4c2c8f03a5ab ("tcp: increase source port perturb table to 2^16") Fixes: 190cc82489f4 ("tcp: change source port randomizarion at connect() time") Reported-by: Christophe Leroy Link: https://lore.kernel.org/netdev/CANn89iLAEYBaoYajy0Y9UmGFff5GPxDUoG-ErVB2jDdRNQ5Tug@mail.gmail.com/T/#t Signed-off-by: Eric Dumazet Cc: Willy Tarreau Tested-by: Christophe Leroy Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/linux/once.h | 28 ++++++++++++++++++++++++++++ lib/once.c | 30 ++++++++++++++++++++++++++++++ net/ipv4/inet_hashtables.c | 4 ++-- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/include/linux/once.h b/include/linux/once.h index d361fb14ac3a..1528625087b6 100644 --- a/include/linux/once.h +++ b/include/linux/once.h @@ -5,10 +5,18 @@ #include #include +/* Helpers used from arbitrary contexts. + * Hard irqs are blocked, be cautious. + */ bool __do_once_start(bool *done, unsigned long *flags); void __do_once_done(bool *done, struct static_key_true *once_key, unsigned long *flags, struct module *mod); +/* Variant for process contexts only. */ +bool __do_once_slow_start(bool *done); +void __do_once_slow_done(bool *done, struct static_key_true *once_key, + struct module *mod); + /* Call a function exactly once. The idea of DO_ONCE() is to perform * a function call such as initialization of random seeds, etc, only * once, where DO_ONCE() can live in the fast-path. After @func has @@ -52,9 +60,29 @@ void __do_once_done(bool *done, struct static_key_true *once_key, ___ret; \ }) +/* Variant of DO_ONCE() for process/sleepable contexts. */ +#define DO_ONCE_SLOW(func, ...) \ + ({ \ + bool ___ret = false; \ + static bool __section(".data.once") ___done = false; \ + static DEFINE_STATIC_KEY_TRUE(___once_key); \ + if (static_branch_unlikely(&___once_key)) { \ + ___ret = __do_once_slow_start(&___done); \ + if (unlikely(___ret)) { \ + func(__VA_ARGS__); \ + __do_once_slow_done(&___done, &___once_key, \ + THIS_MODULE); \ + } \ + } \ + ___ret; \ + }) + #define get_random_once(buf, nbytes) \ DO_ONCE(get_random_bytes, (buf), (nbytes)) #define get_random_once_wait(buf, nbytes) \ DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \ +#define get_random_slow_once(buf, nbytes) \ + DO_ONCE_SLOW(get_random_bytes, (buf), (nbytes)) + #endif /* _LINUX_ONCE_H */ diff --git a/lib/once.c b/lib/once.c index 59149bf3bfb4..351f66aad310 100644 --- a/lib/once.c +++ b/lib/once.c @@ -66,3 +66,33 @@ void __do_once_done(bool *done, struct static_key_true *once_key, once_disable_jump(once_key, mod); } EXPORT_SYMBOL(__do_once_done); + +static DEFINE_MUTEX(once_mutex); + +bool __do_once_slow_start(bool *done) + __acquires(once_mutex) +{ + mutex_lock(&once_mutex); + if (*done) { + mutex_unlock(&once_mutex); + /* Keep sparse happy by restoring an even lock count on + * this mutex. In case we return here, we don't call into + * __do_once_done but return early in the DO_ONCE_SLOW() macro. + */ + __acquire(once_mutex); + return false; + } + + return true; +} +EXPORT_SYMBOL(__do_once_slow_start); + +void __do_once_slow_done(bool *done, struct static_key_true *once_key, + struct module *mod) + __releases(once_mutex) +{ + *done = true; + mutex_unlock(&once_mutex); + once_disable_jump(once_key, mod); +} +EXPORT_SYMBOL(__do_once_slow_done); diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 26c4dd4ec459..ce6a3873f89e 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -771,8 +771,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, if (likely(remaining > 1)) remaining &= ~1U; - net_get_random_once(table_perturb, - INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb)); + get_random_slow_once(table_perturb, + INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb)); index = port_offset & (INET_TABLE_PERTURB_SIZE - 1); offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32); From a624161ebe0c678c10c4c82b574fed6c04d552d8 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Mon, 3 Oct 2022 17:19:27 +0100 Subject: [PATCH 207/610] net: mvpp2: fix mvpp2 debugfs leak [ Upstream commit 0152dfee235e87660f52a117fc9f70dc55956bb4 ] When mvpp2 is unloaded, the driver specific debugfs directory is not removed, which technically leads to a memory leak. However, this directory is only created when the first device is probed, so the hardware is present. Removing the module is only something a developer would to when e.g. testing out changes, so the module would be reloaded. So this memory leak is minor. The original attempt in commit fe2c9c61f668 ("net: mvpp2: debugfs: fix memory leak when using debugfs_lookup()") that was labelled as a memory leak fix was not, it fixed a refcount leak, but in doing so created a problem when the module is reloaded - the directory already exists, but mvpp2_root is NULL, so we lose all debugfs entries. This fix has been reverted. This is the alternative fix, where we remove the offending directory whenever the driver is unloaded. Fixes: 21da57a23125 ("net: mvpp2: add a debugfs interface for the Header Parser") Signed-off-by: Russell King (Oracle) Reviewed-by: Greg Kroah-Hartman Reviewed-by: Marcin Wojtas Link: https://lore.kernel.org/r/E1ofOAB-00CzkG-UO@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 1 + drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c | 10 ++++++++-- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 13 ++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h index cf8acabb90ac..72608a47d4e0 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -1529,6 +1529,7 @@ u32 mvpp2_read(struct mvpp2 *priv, u32 offset); void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name); void mvpp2_dbgfs_cleanup(struct mvpp2 *priv); +void mvpp2_dbgfs_exit(void); void mvpp23_rx_fifo_fc_en(struct mvpp2 *priv, int port, bool en); diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c index 4a3baa7e0142..75e83ea2a926 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c @@ -691,6 +691,13 @@ static int mvpp2_dbgfs_port_init(struct dentry *parent, return 0; } +static struct dentry *mvpp2_root; + +void mvpp2_dbgfs_exit(void) +{ + debugfs_remove(mvpp2_root); +} + void mvpp2_dbgfs_cleanup(struct mvpp2 *priv) { debugfs_remove_recursive(priv->dbgfs_dir); @@ -700,10 +707,9 @@ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv) void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name) { - struct dentry *mvpp2_dir, *mvpp2_root; + struct dentry *mvpp2_dir; int ret, i; - mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL); if (!mvpp2_root) mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL); diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 2baa909290b3..ae586f8895fc 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -7710,7 +7710,18 @@ static struct platform_driver mvpp2_driver = { }, }; -module_platform_driver(mvpp2_driver); +static int __init mvpp2_driver_init(void) +{ + return platform_driver_register(&mvpp2_driver); +} +module_init(mvpp2_driver_init); + +static void __exit mvpp2_driver_exit(void) +{ + platform_driver_unregister(&mvpp2_driver); + mvpp2_dbgfs_exit(); +} +module_exit(mvpp2_driver_exit); MODULE_DESCRIPTION("Marvell PPv2 Ethernet Driver - www.marvell.com"); MODULE_AUTHOR("Marcin Wojtas "); From 20609125b8bd0d4acbb20f6c9075675e07556fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Sun, 12 Jun 2022 16:48:53 +0200 Subject: [PATCH 208/610] drm: bridge: adv7511: fix CEC power down control register offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 1d22b6033ea113a4c3850dfa2c0770885c81aec8 ] The ADV7511_REG_CEC_CTRL = 0xE2 register is part of the main register map - not the CEC register map. As such, we shouldn't apply an offset to the register address. Doing so will cause us to address a bogus register for chips with a CEC register map offset (e.g. ADV7533). Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support") Signed-off-by: Alvin Šipraga Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20220612144854.2223873-2-alvin@pqrs.dk Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 5 +---- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 1b00dfda6e0d..aeeb09a27202 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -387,10 +387,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1); #else static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) { - unsigned int offset = adv7511->type == ADV7533 ? - ADV7533_REG_CEC_OFFSET : 0; - - regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, ADV7511_CEC_CTRL_POWER_DOWN); return 0; } diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index a20a45c0b353..ddd1305b82b2 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -316,7 +316,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) goto err_cec_alloc; } - regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 0); /* cec soft reset */ regmap_write(adv7511->regmap_cec, ADV7511_REG_CEC_SOFT_RESET + offset, 0x01); @@ -343,7 +343,7 @@ err_cec_alloc: dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n", ret); err_cec_parse_dt: - regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, ADV7511_CEC_CTRL_POWER_DOWN); return ret == -EPROBE_DEFER ? ret : 0; } From f369fb4deed7ab997cfa703dc85ec08b3adc1af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Sun, 12 Jun 2022 16:48:54 +0200 Subject: [PATCH 209/610] drm: bridge: adv7511: unregister cec i2c device after cec adapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 40cdb02cb9f965732eb543d47f15bef8d10f0f5f ] cec_unregister_adapter() assumes that the underlying adapter ops are callable. For example, if the CEC adapter currently has a valid physical address, then the unregistration procedure will invalidate the physical address by setting it to f.f.f.f. Whence the following kernel oops observed after removing the adv7511 module: Unable to handle kernel execution of user memory at virtual address 0000000000000000 Internal error: Oops: 86000004 [#1] PREEMPT_RT SMP Call trace: 0x0 adv7511_cec_adap_log_addr+0x1ac/0x1c8 [adv7511] cec_adap_unconfigure+0x44/0x90 [cec] __cec_s_phys_addr.part.0+0x68/0x230 [cec] __cec_s_phys_addr+0x40/0x50 [cec] cec_unregister_adapter+0xb4/0x118 [cec] adv7511_remove+0x60/0x90 [adv7511] i2c_device_remove+0x34/0xe0 device_release_driver_internal+0x114/0x1f0 driver_detach+0x54/0xe0 bus_remove_driver+0x60/0xd8 driver_unregister+0x34/0x60 i2c_del_driver+0x2c/0x68 adv7511_exit+0x1c/0x67c [adv7511] __arm64_sys_delete_module+0x154/0x288 invoke_syscall+0x48/0x100 el0_svc_common.constprop.0+0x48/0xe8 do_el0_svc+0x28/0x88 el0_svc+0x1c/0x50 el0t_64_sync_handler+0xa8/0xb0 el0t_64_sync+0x15c/0x160 Code: bad PC value ---[ end trace 0000000000000000 ]--- Protect against this scenario by unregistering i2c_cec after unregistering the CEC adapter. Duly disable the CEC clock afterwards too. Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support") Signed-off-by: Alvin Šipraga Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20220612144854.2223873-3-alvin@pqrs.dk Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 7e3f6633f255..3dc551d223d6 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1326,8 +1326,6 @@ static int adv7511_remove(struct i2c_client *i2c) if (adv7511->type == ADV7533 || adv7511->type == ADV7535) adv7533_detach_dsi(adv7511); - i2c_unregister_device(adv7511->i2c_cec); - clk_disable_unprepare(adv7511->cec_clk); adv7511_uninit_regulators(adv7511); @@ -1336,6 +1334,8 @@ static int adv7511_remove(struct i2c_client *i2c) adv7511_audio_exit(adv7511); cec_unregister_adapter(adv7511->cec_adap); + i2c_unregister_device(adv7511->i2c_cec); + clk_disable_unprepare(adv7511->cec_clk); i2c_unregister_device(adv7511->i2c_packet); i2c_unregister_device(adv7511->i2c_edid); From 652042135e08db9584ef365572e8fe69a2a59105 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 4 Jul 2022 13:55:40 +0300 Subject: [PATCH 210/610] drm/bridge: Avoid uninitialized variable warning [ Upstream commit 7d1202738efda60155d98b370b3c70d336be0eea ] This code works, but technically it uses "num_in_bus_fmts" before it has been initialized so it leads to static checker warnings and probably KMEMsan warnings at run time. Initialize the variable to zero to silence the warning. Fixes: f32df58acc68 ("drm/bridge: Add the necessary bits to support bus format negotiation") Signed-off-by: Dan Carpenter Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/YrrIs3hoGcPVmXc5@kili Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_bridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 7ee29f073857..78bc315b0b73 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -762,8 +762,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, struct drm_connector_state *conn_state, u32 out_bus_fmt) { + unsigned int i, num_in_bus_fmts = 0; struct drm_bridge_state *cur_state; - unsigned int num_in_bus_fmts, i; struct drm_bridge *prev_bridge; u32 *in_bus_fmts; int ret; @@ -884,7 +884,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, struct drm_connector *conn = conn_state->connector; struct drm_encoder *encoder = bridge->encoder; struct drm_bridge_state *last_bridge_state; - unsigned int i, num_out_bus_fmts; + unsigned int i, num_out_bus_fmts = 0; struct drm_bridge *last_bridge; u32 *out_bus_fmts; int ret = 0; From 26c1b4cfe56f040f71a51c92da1f4cac2e3b9455 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 11 Jul 2022 19:38:31 +0200 Subject: [PATCH 211/610] drm/mipi-dsi: Detach devices when removing the host [ Upstream commit 668a8f17b5290d04ef7343636a5588a0692731a1 ] Whenever the MIPI-DSI host is unregistered, the code of mipi_dsi_host_unregister() loops over every device currently found on that bus and will unregister it. However, it doesn't detach it from the bus first, which leads to all kind of resource leaks if the host wants to perform some clean up whenever a device is detached. Fixes: 068a00233969 ("drm: Add MIPI DSI bus support") Acked-by: Thomas Zimmermann Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20220711173939.1132294-2-maxime@cerno.tech Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_mipi_dsi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 5dd475e82995..2c43d54766f3 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -300,6 +300,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); + mipi_dsi_detach(dsi); mipi_dsi_device_unregister(dsi); return 0; From 60630834fad38252369bf4a351a03b75b76786e3 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 30 Jun 2022 23:07:18 +0300 Subject: [PATCH 212/610] drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling [ Upstream commit 64b88afbd92fbf434759d1896a7cf705e1c00e79 ] 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: Sasha Levin --- 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 248ecd3006c3..7e75fb0fc7bd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -169,6 +169,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, shmem->pages = drm_gem_shmem_get_sg_table(&bo->base); if (IS_ERR(shmem->pages)) { drm_gem_shmem_unpin(&bo->base); + shmem->pages = NULL; return PTR_ERR(shmem->pages); } From fe6eb3d0c874c3e29694c6e19668dfdbf1048f9f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jul 2022 17:22:58 +0800 Subject: [PATCH 213/610] drm/bridge: parade-ps8640: Fix regulator supply order [ Upstream commit fc94224c2e0ae8d83ac511a3ef4962178505469d ] The datasheet says that VDD12 must be enabled and at full voltage before VDD33 is enabled. Reorder the bulk regulator supply names so that VDD12 is enabled before VDD33. Any enable ramp delays should be handled by setting proper constraints on the regulators. Fixes: bc1aee7fc8f0 ("drm/bridge: Add I2C based driver for ps8640 bridge") Signed-off-by: Chen-Yu Tsai Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20220721092258.3397461-1-wenst@chromium.org Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/bridge/parade-ps8640.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c index 7bd0affa057a..924851010400 100644 --- a/drivers/gpu/drm/bridge/parade-ps8640.c +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -333,8 +333,8 @@ static int ps8640_probe(struct i2c_client *client) if (IS_ERR(ps_bridge->panel_bridge)) return PTR_ERR(ps_bridge->panel_bridge); - ps_bridge->supplies[0].supply = "vdd33"; - ps_bridge->supplies[1].supply = "vdd12"; + ps_bridge->supplies[0].supply = "vdd12"; + ps_bridge->supplies[1].supply = "vdd33"; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), ps_bridge->supplies); if (ret) From 56d2233cf57310cdcdc2469c5192cdcbacd1807b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 10 Feb 2022 15:40:25 +0000 Subject: [PATCH 214/610] drm/dp_mst: fix drm_dp_dpcd_read return value checks [ Upstream commit 2ac6cdd581f48c8f68747156fde5868486a44985 ] drm_dp_dpcd_read returns the number of bytes read. The previous code would print garbage on DPCD error, and would exit with on error on success. Signed-off-by: Simon Ser Fixes: cb897542c6d2 ("drm/dp_mst: Fix W=1 warnings") Cc: Lyude Paul Cc: Benjamin Gaignard Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/473500/ Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_dp_mst_topology.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 2a586e6489da..9bf9430209b0 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -4899,14 +4899,14 @@ void drm_dp_mst_dump_topology(struct seq_file *m, seq_printf(m, "dpcd: %*ph\n", DP_RECEIVER_CAP_SIZE, buf); ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2); - if (ret) { + if (ret != 2) { seq_printf(m, "faux/mst read failed\n"); goto out; } seq_printf(m, "faux/mst: %*ph\n", 2, buf); ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1); - if (ret) { + if (ret != 1) { seq_printf(m, "mst ctrl read failed\n"); goto out; } @@ -4914,7 +4914,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m, /* dump the standard OUI branch header */ ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE); - if (ret) { + if (ret != DP_BRANCH_OUI_HEADER_SIZE) { seq_printf(m, "branch oui read failed\n"); goto out; } From 8a475a7732a5a9ba96605c61615b4aa9602b659d Mon Sep 17 00:00:00 2001 From: Liang He Date: Mon, 11 Jul 2022 21:15:50 +0800 Subject: [PATCH 215/610] drm:pl111: Add of_node_put() when breaking out of for_each_available_child_of_node() [ Upstream commit e0686dc6f2252e009c455fe99e2ce9d62a60eb47 ] The reference 'child' in the iteration of for_each_available_child_of_node() is only escaped out into a local variable which is only used to check its value. So we still need to the of_node_put() when breaking of the for_each_available_child_of_node() which will automatically increase and decrease the refcount. Fixes: ca454bd42dc2 ("drm/pl111: Support the Versatile Express") Signed-off-by: Liang He Reviewed-by: Rob Herring Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20220711131550.361350-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/pl111/pl111_versatile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c index bdd883f4f0da..963a5d5e6987 100644 --- a/drivers/gpu/drm/pl111/pl111_versatile.c +++ b/drivers/gpu/drm/pl111/pl111_versatile.c @@ -402,6 +402,7 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np, if (of_device_is_compatible(child, "arm,pl111")) { has_coretile_clcd = true; ct_clcd = child; + of_node_put(child); break; } if (of_device_is_compatible(child, "arm,hdlcd")) { From 57dfb855bc9e3c47710ff0c5d46841c6aeb6d434 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 11 Aug 2022 14:01:26 +0300 Subject: [PATCH 216/610] ASoC: mt6359: fix tests for platform_get_irq() failure [ Upstream commit 51eea3a6fb4d39c2cc71824e6eee5949d7ae4d1c ] The platform_get_irq() returns negative error codes. It can't actually return zero, but if it did that should be treated as success. Fixes: eef07b9e0925 ("ASoC: mediatek: mt6359: add MT6359 accdet jack driver") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/YvThhr86N3qQM2EO@kili Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/mt6359-accdet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c index c190628e2905..7f624854948c 100644 --- a/sound/soc/codecs/mt6359-accdet.c +++ b/sound/soc/codecs/mt6359-accdet.c @@ -965,7 +965,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) mutex_init(&priv->res_lock); priv->accdet_irq = platform_get_irq(pdev, 0); - if (priv->accdet_irq) { + if (priv->accdet_irq >= 0) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_irq, NULL, mt6359_accdet_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, @@ -979,7 +979,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) if (priv->caps & ACCDET_PMIC_EINT0) { priv->accdet_eint0 = platform_get_irq(pdev, 1); - if (priv->accdet_eint0) { + if (priv->accdet_eint0 >= 0) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_eint0, NULL, mt6359_accdet_irq, @@ -994,7 +994,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) } } else if (priv->caps & ACCDET_PMIC_EINT1) { priv->accdet_eint1 = platform_get_irq(pdev, 2); - if (priv->accdet_eint1) { + if (priv->accdet_eint1 >= 0) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_eint1, NULL, mt6359_accdet_irq, From 27bb672c0437faf172a85928a3c5fbbc56667635 Mon Sep 17 00:00:00 2001 From: Rustam Subkhankulov Date: Sun, 14 Aug 2022 01:08:43 +0300 Subject: [PATCH 217/610] platform/chrome: fix double-free in chromeos_laptop_prepare() [ Upstream commit 6ad4194d6a1e1d11b285989cd648ef695b4a93c0 ] If chromeos_laptop_prepare_i2c_peripherals() fails after allocating memory for 'cros_laptop->i2c_peripherals', this memory is freed at 'err_out' label and nonzero value is returned. Then chromeos_laptop_destroy() is called, resulting in double-free error. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Rustam Subkhankulov Fixes: 5020cd29d8bf ("platform/chrome: chromeos_laptop - supply properties for ACPI devices") Reviewed-by: Dmitry Torokhov Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20220813220843.2373004-1-subkhankulov@ispras.ru Signed-off-by: Sasha Levin --- drivers/platform/chrome/chromeos_laptop.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 4e14b4d6635d..a2cdbfbaeae6 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -740,6 +740,7 @@ static int __init chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, const struct chromeos_laptop *src) { + struct i2c_peripheral *i2c_peripherals; struct i2c_peripheral *i2c_dev; struct i2c_board_info *info; int i; @@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, if (!src->num_i2c_peripherals) return 0; - cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals, - src->num_i2c_peripherals * - sizeof(*src->i2c_peripherals), - GFP_KERNEL); - if (!cros_laptop->i2c_peripherals) + i2c_peripherals = kmemdup(src->i2c_peripherals, + src->num_i2c_peripherals * + sizeof(*src->i2c_peripherals), + GFP_KERNEL); + if (!i2c_peripherals) return -ENOMEM; - cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; - - for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; + for (i = 0; i < src->num_i2c_peripherals; i++) { + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info; error = chromeos_laptop_setup_irq(i2c_dev); @@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, } } + cros_laptop->i2c_peripherals = i2c_peripherals; + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; + return 0; err_out: while (--i >= 0) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info; if (!IS_ERR_OR_NULL(info->fwnode)) fwnode_remove_software_node(info->fwnode); } - kfree(cros_laptop->i2c_peripherals); + kfree(i2c_peripherals); return error; } From fd1d3b265784a2243fcaef06aebfb2f8ee733cec Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 19 Aug 2022 08:20:36 +0300 Subject: [PATCH 218/610] platform/chrome: fix memory corruption in ioctl [ Upstream commit 8a07b45fd3c2dda24fad43639be5335a4595196a ] If "s_mem.bytes" is larger than the buffer size it leads to memory corruption. Fixes: eda2e30c6684 ("mfd / platform: cros_ec: Miscellaneous character device to talk with the EC") Signed-off-by: Dan Carpenter Reviewed-by: Guenter Roeck Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/Yv8dpCFZJdbUT5ye@kili Signed-off-by: Sasha Levin --- drivers/platform/chrome/cros_ec_chardev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c index fd33de546aee..0de7c255254e 100644 --- a/drivers/platform/chrome/cros_ec_chardev.c +++ b/drivers/platform/chrome/cros_ec_chardev.c @@ -327,6 +327,9 @@ static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec, if (copy_from_user(&s_mem, arg, sizeof(s_mem))) return -EFAULT; + if (s_mem.bytes > sizeof(s_mem.buffer)) + return -EINVAL; + num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, s_mem.buffer); if (num <= 0) From 35bd912ed6c09e9eda99ec4635bf3909de543810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 25 Aug 2022 16:02:37 +0200 Subject: [PATCH 219/610] ASoC: tas2764: Allow mono streams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 23204d928a27146d13e11c9383632775345ecca8 ] The part is a mono speaker amp, but it can do downmix and switch between left and right channel, so the right channel range is 1 to 2. (This mirrors commit bf54d97a835d ("ASoC: tas2770: Allow mono streams") which was a fix to the tas2770 driver.) Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764") Signed-off-by: Martin Povišer Link: https://lore.kernel.org/r/20220825140241.53963-2-povik+lin@cutebit.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/tas2764.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index ec13ba01e522..d0b6c174186d 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -485,7 +485,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { .id = 0, .playback = { .stream_name = "ASI1 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = TAS2764_RATES, .formats = TAS2764_FORMATS, From e644497c5361a29276e5009cf49cae1adf422397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 25 Aug 2022 16:02:38 +0200 Subject: [PATCH 220/610] ASoC: tas2764: Drop conflicting set_bias_level power setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 09273f38832406db19a8907a934687cc10660a6b ] The driver is setting the PWR_CTRL field in both the set_bias_level callback and on DAPM events of the DAC widget (and also in the mute_stream method). Drop the set_bias_level callback altogether as the power setting it does is in conflict with the other code paths. (This mirrors commit c8a6ae3fe1c8 ("ASoC: tas2770: Drop conflicting set_bias_level power setting") which was a fix to the tas2770 driver.) Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764") Signed-off-by: Martin Povišer Link: https://lore.kernel.org/r/20220825140241.53963-3-povik+lin@cutebit.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/tas2764.c | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index d0b6c174186d..e76ce90c787f 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -50,38 +50,6 @@ static void tas2764_reset(struct tas2764_priv *tas2764) usleep_range(1000, 2000); } -static int tas2764_set_bias_level(struct snd_soc_component *component, - enum snd_soc_bias_level level) -{ - struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); - - switch (level) { - case SND_SOC_BIAS_ON: - snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_ACTIVE); - break; - case SND_SOC_BIAS_STANDBY: - case SND_SOC_BIAS_PREPARE: - snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_MUTE); - break; - case SND_SOC_BIAS_OFF: - snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_SHUTDOWN); - break; - - default: - dev_err(tas2764->dev, - "wrong power level setting %d\n", level); - return -EINVAL; - } - - return 0; -} - #ifdef CONFIG_PM static int tas2764_codec_suspend(struct snd_soc_component *component) { @@ -549,7 +517,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = { .probe = tas2764_codec_probe, .suspend = tas2764_codec_suspend, .resume = tas2764_codec_resume, - .set_bias_level = tas2764_set_bias_level, .controls = tas2764_snd_controls, .num_controls = ARRAY_SIZE(tas2764_snd_controls), .dapm_widgets = tas2764_dapm_widgets, From 6bc81c1b6313c022b74995d84775bd421c6991c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 25 Aug 2022 16:02:39 +0200 Subject: [PATCH 221/610] ASoC: tas2764: Fix mute/unmute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f5ad67f13623548e5aff847f89700c178aaf2a98 ] Because the PWR_CTRL field is modeled as the power state of the DAC widget, and at the same time it is used to implement mute/unmute, we need some additional book-keeping to have the right end result no matter the sequence of calls. Without this fix, one permanently mutes an ongoing stream by toggling the associated speaker pin control. (This mirrors commit 1e5907bcb3a3 ("ASoC: tas2770: Fix handling of mute/unmute") which was a fix to the tas2770 driver.) Fixes: 827ed8a0fa50 ("ASoC: tas2764: Add the driver for the TAS2764") Signed-off-by: Martin Povišer Link: https://lore.kernel.org/r/20220825140241.53963-4-povik+lin@cutebit.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/tas2764.c | 57 +++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index e76ce90c787f..afb4c0d7e714 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -34,6 +34,9 @@ struct tas2764_priv { int v_sense_slot; int i_sense_slot; + + bool dac_powered; + bool unmuted; }; static void tas2764_reset(struct tas2764_priv *tas2764) @@ -50,6 +53,26 @@ static void tas2764_reset(struct tas2764_priv *tas2764) usleep_range(1000, 2000); } +static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764) +{ + struct snd_soc_component *component = tas2764->component; + unsigned int val; + int ret; + + if (tas2764->dac_powered) + val = tas2764->unmuted ? + TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE; + else + val = TAS2764_PWR_CTRL_SHUTDOWN; + + ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, + TAS2764_PWR_CTRL_MASK, val); + if (ret < 0) + return ret; + + return 0; +} + #ifdef CONFIG_PM static int tas2764_codec_suspend(struct snd_soc_component *component) { @@ -82,9 +105,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component) usleep_range(1000, 2000); } - ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_ACTIVE); + ret = tas2764_update_pwr_ctrl(tas2764); if (ret < 0) return ret; @@ -118,14 +139,12 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: - ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_MUTE); + tas2764->dac_powered = true; + ret = tas2764_update_pwr_ctrl(tas2764); break; case SND_SOC_DAPM_PRE_PMD: - ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_SHUTDOWN); + tas2764->dac_powered = false; + ret = tas2764_update_pwr_ctrl(tas2764); break; default: dev_err(tas2764->dev, "Unsupported event\n"); @@ -170,17 +189,11 @@ static const struct snd_soc_dapm_route tas2764_audio_map[] = { static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) { - struct snd_soc_component *component = dai->component; - int ret; + struct tas2764_priv *tas2764 = + snd_soc_component_get_drvdata(dai->component); - ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - mute ? TAS2764_PWR_CTRL_MUTE : 0); - - if (ret < 0) - return ret; - - return 0; + tas2764->unmuted = !mute; + return tas2764_update_pwr_ctrl(tas2764); } static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth) @@ -494,12 +507,6 @@ static int tas2764_codec_probe(struct snd_soc_component *component) if (ret < 0) return ret; - ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, - TAS2764_PWR_CTRL_MASK, - TAS2764_PWR_CTRL_MUTE); - if (ret < 0) - return ret; - return 0; } From 0e21d41bc768e1f4eeeb4a4f9e8d30d47655815f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 25 Aug 2022 16:13:34 +0200 Subject: [PATCH 222/610] platform/x86: msi-laptop: Fix old-ec check for backlight registering [ Upstream commit 83ac7a1c2ed5f17caa07cbbc84bad3c05dc3bf22 ] Commit 2cc6c717799f ("msi-laptop: Port to new backlight interface selection API") replaced this check: if (!quirks->old_ec_model || acpi_video_backlight_support()) pr_info("Brightness ignored, ..."); else do_register(); With: if (quirks->old_ec_model || acpi_video_get_backlight_type() == acpi_backlight_vendor) do_register(); But since the do_register() part was part of the else branch, the entire condition should be inverted. So not only the 2 statements on either side of the || should be inverted, but the || itself should be replaced with a &&. In practice this has likely not been an issue because the new-ec models (old_ec_model==false) likely all support ACPI video backlight control, making acpi_video_get_backlight_type() return acpi_backlight_video turning the second part of the || also false when old_ec_model == false. Fixes: 2cc6c717799f ("msi-laptop: Port to new backlight interface selection API") Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20220825141336.208597-1-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/msi-laptop.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 24ffc8e2d2d1..0960205ee49f 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -1048,8 +1048,7 @@ static int __init msi_init(void) return -EINVAL; /* Register backlight stuff */ - - if (quirks->old_ec_model || + if (quirks->old_ec_model && acpi_video_get_backlight_type() == acpi_backlight_vendor) { struct backlight_properties props; memset(&props, 0, sizeof(struct backlight_properties)); From c317d2b8a430e6482e020c8b05f218de215fe3ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 25 Aug 2022 16:13:36 +0200 Subject: [PATCH 223/610] platform/x86: msi-laptop: Fix resource cleanup [ Upstream commit 5523632aa10f906dfe2eb714ee748590dc7fc6b1 ] Fix the input-device not getting free-ed on probe-errors and fix the msi_touchpad_dwork not getting cancelled on neither probe-errors nor on remove. Fixes: 143a4c0284dc ("msi-laptop: send out touchpad on/off key") Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20220825141336.208597-3-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/msi-laptop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 0960205ee49f..3e935303b143 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -1116,6 +1116,8 @@ fail_create_attr: fail_create_group: if (quirks->load_scm_model) { i8042_remove_filter(msi_laptop_i8042_filter); + cancel_delayed_work_sync(&msi_touchpad_dwork); + input_unregister_device(msi_laptop_input_dev); cancel_delayed_work_sync(&msi_rfkill_dwork); cancel_work_sync(&msi_rfkill_work); rfkill_cleanup(); @@ -1136,6 +1138,7 @@ static void __exit msi_cleanup(void) { if (quirks->load_scm_model) { i8042_remove_filter(msi_laptop_i8042_filter); + cancel_delayed_work_sync(&msi_touchpad_dwork); input_unregister_device(msi_laptop_input_dev); cancel_delayed_work_sync(&msi_rfkill_dwork); cancel_work_sync(&msi_rfkill_work); From c12daccc901711c88b772c4e0946fc024d3a18b7 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Fri, 19 Aug 2022 19:08:03 +0000 Subject: [PATCH 224/610] platform/chrome: cros_ec_typec: Correct alt mode index [ Upstream commit 4e477663e396f48c5cfc5f2d75d4b514f409516a ] Alt mode indices used by USB PD (Power Delivery) start with 1, not 0. Update the alt mdoe registration code to factor this in to the alt mode descriptor. Fixes: de0f49487db3 ("platform/chrome: cros_ec_typec: Register partner altmodes") Signed-off-by: Prashant Malani Acked-by: Heikki Krogerus Reviewed-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20220819190807.1275937-3-pmalani@chromium.org Signed-off-by: Sasha Levin --- drivers/platform/chrome/cros_ec_typec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 4027c3ef90d7..aadb8d237aef 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -691,7 +691,7 @@ static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_ for (j = 0; j < sop_disc->svids[i].mode_count; j++) { memset(&desc, 0, sizeof(desc)); desc.svid = sop_disc->svids[i].svid; - desc.mode = j; + desc.mode = j + 1; desc.vdo = sop_disc->svids[i].mode_vdo[j]; if (is_partner) From 079c550c57ff5f40a78fcb65ad3e0e6721cbff6f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 26 Aug 2022 16:57:54 +0800 Subject: [PATCH 225/610] drm/amdgpu: add missing pci_disable_device() in amdgpu_pmops_runtime_resume() [ Upstream commit 6b11af6d1c8f5d4135332bb932baaa06e511173d ] Add missing pci_disable_device() if amdgpu_device_resume() fails. Fixes: 8e4d5d43cc6c ("drm/amdgpu: Handling of amdgpu_device_resume return value for graceful teardown") Signed-off-by: Yang Yingliang Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index f65b4b233ffb..28dea2eb61c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2415,8 +2415,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev) amdgpu_device_baco_exit(drm_dev); } ret = amdgpu_device_resume(drm_dev, false); - if (ret) + if (ret) { + if (amdgpu_device_supports_px(drm_dev)) + pci_disable_device(pdev); return ret; + } if (amdgpu_device_supports_px(drm_dev)) drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; From 4610e7a4111fa3f3ce27c09d6d94008c55f1cd31 Mon Sep 17 00:00:00 2001 From: Zheyu Ma Date: Tue, 30 Aug 2022 15:34:50 +0800 Subject: [PATCH 226/610] drm/bridge: megachips: Fix a null pointer dereference bug [ Upstream commit 1ff673333d46d2c1b053ebd0c1c7c7c79e36943e ] When removing the module we will get the following warning: [ 31.911505] i2c-core: driver [stdp2690-ge-b850v3-fw] unregistered [ 31.912484] general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN PTI [ 31.913338] KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] [ 31.915280] RIP: 0010:drm_bridge_remove+0x97/0x130 [ 31.921825] Call Trace: [ 31.922533] stdp4028_ge_b850v3_fw_remove+0x34/0x60 [megachips_stdpxxxx_ge_b850v3_fw] [ 31.923139] i2c_device_remove+0x181/0x1f0 The two bridges (stdp2690, stdp4028) do not probe at the same time, so the driver does not call ge_b850v3_resgiter() when probing, causing the driver to try to remove the object that has not been initialized. Fix this by checking whether both the bridges are probed. Fixes: 11632d4aa2b3 ("drm/bridge: megachips: Ensure both bridges are probed before registration") Signed-off-by: Zheyu Ma Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20220830073450.1897020-1-zheyuma97@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 4 +++- 1 file changed, 3 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 cce98bf2a4e7..72248a565579 100644 --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void) * This check is to avoid both the drivers * removing the bridge in their remove() function */ - if (!ge_b850v3_lvds_ptr) + if (!ge_b850v3_lvds_ptr || + !ge_b850v3_lvds_ptr->stdp2690_i2c || + !ge_b850v3_lvds_ptr->stdp4028_i2c) goto out; drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge); From fbb88a7c84c1baf6b55f3ecf66a0f1552db3908b Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Fri, 2 Sep 2022 09:30:30 +0800 Subject: [PATCH 227/610] ASoC: rsnd: Add check for rsnd_mod_power_on [ Upstream commit 376be51caf8871419bbcbb755e1e615d30dc3153 ] As rsnd_mod_power_on() can return negative numbers, it should be better to check the return value and deal with the exception. Fixes: e7d850dd10f4 ("ASoC: rsnd: use mod base common method on SSI-parent") Signed-off-by: Jiasheng Jiang Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/20220902013030.3691266-1-jiasheng@iscas.ac.cn Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/sh/rcar/ctu.c | 6 +++++- sound/soc/sh/rcar/dvc.c | 6 +++++- sound/soc/sh/rcar/mix.c | 6 +++++- sound/soc/sh/rcar/src.c | 5 ++++- sound/soc/sh/rcar/ssi.c | 4 +++- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 6156445bcb69..e39eb2ac7e95 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -171,7 +171,11 @@ static int rsnd_ctu_init(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - rsnd_mod_power_on(mod); + int ret; + + ret = rsnd_mod_power_on(mod); + if (ret < 0) + return ret; rsnd_ctu_activation(mod); diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 5137e03a9d7c..16befcbc312c 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -186,7 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - rsnd_mod_power_on(mod); + int ret; + + ret = rsnd_mod_power_on(mod); + if (ret < 0) + return ret; rsnd_dvc_activation(mod); diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 3572c2c5686c..1de0e085804c 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -146,7 +146,11 @@ static int rsnd_mix_init(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { - rsnd_mod_power_on(mod); + int ret; + + ret = rsnd_mod_power_on(mod); + if (ret < 0) + return ret; rsnd_mix_activation(mod); diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 0ea84ae57c6a..f832165e46bc 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -463,11 +463,14 @@ static int rsnd_src_init(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_src *src = rsnd_mod_to_src(mod); + int ret; /* reset sync convert_rate */ src->sync.val = 0; - rsnd_mod_power_on(mod); + ret = rsnd_mod_power_on(mod); + if (ret < 0) + return ret; rsnd_src_activation(mod); diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 43c5e27dc5c8..7ade6c5ed96f 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -480,7 +480,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, ssi->usrcnt++; - rsnd_mod_power_on(mod); + ret = rsnd_mod_power_on(mod); + if (ret < 0) + return ret; rsnd_ssi_config_init(mod, io); From 928ac9fc1ace8a8387bc80b2cd5a525da1516817 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 6 Sep 2022 11:23:06 +0200 Subject: [PATCH 228/610] ALSA: hda: beep: Simplify keep-power-at-enable behavior [ Upstream commit 4c8d695cb9bc5f6fd298a586602947b2fc099a64 ] The recent fix for IDT codecs to keep the power up while the beep is enabled can be better integrated into the beep helper code. This patch cleans up the code with refactoring. Fixes: 414d38ba8710 ("ALSA: hda/sigmatel: Keep power up while beep is enabled") Link: https://lore.kernel.org/r/20220906092306.26183-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/hda_beep.c | 15 +++++++++++++-- sound/pci/hda/hda_beep.h | 1 + sound/pci/hda/patch_sigmatel.c | 25 ++----------------------- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 53a2b89f8983..e63621bcb214 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, return 0; } +static void turn_on_beep(struct hda_beep *beep) +{ + if (beep->keep_power_at_enable) + snd_hda_power_up_pm(beep->codec); +} + static void turn_off_beep(struct hda_beep *beep) { cancel_work_sync(&beep->beep_work); @@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep) /* turn off beep */ generate_tone(beep, 0); } + if (beep->keep_power_at_enable) + snd_hda_power_down_pm(beep->codec); } /** @@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) enable = !!enable; if (beep->enabled != enable) { beep->enabled = enable; - if (!enable) + if (enable) + turn_on_beep(beep); + else turn_off_beep(beep); return 1; } @@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device) input_unregister_device(beep->dev); else input_free_device(beep->dev); - turn_off_beep(beep); + if (beep->enabled) + turn_off_beep(beep); return 0; } diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index a25358a4807a..db76e3ddba65 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h @@ -25,6 +25,7 @@ struct hda_beep { unsigned int enabled:1; unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ unsigned int playing:1; + unsigned int keep_power_at_enable:1; /* set by driver */ struct work_struct beep_work; /* scheduled task for beep event */ struct mutex mutex; void (*power_hook)(struct hda_beep *beep, bool on); diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7f340f18599c..a794a01a68ca 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec) if (codec->beep) { /* IDT/STAC codecs have linear beep tone parameter */ codec->beep->linear_tone = spec->linear_tone_beep; + /* keep power up while beep is enabled */ + codec->beep->keep_power_at_enable = 1; /* if no beep switch is available, make its own one */ caps = query_amp_caps(codec, nid, HDA_OUTPUT); if (!(caps & AC_AMPCAP_MUTE)) { @@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec) return 0; } - -static int stac_check_power_status(struct hda_codec *codec, hda_nid_t nid) -{ -#ifdef CONFIG_SND_HDA_INPUT_BEEP - struct sigmatel_spec *spec = codec->spec; -#endif - int ret = snd_hda_gen_check_power_status(codec, nid); - -#ifdef CONFIG_SND_HDA_INPUT_BEEP - if (nid == spec->gen.beep_nid && codec->beep) { - if (codec->beep->enabled != spec->beep_power_on) { - spec->beep_power_on = codec->beep->enabled; - if (spec->beep_power_on) - snd_hda_power_up_pm(codec); - else - snd_hda_power_down_pm(codec); - } - ret |= spec->beep_power_on; - } -#endif - return ret; -} #else #define stac_suspend NULL #endif /* CONFIG_PM */ @@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = { .unsol_event = snd_hda_jack_unsol_event, #ifdef CONFIG_PM .suspend = stac_suspend, - .check_power_status = stac_check_power_status, #endif }; From f5f599daa0bcb555cb4bc04f7d031a07225b9789 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 6 Sep 2022 16:29:57 +0200 Subject: [PATCH 229/610] drm/bochs: fix blanking [ Upstream commit e740ceb53e4579a7a4063712cebecac3c343b189 ] VGA_IS1_RC is the color mode register (VGA_IS1_RM the one for monochrome mode, note C vs. M at the end). So when using VGA_IS1_RC make sure the vga device is actually in color mode and set the corresponding bit in the misc register. Reproducible when booting VMs in UEFI mode with some edk2 versions (edk2 fix is on the way too). Doesn't happen in BIOS mode because in that case the vgabios already flips the bit. Fixes: 250e743915d4 ("drm/bochs: Add screen blanking support") Signed-off-by: Gerd Hoffmann Acked-by: Thomas Zimmermann Link: http://patchwork.freedesktop.org/patch/msgid/20220906142957.2763577-1-kraxel@redhat.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/tiny/bochs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index 73415fa9ae0f..eb8116ff0d90 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -305,6 +305,8 @@ static void bochs_hw_fini(struct drm_device *dev) static void bochs_hw_blank(struct bochs_device *bochs, bool blank) { DRM_DEBUG_DRIVER("hw_blank %d\n", blank); + /* enable color bit (so VGA_IS1_RC access works) */ + bochs_vga_writeb(bochs, VGA_MIS_W, VGA_MIS_COLOR); /* discard ar_flip_flop */ (void)bochs_vga_readb(bochs, VGA_IS1_RC); /* blank or unblank; we need only update index and set 0x20 */ From a5ce83e85d795ec98697039ecc518b21d5810adc Mon Sep 17 00:00:00 2001 From: Liang He Date: Fri, 22 Jul 2022 22:43:48 +0800 Subject: [PATCH 230/610] drm/omap: dss: Fix refcount leak bugs [ Upstream commit 8b42057e62120813ebe9274f508fa785b7cab33a ] In dss_init_ports() and __dss_uninit_ports(), we should call of_node_put() for the reference returned by of_graph_get_port_by_id() in fail path or when it is not used anymore. Fixes: 09bffa6e5192 ("drm: omap: use common OF graph helpers") Signed-off-by: Liang He Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20220722144348.1306569-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/omapdrm/dss/dss.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index d6a5862b4dbf..7567e2265aa3 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports) default: break; } + of_node_put(port); } } @@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss) default: break; } + of_node_put(port); } return 0; error: + of_node_put(port); __dss_uninit_ports(dss, i); return r; } From 3ba3814c00a4817eb1cd31eff08d921c40e5f3a4 Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Mon, 12 Sep 2022 19:34:32 -0300 Subject: [PATCH 231/610] drm/amdgpu: Fix memory leak in hpd_rx_irq_create_workqueue() [ Upstream commit 7136f956c73c4ba50bfeb61653dfd6a9669ea915 ] If construction of the array of work queues to handle hpd_rx_irq offload work fails, we need to unwind. Destroy all the created workqueues and the allocated memory for the hpd_rx_irq_offload_work_queue struct array. Fixes: 8e794421bc98 ("drm/amd/display: Fork thread to offload work of hpd_rx_irq") Signed-off-by: Rafael Mendonca Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 9b815950b860..484c28919271 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1307,13 +1307,21 @@ static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(struct if (hpd_rx_offload_wq[i].wq == NULL) { DRM_ERROR("create amdgpu_dm_hpd_rx_offload_wq fail!"); - return NULL; + goto out_err; } spin_lock_init(&hpd_rx_offload_wq[i].offload_lock); } return hpd_rx_offload_wq; + +out_err: + for (i = 0; i < max_caps; i++) { + if (hpd_rx_offload_wq[i].wq) + destroy_workqueue(hpd_rx_offload_wq[i].wq); + } + kfree(hpd_rx_offload_wq); + return NULL; } struct amdgpu_stutter_quirk { From 64545b8a969096de1922f120f07ac17d097bfd88 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 25 Aug 2022 09:33:57 +0200 Subject: [PATCH 232/610] mmc: au1xmmc: Fix an error handling path in au1xmmc_probe() [ Upstream commit 5cbedf52608cc3cbc1c2a9a861fb671620427a20 ] If clk_prepare_enable() fails, there is no point in calling clk_disable_unprepare() in the error handling path. Move the out_clk label at the right place. Fixes: b6507596dfd6 ("MIPS: Alchemy: au1xmmc: use clk framework") Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/21d99886d07fa7fcbec74992657dabad98c935c4.1661412818.git.christophe.jaillet@wanadoo.fr Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/au1xmmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 0acc237843f7..f5f9cb7a2da5 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -1095,8 +1095,9 @@ out5: if (host->platdata && host->platdata->cd_setup && !(mmc->caps & MMC_CAP_NEEDS_POLL)) host->platdata->cd_setup(mmc, 0); -out_clk: + clk_disable_unprepare(host->clk); +out_clk: clk_put(host->clk); out_irq: free_irq(host->irq, host); From 4f859884673d0b9e8e9e7ef001c7b9ae7e37f7fd Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 14 Sep 2022 21:43:54 +0800 Subject: [PATCH 233/610] ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API [ Upstream commit bfb735a3ceff0bab6473bac275da96f9b2a06dec ] In eukrea_tlv320_probe(), we need to hold the reference returned from of_find_compatible_node() which has increased the refcount and then call of_node_put() with it when done. Fixes: 66f232908de2 ("ASoC: eukrea-tlv320: Add DT support.") Co-authored-by: Kelin Wang Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220914134354.3995587-1-windhl@126.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/fsl/eukrea-tlv320.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index e13271ea84de..29cf9234984d 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -86,7 +86,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) int ret; int int_port = 0, ext_port; struct device_node *np = pdev->dev.of_node; - struct device_node *ssi_np = NULL, *codec_np = NULL; + struct device_node *ssi_np = NULL, *codec_np = NULL, *tmp_np = NULL; eukrea_tlv320.dev = &pdev->dev; if (np) { @@ -143,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) } if (machine_is_eukrea_cpuimx27() || - of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) { + (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux"))) { imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, IMX_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_TFSDIR | @@ -158,10 +158,11 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) IMX_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) ); + of_node_put(tmp_np); } else if (machine_is_eukrea_cpuimx25sd() || machine_is_eukrea_cpuimx35sd() || machine_is_eukrea_cpuimx51sd() || - of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) { + (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux"))) { if (!np) ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3; @@ -178,6 +179,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) IMX_AUDMUX_V2_PTCR_SYN, IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) ); + of_node_put(tmp_np); } else { if (np) { /* The eukrea,asoc-tlv320 driver was explicitly From 635e7700c5b4ca2baa4ffaa25c8a1e086ede1176 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 15 Jun 2022 15:57:01 +0300 Subject: [PATCH 234/610] drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx [ Upstream commit 7538f80ae0d98bf51eb89eee5344aec219902d42 ] Remove loops over hw_vbif. Instead always VBIF's idx as an index in the array. This fixes an error in dpu_kms_hw_init(), where we fill dpu_kms->hw_vbif[i], but check for an error pointer at dpu_kms->hw_vbif[vbif_idx]. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/489569/ Link: https://lore.kernel.org/r/20220615125703.24647-1-dmitry.baryshkov@linaro.org Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 ++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 29 +++++++++++------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 8b7693883e7c..6d36622977af 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -725,12 +725,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) _dpu_kms_mmu_destroy(dpu_kms); if (dpu_kms->catalog) { - for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { - u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - - if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) { - dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]); - dpu_kms->hw_vbif[vbif_idx] = NULL; + for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { + if (dpu_kms->hw_vbif[i]) { + dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]); + dpu_kms->hw_vbif[i] = NULL; } } } @@ -1049,7 +1047,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx, + dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx, dpu_kms->vbif[vbif_idx], dpu_kms->catalog); if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) { rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c index 21d20373eb8b..a18fb649301c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -11,6 +11,14 @@ #include "dpu_hw_vbif.h" #include "dpu_trace.h" +static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx) +{ + if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif)) + return dpu_kms->hw_vbif[vbif_idx]; + + return NULL; +} + /** * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt * @vbif: Pointer to hardware vbif driver @@ -148,20 +156,15 @@ exit: void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, struct dpu_vbif_set_ot_params *params) { - struct dpu_hw_vbif *vbif = NULL; + struct dpu_hw_vbif *vbif; struct dpu_hw_mdp *mdp; bool forced_on = false; u32 ot_lim; - int ret, i; + int ret; mdp = dpu_kms->hw_mdp; - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) - vbif = dpu_kms->hw_vbif[i]; - } - + vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); if (!vbif || !mdp) { DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n", vbif != NULL, mdp != NULL); @@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, struct dpu_vbif_set_qos_params *params) { - struct dpu_hw_vbif *vbif = NULL; + struct dpu_hw_vbif *vbif; struct dpu_hw_mdp *mdp; bool forced_on = false; const struct dpu_vbif_qos_tbl *qos_tbl; @@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, } mdp = dpu_kms->hw_mdp; - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) { - vbif = dpu_kms->hw_vbif[i]; - break; - } - } + vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); if (!vbif || !vbif->cap) { DPU_ERROR("invalid vbif %d\n", params->vbif_idx); From bdf54d4b00747aa2ddeb4ebc102e9dfdeb07c246 Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Wed, 24 Aug 2022 13:15:50 -0700 Subject: [PATCH 235/610] drm/msm/dp: correct 1.62G link rate at dp_catalog_ctrl_config_msa() [ Upstream commit aa0bff10af1c4b92e6b56e3e1b7f81c660d3ba78 ] At current implementation there is an extra 0 at 1.62G link rate which cause no correct pixel_div selected for 1.62G link rate to calculate mvid and nvid. This patch delete the extra 0 to have mvid and nvid be calculated correctly. Changes in v2: -- fix Fixes tag's text Changes in v3: -- fix misspelling of "Reviewed-by" Fixes: 937f941ca06f ("drm/msm/dp: Use qmp phy for DP PLL and PHY") Signed-off-by: Kuogee Hsieh Reviewed-by: Stephen Boyd Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/499328/ Link: https://lore.kernel.org/r/1661372150-3764-1-git-send-email-quic_khsieh@quicinc.com [DB: rewrapped commit message] Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/dp/dp_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index cc2bb8295329..9ef24ced6586 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -437,7 +437,7 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, if (rate == link_rate_hbr3) pixel_div = 6; - else if (rate == 1620000 || rate == 270000) + else if (rate == 162000 || rate == 270000) pixel_div = 2; else if (rate == link_rate_hbr2) pixel_div = 4; From b47a37ad4a444d82f9caf153a79d090b79786ebb Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Fri, 16 Sep 2022 17:47:51 -0300 Subject: [PATCH 236/610] drm/vmwgfx: Fix memory leak in vmw_mksstat_add_ioctl() [ Upstream commit a40c7f61d12fbd1e785e59140b9efd57127c0c33 ] If the copy of the description string from userspace fails, then the page for the instance descriptor doesn't get freed before returning -EFAULT, which leads to a memleak. Fixes: 7a7a933edd6c ("drm/vmwgfx: Introduce VMware mks-guest-stats") Signed-off-by: Rafael Mendonca Reviewed-by: Martin Krastev Signed-off-by: Zack Rusin Link: https://patchwork.freedesktop.org/patch/msgid/20220916204751.720716-1-rafaelmendsr@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index e50fb82a3030..47eb3a50dd08 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -1076,6 +1076,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, if (desc_len < 0) { atomic_set(&dev_priv->mksstat_user_pids[slot], 0); + __free_page(page); return -EFAULT; } From f910aca076251dbd40ae962b779dfce077b98df5 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 6 Sep 2022 18:01:05 +0100 Subject: [PATCH 237/610] ASoC: codecs: tx-macro: fix kcontrol put [ Upstream commit c1057a08af438e0cf5450c1d977a3011198ed2f8 ] tx_macro_tx_mixer_put() and tx_macro_dec_mode_put() currently returns zero eventhough it changes the value. Fix this, so that change notifications are sent correctly. Fixes: d207bdea0ca9 ("ASoC: codecs: lpass-tx-macro: add dapm widgets and route") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220906170112.1984-6-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/lpass-tx-macro.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index e4bbc6bd4925..feafb8a90ffe 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -815,17 +815,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol, struct tx_macro *tx = snd_soc_component_get_drvdata(component); if (enable) { + if (tx->active_decimator[dai_id] == dec_id) + return 0; + set_bit(dec_id, &tx->active_ch_mask[dai_id]); tx->active_ch_cnt[dai_id]++; tx->active_decimator[dai_id] = dec_id; } else { + if (tx->active_decimator[dai_id] == -1) + return 0; + tx->active_ch_cnt[dai_id]--; clear_bit(dec_id, &tx->active_ch_mask[dai_id]); tx->active_decimator[dai_id] = -1; } snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); - return 0; + return 1; } static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, @@ -1011,9 +1017,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol, int path = e->shift_l; struct tx_macro *tx = snd_soc_component_get_drvdata(component); + if (tx->dec_mode[path] == value) + return 0; + tx->dec_mode[path] = value; - return 0; + return 1; } static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol, From f5f1f5ee5048cfa7bd07f496b33bd2cfc198a176 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 22 Sep 2022 21:44:57 +0200 Subject: [PATCH 238/610] ASoC: da7219: Fix an error handling path in da7219_register_dai_clks() [ Upstream commit abb4e4349afe7eecdb0499582f1c777031e3a7c8 ] If clk_hw_register() fails, the corresponding clk should not be unregistered. To handle errors from loops, clean up partial iterations before doing the goto. So add a clk_hw_unregister(). Then use a while (--i >= 0) loop in the unwind section. Fixes: 78013a1cf297 ("ASoC: da7219: Fix clock handling around codec level probe") Reported-by: Dan Carpenter Signed-off-by: Christophe JAILLET Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/e4acceab57a0d9e477a8d5890a45c5309e553e7c.1663875789.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/da7219.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index c7493549a9a5..da4c24b8dae5 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2196,6 +2196,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) dai_clk_lookup = clkdev_hw_create(dai_clk_hw, init.name, "%s", dev_name(dev)); if (!dai_clk_lookup) { + clk_hw_unregister(dai_clk_hw); ret = -ENOMEM; goto err; } else { @@ -2217,12 +2218,12 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) return 0; err: - do { + while (--i >= 0) { if (da7219->dai_clks_lookup[i]) clkdev_drop(da7219->dai_clks_lookup[i]); clk_hw_unregister(&da7219->dai_clks_hw[i]); - } while (i-- > 0); + } if (np) kfree(da7219->clk_hw_data); From b14dc262274b01880190d8243f28eedab90697e9 Mon Sep 17 00:00:00 2001 From: Andreas Pape Date: Mon, 26 Sep 2022 18:58:13 +0200 Subject: [PATCH 239/610] ALSA: dmaengine: increment buffer pointer atomically [ Upstream commit d1c442019594692c64a70a86ad88eb5b6db92216 ] Setting pointer and afterwards checking for wraparound leads to the possibility of returning the inconsistent pointer position. This patch increments buffer pointer atomically to avoid this issue. Fixes: e7f73a1613567a ("ASoC: Add dmaengine PCM helper functions") Signed-off-by: Andreas Pape Signed-off-by: Eugeniu Rosca Link: https://lore.kernel.org/r/1664211493-11789-1-git-send-email-erosca@de.adit-jv.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/core/pcm_dmaengine.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 1fc2fa077574..0fe93b423c4e 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -132,12 +132,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); static void dmaengine_pcm_dma_complete(void *arg) { + unsigned int new_pos; struct snd_pcm_substream *substream = arg; struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - prtd->pos += snd_pcm_lib_period_bytes(substream); - if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream)) - prtd->pos = 0; + new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream); + if (new_pos >= snd_pcm_lib_buffer_bytes(substream)) + new_pos = 0; + prtd->pos = new_pos; snd_pcm_period_elapsed(substream); } From 3c3ef19a8870da8c845bbe1835eb4b6f6fcf99aa Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 22 Sep 2022 21:06:40 +0200 Subject: [PATCH 240/610] mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe() [ Upstream commit cb58188ad90a61784a56a64f5107faaf2ad323e7 ] A dma_free_coherent() call is missing in the error handling path of the probe, as already done in the remove function. Fixes: 3a96dff0f828 ("mmc: SD/MMC Host Controller for Wondermedia WM8505/WM8650") Signed-off-by: Christophe JAILLET Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/53fc6ffa5d1c428fefeae7d313cf4a669c3a1e98.1663873255.git.christophe.jaillet@wanadoo.fr Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/wmt-sdmmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index cf10949fb0ac..8df722ec57ed 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -849,7 +849,7 @@ static int wmt_mci_probe(struct platform_device *pdev) if (IS_ERR(priv->clk_sdmmc)) { dev_err(&pdev->dev, "Error getting clock\n"); ret = PTR_ERR(priv->clk_sdmmc); - goto fail5; + goto fail5_and_a_half; } ret = clk_prepare_enable(priv->clk_sdmmc); @@ -866,6 +866,9 @@ static int wmt_mci_probe(struct platform_device *pdev) return 0; fail6: clk_put(priv->clk_sdmmc); +fail5_and_a_half: + dma_free_coherent(&pdev->dev, mmc->max_blk_count * 16, + priv->dma_desc_buffer, priv->dma_desc_device_addr); fail5: free_irq(dma_irq, priv); fail4: From b2bc9fc56a3edd9a0cf3918d7555494e09ad698b Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Thu, 29 Sep 2022 00:01:13 +0800 Subject: [PATCH 241/610] ASoC: wm8997: Fix PM disable depth imbalance in wm8997_probe [ Upstream commit 41a736ac20602f64773e80f0f5b32cde1830a44a ] The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm8997_probe Fixes:40843aea5a9bd ("ASoC: wm8997: Initial CODEC driver") Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20220928160116.125020-2-zhangqilong3@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wm8997.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 38ef631d1a1f..c8c711e555c0 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1162,9 +1162,6 @@ static int wm8997_probe(struct platform_device *pdev) regmap_update_bits(arizona->regmap, wm8997_digital_vu[i], WM8997_DIG_VU, WM8997_DIG_VU); - pm_runtime_enable(&pdev->dev); - pm_runtime_idle(&pdev->dev); - arizona_init_common(arizona); ret = arizona_init_vol_limit(arizona); @@ -1183,6 +1180,9 @@ static int wm8997_probe(struct platform_device *pdev) goto err_spk_irqs; } + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + return ret; err_spk_irqs: From b7dda65fa875eac4cd087b78ff679b619184d1c7 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Thu, 29 Sep 2022 00:01:14 +0800 Subject: [PATCH 242/610] ASoC: wm5110: Fix PM disable depth imbalance in wm5110_probe [ Upstream commit 86b46bf1feb83898d89a2b4a8d08d21e9ea277a7 ] The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm5110_probe. Fixes:5c6af635fd772 ("ASoC: wm5110: Add audio CODEC driver") Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20220928160116.125020-3-zhangqilong3@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wm5110.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 7c6e01720d65..66a4827c16bd 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2458,9 +2458,6 @@ static int wm5110_probe(struct platform_device *pdev) regmap_update_bits(arizona->regmap, wm5110_digital_vu[i], WM5110_DIG_VU, WM5110_DIG_VU); - pm_runtime_enable(&pdev->dev); - pm_runtime_idle(&pdev->dev); - ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, "ADSP2 Compressed IRQ", wm5110_adsp2_irq, wm5110); @@ -2493,6 +2490,9 @@ static int wm5110_probe(struct platform_device *pdev) goto err_spk_irqs; } + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + return ret; err_spk_irqs: From f9cb3bd55726ca703913e924f3763fad5d77c588 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Thu, 29 Sep 2022 00:01:15 +0800 Subject: [PATCH 243/610] ASoC: wm5102: Fix PM disable depth imbalance in wm5102_probe [ Upstream commit fcbb60820cd3008bb44334a0395e5e57ccb77329 ] The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm5102_probe. Fixes:93e8791dd34ca ("ASoC: wm5102: Initial driver") Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20220928160116.125020-4-zhangqilong3@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/wm5102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 621598608bf0..c8adce8936bc 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2087,9 +2087,6 @@ static int wm5102_probe(struct platform_device *pdev) regmap_update_bits(arizona->regmap, wm5102_digital_vu[i], WM5102_DIG_VU, WM5102_DIG_VU); - pm_runtime_enable(&pdev->dev); - pm_runtime_idle(&pdev->dev); - ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, "ADSP2 Compressed IRQ", wm5102_adsp2_irq, wm5102); @@ -2122,6 +2119,9 @@ static int wm5102_probe(struct platform_device *pdev) goto err_spk_irqs; } + pm_runtime_enable(&pdev->dev); + pm_runtime_idle(&pdev->dev); + return ret; err_spk_irqs: From cc756b79a5c9c1076e3987f2d6d739545656bc48 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Thu, 29 Sep 2022 00:01:16 +0800 Subject: [PATCH 244/610] ASoC: mt6660: Fix PM disable depth imbalance in mt6660_i2c_probe [ Upstream commit b73f11e895e140537e7f8c7251211ccd3ce0782b ] The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of mt6660_i2c_probe. Fixes:f289e55c6eeb4 ("ASoC: Add MediaTek MT6660 Speaker Amp Driver") Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20220928160116.125020-5-zhangqilong3@huawei.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/mt6660.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c index 358c500377df..a0a3fd60e93a 100644 --- a/sound/soc/codecs/mt6660.c +++ b/sound/soc/codecs/mt6660.c @@ -504,13 +504,17 @@ static int mt6660_i2c_probe(struct i2c_client *client, dev_err(chip->dev, "read chip revision fail\n"); goto probe_fail; } - pm_runtime_set_active(chip->dev); - pm_runtime_enable(chip->dev); ret = devm_snd_soc_register_component(chip->dev, &mt6660_component_driver, &mt6660_codec_dai, 1); + if (!ret) { + pm_runtime_set_active(chip->dev); + pm_runtime_enable(chip->dev); + } + return ret; + probe_fail: _mt6660_chip_power_on(chip, 0); mutex_destroy(&chip->io_lock); From 10df962300c2d7b29e69a4d7ec6380d5c730409e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 1 Oct 2022 09:48:10 +0200 Subject: [PATCH 245/610] ALSA: hda/hdmi: Don't skip notification handling during PM operation [ Upstream commit 5226c7b9784eee215e3914f440b3c2e1764f67a8 ] The HDMI driver skips the notification handling from the graphics driver when the codec driver is being in the PM operation. This behavior was introduced by the commit eb399d3c99d8 ("ALSA: hda - Skip ELD notification during PM process"). This skip may cause a problem, as we may miss the ELD update when the connection/disconnection happens right at the runtime-PM operation of the audio codec. Although this workaround was valid at that time, it's no longer true; the fix was required just because the ELD update procedure needed to wake up the audio codec, which had lead to a runtime-resume during a runtime-suspend. Meanwhile, the ELD update procedure doesn't need a codec wake up any longer since the commit 788d441a164c ("ALSA: hda - Use component ops for i915 HDMI/DP audio jack handling"); i.e. there is no much reason for skipping the notification. Let's drop those checks for addressing the missing notification. Fixes: 788d441a164c ("ALSA: hda - Use component ops for i915 HDMI/DP audio jack handling") Reported-by: Brent Lu Link: https://lore.kernel.org/r/20220927135807.4097052-1-brent.lu@intel.com Link: https://lore.kernel.org/r/20221001074809.7461-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/patch_hdmi.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 1994a83fa391..ba1289abd45f 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2685,9 +2685,6 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id) */ if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) return; - /* ditto during suspend/resume process itself */ - if (snd_hdac_is_in_pm(&codec->core)) - return; check_presence_and_report(codec, pin_nid, dev_id); } @@ -2871,9 +2868,6 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) */ if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) return; - /* ditto during suspend/resume process itself */ - if (snd_hdac_is_in_pm(&codec->core)) - return; snd_hdac_i915_set_bclk(&codec->bus->core); check_presence_and_report(codec, pin_nid, dev_id); From 566b143aa5112a0c2784e20603778518bb799537 Mon Sep 17 00:00:00 2001 From: Liang He Date: Sat, 16 Jul 2022 11:13:24 +0800 Subject: [PATCH 246/610] memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe() [ Upstream commit 61b3c876c1cbdb1efd1f52a1f348580e6e14efb6 ] The break of for_each_available_child_of_node() needs a corresponding of_node_put() when the reference 'child' is not used anymore. Here we do not need to call of_node_put() in fail path as '!match' means no break. While the of_platform_device_create() will created a new reference by 'child' but it has considered the refcounting. Fixes: fee10bd22678 ("memory: pl353: Add driver for arm pl353 static memory controller") Signed-off-by: Liang He Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220716031324.447680-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/memory/pl353-smc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c index f84b98278745..d39ee7d06665 100644 --- a/drivers/memory/pl353-smc.c +++ b/drivers/memory/pl353-smc.c @@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) } of_platform_device_create(child, NULL, &adev->dev); + of_node_put(child); return 0; From 2680690f9ce4e6abbb4f559e97271c15b7eeda97 Mon Sep 17 00:00:00 2001 From: Liang He Date: Tue, 19 Jul 2022 16:56:39 +0800 Subject: [PATCH 247/610] memory: of: Fix refcount leak bug in of_get_ddr_timings() [ Upstream commit 05215fb32010d4afb68fbdbb4d237df6e2d4567b ] We should add the of_node_put() when breaking out of for_each_child_of_node() as it will automatically increase and decrease the refcount. Fixes: e6b42eb6a66c ("memory: emif: add device tree support to emif driver") Signed-off-by: Liang He Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220719085640.1210583-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/memory/of_memory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c index d9f5437d3bce..d0a80aefdea8 100644 --- a/drivers/memory/of_memory.c +++ b/drivers/memory/of_memory.c @@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr, for_each_child_of_node(np_ddr, np_tim) { if (of_device_is_compatible(np_tim, tim_compat)) { if (of_do_get_timings(np_tim, &timings[i])) { + of_node_put(np_tim); devm_kfree(dev, timings); goto default_timings; } From 7e053784c4c70df28324106d476778be7a4519b3 Mon Sep 17 00:00:00 2001 From: Liang He Date: Tue, 19 Jul 2022 16:56:40 +0800 Subject: [PATCH 248/610] memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings() [ Upstream commit 48af14fb0eaa63d9aa68f59fb0b205ec55a95636 ] We should add the of_node_put() when breaking out of for_each_child_of_node() as it will automatically increase and decrease the refcount. Fixes: 976897dd96db ("memory: Extend of_memory with LPDDR3 support") Signed-off-by: Liang He Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220719085640.1210583-2-windhl@126.com Signed-off-by: Sasha Levin --- drivers/memory/of_memory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c index d0a80aefdea8..1791614f324b 100644 --- a/drivers/memory/of_memory.c +++ b/drivers/memory/of_memory.c @@ -283,6 +283,7 @@ const struct lpddr3_timings if (of_device_is_compatible(np_tim, tim_compat)) { if (of_lpddr3_do_get_timings(np_tim, &timings[i])) { devm_kfree(dev, timings); + of_node_put(np_tim); goto default_timings; } i++; From a29b6eb959bd5c3cbb2dd0ed7c982a10c93734d4 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Tue, 16 Aug 2022 17:53:17 +0300 Subject: [PATCH 249/610] locks: fix TOCTOU race when granting write lease [ Upstream commit d6da19c9cace63290ccfccb1fc35151ffefc0bec ] Thread A trying to acquire a write lease checks the value of i_readcount and i_writecount in check_conflicting_open() to verify that its own fd is the only fd referencing the file. Thread B trying to open the file for read will call break_lease() in do_dentry_open() before incrementing i_readcount, which leaves a small window where thread A can acquire the write lease and then thread B completes the open of the file for read without breaking the write lease that was acquired by thread A. Fix this race by incrementing i_readcount before checking for existing leases, same as the case with i_writecount. Use a helper put_file_access() to decrement i_readcount or i_writecount in do_dentry_open() and __fput(). Fixes: 387e3746d01c ("locks: eliminate false positive conflicts for write lease") Reviewed-by: Jeff Layton Signed-off-by: Amir Goldstein Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/file_table.c | 7 +------ fs/internal.h | 10 ++++++++++ fs/open.c | 11 ++++------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index e8c9016703ad..6f297f9782fc 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -284,12 +284,7 @@ static void __fput(struct file *file) } fops_put(file->f_op); put_pid(file->f_owner.pid); - if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) - i_readcount_dec(inode); - if (mode & FMODE_WRITER) { - put_write_access(inode); - __mnt_drop_write(mnt); - } + put_file_access(file); dput(dentry); if (unlikely(mode & FMODE_NEED_UNMOUNT)) dissolve_on_fput(mnt); diff --git a/fs/internal.h b/fs/internal.h index 4f1fe6d08866..9075490f21a6 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -100,6 +100,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *); extern struct file *alloc_empty_file(int, const struct cred *); extern struct file *alloc_empty_file_noaccount(int, const struct cred *); +static inline void put_file_access(struct file *file) +{ + if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { + i_readcount_dec(file->f_inode); + } else if (file->f_mode & FMODE_WRITER) { + put_write_access(file->f_inode); + __mnt_drop_write(file->f_path.mnt); + } +} + /* * super.c */ diff --git a/fs/open.c b/fs/open.c index 1ba1d2ab2ef0..5e322f188e83 100644 --- a/fs/open.c +++ b/fs/open.c @@ -786,7 +786,9 @@ static int do_dentry_open(struct file *f, return 0; } - if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { + if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { + i_readcount_inc(inode); + } else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { error = get_write_access(inode); if (unlikely(error)) goto cleanup_file; @@ -826,8 +828,6 @@ static int do_dentry_open(struct file *f, goto cleanup_all; } f->f_mode |= FMODE_OPENED; - if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) - i_readcount_inc(inode); if ((f->f_mode & FMODE_READ) && likely(f->f_op->read || f->f_op->read_iter)) f->f_mode |= FMODE_CAN_READ; @@ -880,10 +880,7 @@ cleanup_all: if (WARN_ON_ONCE(error > 0)) error = -EINVAL; fops_put(f->f_op); - if (f->f_mode & FMODE_WRITER) { - put_write_access(inode); - __mnt_drop_write(f->f_path.mnt); - } + put_file_access(f); cleanup_file: path_put(&f->f_path); f->f_path.mnt = NULL; From 96e0028debdd07a6d582f0dfadf9a3ec2b5fffff Mon Sep 17 00:00:00 2001 From: Liang He Date: Thu, 21 Jul 2022 21:52:16 +0800 Subject: [PATCH 250/610] soc: qcom: smsm: Fix refcount leak bugs in qcom_smsm_probe() [ Upstream commit af8f6f39b8afd772fda4f8e61823ef8c021bf382 ] There are two refcount leak bugs in qcom_smsm_probe(): (1) The 'local_node' is escaped out from for_each_child_of_node() as the break of iteration, we should call of_node_put() for it in error path or when it is not used anymore. (2) The 'node' is escaped out from for_each_available_child_of_node() as the 'goto', we should call of_node_put() for it in goto target. Fixes: c97c4090ff72 ("soc: qcom: smsm: Add driver for Qualcomm SMSM") Signed-off-by: Liang He Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220721135217.1301039-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/soc/qcom/smsm.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index 9df9bba242f3..3e8994d6110e 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -526,7 +526,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) for (id = 0; id < smsm->num_hosts; id++) { ret = smsm_parse_ipc(smsm, id); if (ret < 0) - return ret; + goto out_put; } /* Acquire the main SMSM state vector */ @@ -534,13 +534,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) smsm->num_entries * sizeof(u32)); if (ret < 0 && ret != -EEXIST) { dev_err(&pdev->dev, "unable to allocate shared state entry\n"); - return ret; + goto out_put; } states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); if (IS_ERR(states)) { dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); - return PTR_ERR(states); + ret = PTR_ERR(states); + goto out_put; } /* Acquire the list of interrupt mask vectors */ @@ -548,13 +549,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size); if (ret < 0 && ret != -EEXIST) { dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n"); - return ret; + goto out_put; } intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); if (IS_ERR(intr_mask)) { dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); - return PTR_ERR(intr_mask); + ret = PTR_ERR(intr_mask); + goto out_put; } /* Setup the reference to the local state bits */ @@ -565,7 +567,8 @@ static int qcom_smsm_probe(struct platform_device *pdev) smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm); if (IS_ERR(smsm->state)) { dev_err(smsm->dev, "failed to register qcom_smem_state\n"); - return PTR_ERR(smsm->state); + ret = PTR_ERR(smsm->state); + goto out_put; } /* Register handlers for remote processor entries of interest. */ @@ -595,16 +598,19 @@ static int qcom_smsm_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, smsm); + of_node_put(local_node); return 0; unwind_interfaces: + of_node_put(node); for (id = 0; id < smsm->num_entries; id++) if (smsm->entries[id].domain) irq_domain_remove(smsm->entries[id].domain); qcom_smem_state_unregister(smsm->state); - +out_put: + of_node_put(local_node); return ret; } From 08ada28d1defedea0398f757687d4153a7f40d1a Mon Sep 17 00:00:00 2001 From: Liang He Date: Thu, 21 Jul 2022 21:52:17 +0800 Subject: [PATCH 251/610] soc: qcom: smem_state: Add refcounting for the 'state->of_node' [ Upstream commit 90681f53b9381c23ff7762a3b13826d620c272de ] In qcom_smem_state_register() and qcom_smem_state_release(), we should better use of_node_get() and of_node_put() for the reference creation and destruction of 'device_node'. Fixes: 9460ae2ff308 ("soc: qcom: Introduce common SMEM state machine code") Signed-off-by: Liang He Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220721135217.1301039-2-windhl@126.com Signed-off-by: Sasha Levin --- drivers/soc/qcom/smem_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c index 31faf4aa868e..e848cc9a3cf8 100644 --- a/drivers/soc/qcom/smem_state.c +++ b/drivers/soc/qcom/smem_state.c @@ -136,6 +136,7 @@ static void qcom_smem_state_release(struct kref *ref) struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount); list_del(&state->list); + of_node_put(state->of_node); kfree(state); } @@ -205,7 +206,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, kref_init(&state->refcount); - state->of_node = of_node; + state->of_node = of_node_get(of_node); state->ops = *ops; state->priv = priv; From 96d8f2b43e7290ca7b376f4050a0618a2bf07895 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Tue, 26 Jul 2022 15:05:23 +0200 Subject: [PATCH 252/610] ARM: dts: imx6qdl-kontron-samx6i: hook up DDC i2c bus [ Upstream commit afd8f77957e3e83adf21d9229c61ff37f44a177a ] i2c2 is routed to the pins dedicated as DDC in the module standard. Reduce clock rate to 100kHz to be in line with VESA standard and hook this bus up to the HDMI node. Fixes: 708ed2649ad8 ("ARM: dts: imx6qdl-kontron-samx6i: increase i2c-frequency") Signed-off-by: Lucas Stach [m.felsch@pengutronix.de: add fixes line] Signed-off-by: Marco Felsch Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi index 6b791d515e29..683f6e58ab23 100644 --- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi @@ -263,6 +263,10 @@ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; }; +&hdmi { + ddc-i2c-bus = <&i2c2>; +}; + &i2c_intern { pmic@8 { compatible = "fsl,pfuze100"; @@ -387,7 +391,7 @@ /* HDMI_CTRL */ &i2c2 { - clock-frequency = <375000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; }; From 42ce4c73a468724fee53ff24e51d8ee97ee916e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 27 Jul 2022 14:56:10 +0200 Subject: [PATCH 253/610] ARM: dts: turris-omnia: Fix mpp26 pin name and comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 49e93898f0dc177e645c22d0664813567fd9ec00 ] There is a bug in Turris Omnia's schematics, whereupon the MPP[26] pin, which is routed to CN11 pin header, is documented as SPI CS1, but MPP[26] pin does not support this function. Instead it controls chip select 2 if in "spi0" mode. Fix the name of the pin node in pinctrl node and fix the comment in SPI node. Fixes: 26ca8b52d6e1 ("ARM: dts: add support for Turris Omnia") Signed-off-by: Marek Behún Signed-off-by: Gregory CLEMENT Signed-off-by: Sasha Levin --- arch/arm/boot/dts/armada-385-turris-omnia.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts index 5bd6a66d2c2b..01b0dfd55d70 100644 --- a/arch/arm/boot/dts/armada-385-turris-omnia.dts +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts @@ -471,7 +471,7 @@ marvell,function = "spi0"; }; - spi0cs1_pins: spi0cs1-pins { + spi0cs2_pins: spi0cs2-pins { marvell,pins = "mpp26"; marvell,function = "spi0"; }; @@ -506,7 +506,7 @@ }; }; - /* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */ + /* MISO, MOSI, SCLK and CS2 are routed to pin header CN11 */ }; &uart0 { From bf7caa3c5caf3a9f1fe05bfc3d76b5dbe1c3955a Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 16 Aug 2022 02:10:24 +0200 Subject: [PATCH 254/610] ARM: dts: kirkwood: lsxl: fix serial line [ Upstream commit 04eabc6ac10fda9424606d9a7ab6ab9a5d95350a ] Commit 327e15428977 ("ARM: dts: kirkwood: consolidate common pinctrl settings") unknowingly broke the serial output on this board. Before this commit, the pinmux was still configured by the bootloader and the kernel didn't reconfigured it again. This was an oversight by the initial board support where the pinmux for the serial line was never configured by the kernel. But with this commit, the serial line will be reconfigured to the wrong pins. This is especially confusing, because the output still works, but the input doesn't. Presumingly, the input is reconfigured to MPP10, but the output is connected to both MPP11 and MPP5. Override the pinmux in the board device tree. Fixes: 327e15428977 ("ARM: dts: kirkwood: consolidate common pinctrl settings") Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT Signed-off-by: Sasha Levin --- arch/arm/boot/dts/kirkwood-lsxl.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi index 7b151acb9984..321a40a98ed2 100644 --- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi +++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi @@ -10,6 +10,11 @@ ocp@f1000000 { pinctrl: pin-controller@10000 { + /* Non-default UART pins */ + pmx_uart0: pmx-uart0 { + marvell,pins = "mpp4", "mpp5"; + }; + pmx_power_hdd: pmx-power-hdd { marvell,pins = "mpp10"; marvell,function = "gpo"; From 2ef01657b2d691545b051c8f5683c69e8be0b513 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 16 Aug 2022 02:10:25 +0200 Subject: [PATCH 255/610] ARM: dts: kirkwood: lsxl: remove first ethernet port [ Upstream commit 2d528eda7c96ce5c70f895854ecd5684bd5d80b9 ] Both the Linkstation LS-CHLv2 and the LS-XHL have only one ethernet port. This has always been wrong, i.e. the board code used to set up both ports, but the driver will play nice and return -ENODEV if the assiciated PHY is not found. Nevertheless, it is wrong. Remove it. Fixes: 876e23333511 ("ARM: kirkwood: add gigabit ethernet and mvmdio device tree nodes") Signed-off-by: Michael Walle Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT Signed-off-by: Sasha Levin --- arch/arm/boot/dts/kirkwood-lsxl.dtsi | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi index 321a40a98ed2..88b70ba1c8fe 100644 --- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi +++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi @@ -218,22 +218,11 @@ &mdio { status = "okay"; - ethphy0: ethernet-phy@0 { - reg = <0>; - }; - ethphy1: ethernet-phy@8 { reg = <8>; }; }; -ð0 { - status = "okay"; - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; - ð1 { status = "okay"; ethernet1-port@0 { From 4f7892f2428179183b918322c930a87d61976ee3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 10 Sep 2022 18:26:16 -0700 Subject: [PATCH 256/610] ia64: export memory_add_physaddr_to_nid to fix cxl build error [ Upstream commit 97c318bfbe84efded246e80428054f300042f110 ] cxl_pmem.ko uses memory_add_physaddr_to_nid() but ia64 does not export it, so this causes a build error: ERROR: modpost: "memory_add_physaddr_to_nid" [drivers/cxl/cxl_pmem.ko] undefined! Fix this by exporting that function. Fixes: 8c2676a5870a ("hot-add-mem x86_64: memory_add_physaddr_to_nid node fixup") Reported-by: kernel test robot Signed-off-by: Randy Dunlap Cc: Dan Williams Cc: Ben Widawsky Cc: Jonathan Cameron Cc: linux-ia64@vger.kernel.org Cc: Arnd Bergmann Cc: Keith Mannthey Cc: Andrew Morton Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- arch/ia64/mm/numa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c index d6579ec3ea32..4c7b1f50e3b7 100644 --- a/arch/ia64/mm/numa.c +++ b/arch/ia64/mm/numa.c @@ -75,5 +75,6 @@ int memory_add_physaddr_to_nid(u64 addr) return 0; return nid; } +EXPORT_SYMBOL(memory_add_physaddr_to_nid); #endif #endif From 7247a1d7a46ae9dbb12fd82947ae6497824a38d4 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 23 Sep 2020 03:34:21 +0300 Subject: [PATCH 257/610] soc/tegra: fuse: Drop Kconfig dependency on TEGRA20_APB_DMA [ Upstream commit 2254182807fc09ba9dec9a42ef239e373796f1b2 ] The DMA subsystem could be entirely disabled in Kconfig and then the TEGRA20_APB_DMA option isn't available too. Hence kernel configuration fails if DMADEVICES Kconfig option is disabled due to the unsatisfiable dependency. The FUSE driver isn't a critical driver and currently it only provides NVMEM interface to userspace which isn't known to be widely used, and thus, it's fine if FUSE driver fails to load. Let's remove the erroneous Kconfig dependency and let the FUSE driver to fail the probing if DMA is unavailable. Fixes: 19d41e5e9c68 ("soc/tegra: fuse: Add APB DMA dependency for Tegra20") Reported-by: Necip Fazil Yildiran Link: https://bugzilla.kernel.org/show_bug.cgi?id=209301 Signed-off-by: Dmitry Osipenko Signed-off-by: Sasha Levin --- drivers/soc/tegra/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig index 8b53ed1cc67e..1224e1c8c2c9 100644 --- a/drivers/soc/tegra/Kconfig +++ b/drivers/soc/tegra/Kconfig @@ -136,7 +136,6 @@ config SOC_TEGRA_FUSE def_bool y depends on ARCH_TEGRA select SOC_BUS - select TEGRA20_APB_DMA if ARCH_TEGRA_2x_SOC config SOC_TEGRA_FLOWCTRL bool From 2134214bc4030a109ce6c107bf895ca1229d913b Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Mon, 19 Sep 2022 13:57:23 -0700 Subject: [PATCH 258/610] arm64: dts: ti: k3-j7200: fix main pinmux range [ Upstream commit 0d0a0b4413460383331088b2203ba09a6971bc3a ] Range size of 0x2b4 was incorrect since there isn't 173 configurable pins for muxing. Additionally there is a non-addressable region in the mapping which requires splitting into two ranges. main_pmx0 -> 67 pins main_pmx1 -> 3 pins Fixes: d361ed88455f ("arm64: dts: ti: Add support for J7200 SoC") Signed-off-by: Matt Ranostay Signed-off-by: Vignesh Raghavendra Tested-by: Vaishnav Achath Link: https://lore.kernel.org/r/20220919205723.8342-1-mranostay@ti.com Signed-off-by: Sasha Levin --- .../boot/dts/ti/k3-j7200-common-proc-board.dts | 14 ++++++++------ arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 11 ++++++++++- 2 files changed, 18 insertions(+), 7 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 d14f3c18b65f..c3406e7f10a9 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 @@ -131,12 +131,6 @@ >; }; - main_usbss0_pins_default: main-usbss0-pins-default { - pinctrl-single,pins = < - J721E_IOPAD(0x120, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ - >; - }; - vdd_sd_dv_pins_default: vdd-sd-dv-pins-default { pinctrl-single,pins = < J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */ @@ -144,6 +138,14 @@ }; }; +&main_pmx1 { + main_usbss0_pins_default: main-usbss0-pins-default { + pinctrl-single,pins = < + J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ + >; + }; +}; + &wkup_uart0 { /* Wakeup UART is used by System firmware */ status = "reserved"; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi index 000b5732ea0c..b1df17525dea 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi @@ -295,7 +295,16 @@ main_pmx0: pinctrl@11c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ - reg = <0x00 0x11c000 0x00 0x2b4>; + reg = <0x00 0x11c000 0x00 0x10c>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + main_pmx1: pinctrl@11c11c { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x11c11c 0x00 0xc>; #pinctrl-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xffffffff>; From 2af04fe87ea5d1f5e9cb4ebe2aa5950c90c2f402 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 26 Sep 2022 12:43:53 +0200 Subject: [PATCH 259/610] ARM: dts: exynos: correct s5k6a3 reset polarity on Midas family [ Upstream commit 3ba2d4bb9592bf7a6a3fe3dbe711ecfc3d004bab ] According to s5k6a3 driver code, the reset line for the chip appears to be active low. This also matches the typical polarity of reset lines in general. Let's fix it up as having correct polarity in DTS is important when the driver will be switched over to gpiod API. Fixes: b4fec64758ab ("ARM: dts: Add camera device nodes for Exynos4412 TRATS2 board") Signed-off-by: Dmitry Torokhov Signed-off-by: Krzysztof Kozlowski Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20220913164104.203957-1-dmitry.torokhov@gmail.com Link: https://lore.kernel.org/r/20220926104354.118578-2-krzysztof.kozlowski@linaro.org' Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- arch/arm/boot/dts/exynos4412-midas.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi index 968c7943653e..49843e016828 100644 --- a/arch/arm/boot/dts/exynos4412-midas.dtsi +++ b/arch/arm/boot/dts/exynos4412-midas.dtsi @@ -585,7 +585,7 @@ clocks = <&camera 1>; clock-names = "extclk"; samsung,camclk-out = <1>; - gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>; + gpios = <&gpm1 6 GPIO_ACTIVE_LOW>; port { is_s5k6a3_ep: endpoint { From 7a00a23207526c79bfaaf3b06411c4e3b1742902 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 27 Sep 2022 15:28:26 +0200 Subject: [PATCH 260/610] ARM: Drop CMDLINE_* dependency on ATAGS [ Upstream commit 136f4b1ec7c962ee37a787e095fd37b058d72bd3 ] On arm32, the configuration options to specify the kernel command line type depend on ATAGS. However, the actual CMDLINE cofiguration option does not depend on ATAGS, and the code that handles this is not specific to ATAGS (see drivers/of/fdt.c:early_init_dt_scan_chosen()). Hence users who desire to override the kernel command line on arm32 must enable support for ATAGS, even on a pure-DT system. Other architectures (arm64, loongarch, microblaze, nios2, powerpc, and riscv) do not impose such a restriction. Hence drop the dependency on ATAGS. Fixes: bd51e2f595580fb6 ("ARM: 7506/1: allow for ATAGS to be configured out when DT support is selected") Signed-off-by: Geert Uytterhoeven Acked-by: Ard Biesheuvel Signed-off-by: Arnd Bergmann Signed-off-by: Sasha Levin --- arch/arm/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4ebd512043be..a8ae17f5740d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1741,7 +1741,6 @@ config CMDLINE choice prompt "Kernel command line type" if CMDLINE != "" default CMDLINE_FROM_BOOTLOADER - depends on ATAGS config CMDLINE_FROM_BOOTLOADER bool "Use bootloader kernel arguments if available" From bbf64eb1027309ed58080bc30fd37116da7c36cc Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 31 Jul 2022 20:24:53 -0700 Subject: [PATCH 261/610] ext4: don't run ext4lazyinit for read-only filesystems [ Upstream commit 426d15ad11419066f7042ffa8fbf1b5c21a1ecbe ] On a read-only filesystem, we won't invoke the block allocator, so we don't need to prefetch the block bitmaps. This avoids starting and running the ext4lazyinit thread at all on a system with no read-write ext4 filesystems (for instance, a container VM with read-only filesystems underneath an overlayfs). Fixes: 21175ca434c5 ("ext4: make prefetch_block_bitmaps default") Signed-off-by: Josh Triplett Reviewed-by: Lukas Czerner Link: https://lore.kernel.org/r/48b41da1498fcac3287e2e06b660680646c1c050.1659323972.git.josh@joshtriplett.org Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index eec41990fa65..985d79fb6128 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3587,9 +3587,9 @@ int ext4_register_li_request(struct super_block *sb, goto out; } - if (test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS) && - (first_not_zeroed == ngroups || sb_rdonly(sb) || - !test_opt(sb, INIT_INODE_TABLE))) + if (sb_rdonly(sb) || + (test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS) && + (first_not_zeroed == ngroups || !test_opt(sb, INIT_INODE_TABLE)))) goto out; elr = ext4_li_request_new(sb, first_not_zeroed); From 6c93b683cedaef745884cb9d554d02ed6266b897 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 29 Sep 2022 14:45:25 +0100 Subject: [PATCH 262/610] arm64: ftrace: fix module PLTs with mcount [ Upstream commit 8cfb08575c6d4585f1ce0deeb189e5c824776b04 ] Li Huafei reports that mcount-based ftrace with module PLTs was broken by commit: a6253579977e4c6f ("arm64: ftrace: consistently handle PLTs.") When a module PLTs are used and a module is loaded sufficiently far away from the kernel, we'll create PLTs for any branches which are out-of-range. These are separate from the special ftrace trampoline PLTs, which the module PLT code doesn't directly manipulate. When mcount is in use this is a problem, as each mcount callsite in a module will be initialized to point to a module PLT, but since commit a6253579977e4c6f ftrace_make_nop() will assume that the callsite has been initialized to point to the special ftrace trampoline PLT, and ftrace_find_callable_addr() rejects other cases. This means that when ftrace tries to initialize a callsite via ftrace_make_nop(), the call to ftrace_find_callable_addr() will find that the `_mcount` stub is out-of-range and is not handled by the ftrace PLT, resulting in a splat: | ftrace_test: loading out-of-tree module taints kernel. | ftrace: no module PLT for _mcount | ------------[ ftrace bug ]------------ | ftrace failed to modify | [] 0xffff800029180014 | actual: 44:00:00:94 | Initializing ftrace call sites | ftrace record flags: 2000000 | (0) | expected tramp: ffff80000802eb3c | ------------[ cut here ]------------ | WARNING: CPU: 3 PID: 157 at kernel/trace/ftrace.c:2120 ftrace_bug+0x94/0x270 | Modules linked in: | CPU: 3 PID: 157 Comm: insmod Tainted: G O 6.0.0-rc6-00151-gcd722513a189-dirty #22 | Hardware name: linux,dummy-virt (DT) | pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : ftrace_bug+0x94/0x270 | lr : ftrace_bug+0x21c/0x270 | sp : ffff80000b2bbaf0 | x29: ffff80000b2bbaf0 x28: 0000000000000000 x27: ffff0000c4d38000 | x26: 0000000000000001 x25: ffff800009d7e000 x24: ffff0000c4d86e00 | x23: 0000000002000000 x22: ffff80000a62b000 x21: ffff8000098ebea8 | x20: ffff0000c4d38000 x19: ffff80000aa24158 x18: ffffffffffffffff | x17: 0000000000000000 x16: 0a0d2d2d2d2d2d2d x15: ffff800009aa9118 | x14: 0000000000000000 x13: 6333626532303830 x12: 3030303866666666 | x11: 203a706d61727420 x10: 6465746365707865 x9 : 3362653230383030 | x8 : c0000000ffffefff x7 : 0000000000017fe8 x6 : 000000000000bff4 | x5 : 0000000000057fa8 x4 : 0000000000000000 x3 : 0000000000000001 | x2 : ad2cb14bb5438900 x1 : 0000000000000000 x0 : 0000000000000022 | Call trace: | ftrace_bug+0x94/0x270 | ftrace_process_locs+0x308/0x430 | ftrace_module_init+0x44/0x60 | load_module+0x15b4/0x1ce8 | __do_sys_init_module+0x1ec/0x238 | __arm64_sys_init_module+0x24/0x30 | invoke_syscall+0x54/0x118 | el0_svc_common.constprop.4+0x84/0x100 | do_el0_svc+0x3c/0xd0 | el0_svc+0x1c/0x50 | el0t_64_sync_handler+0x90/0xb8 | el0t_64_sync+0x15c/0x160 | ---[ end trace 0000000000000000 ]--- | ---------test_init----------- Fix this by reverting to the old behaviour of ignoring the old instruction when initialising an mcount callsite in a module, which was the behaviour prior to commit a6253579977e4c6f. Signed-off-by: Mark Rutland Fixes: a6253579977e ("arm64: ftrace: consistently handle PLTs.") Reported-by: Li Huafei Link: https://lore.kernel.org/linux-arm-kernel/20220929094134.99512-1-lihuafei1@huawei.com Cc: Ard Biesheuvel Cc: Will Deacon Link: https://lore.kernel.org/r/20220929134525.798593-1-mark.rutland@arm.com Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/kernel/ftrace.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c index ae0248154981..dba774f3b8d7 100644 --- a/arch/arm64/kernel/ftrace.c +++ b/arch/arm64/kernel/ftrace.c @@ -217,11 +217,26 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long pc = rec->ip; u32 old = 0, new; + new = aarch64_insn_gen_nop(); + + /* + * When using mcount, callsites in modules may have been initalized to + * call an arbitrary module PLT (which redirects to the _mcount stub) + * rather than the ftrace PLT we'll use at runtime (which redirects to + * the ftrace trampoline). We can ignore the old PLT when initializing + * the callsite. + * + * Note: 'mod' is only set at module load time. + */ + if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) && + IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && mod) { + return aarch64_insn_patch_text_nosync((void *)pc, new); + } + if (!ftrace_find_callable_addr(rec, mod, &addr)) return -EINVAL; old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); - new = aarch64_insn_gen_nop(); return ftrace_modify_code(pc, old, new, true); } From 017cf3b0a628653359f8602d62fe3a9e5b00d5bf Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 27 Sep 2022 15:05:03 -0700 Subject: [PATCH 263/610] ARM: dts: exynos: fix polarity of VBUS GPIO of Origen [ Upstream commit a08137bd1e0a7ce951dce9ce4a83e39d379b6e1b ] EHCI Oxynos (drivers/usb/host/ehci-exynos.c) drives VBUS GPIO high when trying to power up the bus, therefore the GPIO in DTS must be marked as "active high". This will be important when EHCI driver is converted to gpiod API that respects declared polarities. Fixes: 4e8991def565 ("ARM: dts: exynos: Enable AX88760 USB hub on Origen board") Signed-off-by: Dmitry Torokhov Link: https://lore.kernel.org/r/20220927220504.3744878-1-dmitry.torokhov@gmail.com Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin --- arch/arm/boot/dts/exynos4412-origen.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 5479ef09f9f3..0acb05f0a2b7 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -95,7 +95,7 @@ }; &ehci { - samsung,vbus-gpio = <&gpx3 5 1>; + samsung,vbus-gpio = <&gpx3 5 GPIO_ACTIVE_HIGH>; status = "okay"; phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>; phy-names = "hsic0", "hsic1"; From 5f1654a0e520e989ebf85a5aadb6265d04161c74 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 3 Aug 2022 13:28:37 +0300 Subject: [PATCH 264/610] iio: adc: at91-sama5d2_adc: fix AT91_SAMA5D2_MR_TRACKTIM_MAX [ Upstream commit bb73d5d9164c57c4bb916739a98e5cd8e0a5ed8c ] All ADC HW versions handled by this driver (SAMA5D2, SAM9X60, SAMA7G5) have MR.TRACKTIM on 4 bits. Fix AT91_SAMA5D2_MR_TRACKTIM_MAX to reflect this. Fixes: 27e177190891 ("iio:adc:at91_adc8xx: introduce new atmel adc driver") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220803102855.2191070-2-claudiu.beznea@microchip.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/at91-sama5d2_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index c4de706012e5..92e2e7420aa9 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -74,7 +74,7 @@ #define AT91_SAMA5D2_MR_ANACH BIT(23) /* Tracking Time */ #define AT91_SAMA5D2_MR_TRACKTIM(v) ((v) << 24) -#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xff +#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xf /* Transfer Time */ #define AT91_SAMA5D2_MR_TRANSFER(v) ((v) << 28) #define AT91_SAMA5D2_MR_TRANSFER_MAX 0x3 From c5c63736d2a11391c32097fb9dcf2e5550fda8c7 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 3 Aug 2022 13:28:38 +0300 Subject: [PATCH 265/610] iio: adc: at91-sama5d2_adc: check return status for pressure and touch [ Upstream commit d84ace944a3b24529798dbae1340dea098473155 ] Check return status of at91_adc_read_position() and at91_adc_read_pressure() in at91_adc_read_info_raw(). Fixes: 6794e23fa3fe ("iio: adc: at91-sama5d2_adc: add support for oversampling resolution") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220803102855.2191070-3-claudiu.beznea@microchip.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/at91-sama5d2_adc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 92e2e7420aa9..6eb72ba6b4d2 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -1331,8 +1331,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, *val = tmp_val; mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); + if (ret > 0) + ret = at91_adc_adjust_val_osr(st, val); - return at91_adc_adjust_val_osr(st, val); + return ret; } if (chan->type == IIO_PRESSURE) { ret = iio_device_claim_direct_mode(indio_dev); @@ -1345,8 +1347,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, *val = tmp_val; mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); + if (ret > 0) + ret = at91_adc_adjust_val_osr(st, val); - return at91_adc_adjust_val_osr(st, val); + return ret; } /* in this case we have a voltage channel */ From 5db9b840ac883c799d69588862359bcfca80a395 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 3 Aug 2022 13:28:39 +0300 Subject: [PATCH 266/610] iio: adc: at91-sama5d2_adc: lock around oversampling and sample freq [ Upstream commit 9780a23ed5a0a0a63683e078f576719a98d4fb70 ] .read_raw()/.write_raw() could be called asynchronously from user space or other in kernel drivers. Without locking on st->lock these could be called asynchronously while there is a conversion in progress. Read will be harmless but changing registers while conversion is in progress may lead to inconsistent results. Thus, to avoid this lock st->lock. Fixes: 27e177190891 ("iio:adc:at91_adc8xx: introduce new atmel adc driver") Fixes: 6794e23fa3fe ("iio: adc: at91-sama5d2_adc: add support for oversampling resolution") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220803102855.2191070-4-claudiu.beznea@microchip.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/at91-sama5d2_adc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 6eb72ba6b4d2..9cd6a779a217 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -1329,10 +1329,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, ret = at91_adc_read_position(st, chan->channel, &tmp_val); *val = tmp_val; - mutex_unlock(&st->lock); - iio_device_release_direct_mode(indio_dev); if (ret > 0) ret = at91_adc_adjust_val_osr(st, val); + mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); return ret; } @@ -1345,10 +1345,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, ret = at91_adc_read_pressure(st, chan->channel, &tmp_val); *val = tmp_val; - mutex_unlock(&st->lock); - iio_device_release_direct_mode(indio_dev); if (ret > 0) ret = at91_adc_adjust_val_osr(st, val); + mutex_unlock(&st->lock); + iio_device_release_direct_mode(indio_dev); return ret; } @@ -1441,16 +1441,20 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev, /* if no change, optimize out */ if (val == st->oversampling_ratio) return 0; + mutex_lock(&st->lock); st->oversampling_ratio = val; /* update ratio */ at91_adc_config_emr(st); + mutex_unlock(&st->lock); return 0; case IIO_CHAN_INFO_SAMP_FREQ: if (val < st->soc_info.min_sample_rate || val > st->soc_info.max_sample_rate) return -EINVAL; + mutex_lock(&st->lock); at91_adc_setup_samp_freq(indio_dev, val); + mutex_unlock(&st->lock); return 0; default: return -EINVAL; From b0d4fcc3ecb83d85597c6d208609c61828859c70 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 3 Aug 2022 13:28:40 +0300 Subject: [PATCH 267/610] iio: adc: at91-sama5d2_adc: disable/prepare buffer on suspend/resume [ Upstream commit 808175e21d9b7f866eda742e8970f27b78afe5db ] In case triggered buffers are enabled while system is suspended they will not work anymore after resume. For this call at91_adc_buffer_postdisable() on suspend and at91_adc_buffer_prepare() on resume. On tests it has been seen that at91_adc_buffer_postdisable() call is not necessary but it has been kept because it also does the book keeping for DMA. On resume path there is no need to call at91_adc_configure_touch() as it is embedded in at91_adc_buffer_prepare(). Fixes: 073c662017f2f ("iio: adc: at91-sama5d2_adc: add support for DMA") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220803102855.2191070-5-claudiu.beznea@microchip.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/at91-sama5d2_adc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 9cd6a779a217..403a29e4dc3e 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -1903,6 +1903,9 @@ static __maybe_unused int at91_adc_suspend(struct device *dev) struct iio_dev *indio_dev = dev_get_drvdata(dev); struct at91_adc_state *st = iio_priv(indio_dev); + if (iio_buffer_enabled(indio_dev)) + at91_adc_buffer_postdisable(indio_dev); + /* * Do a sofware reset of the ADC before we go to suspend. * this will ensure that all pins are free from being muxed by the ADC @@ -1946,14 +1949,11 @@ static __maybe_unused int at91_adc_resume(struct device *dev) if (!iio_buffer_enabled(indio_dev)) return 0; - /* check if we are enabling triggered buffer or the touchscreen */ - if (at91_adc_current_chan_is_touch(indio_dev)) - return at91_adc_configure_touch(st, true); - else - return at91_adc_configure_trigger(st->trig, true); + ret = at91_adc_buffer_prepare(indio_dev); + if (ret) + goto vref_disable_resume; - /* not needed but more explicit */ - return 0; + return at91_adc_configure_trigger(st->trig, true); vref_disable_resume: regulator_disable(st->vref); From 504e8807fe5f9efdaf61a047a5a21ca4ecaf9aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Fri, 15 Jul 2022 14:28:49 +0200 Subject: [PATCH 268/610] iio: inkern: only release the device node when done with it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 79c3e84874c7d14f04ad58313b64955a0d2e9437 ] 'of_node_put()' can potentially release the memory pointed to by 'iiospec.np' which would leave us with an invalid pointer (and we would still pass it in 'of_xlate()'). Note that it is not guaranteed for the of_node lifespan to be attached to the device (to which is attached) lifespan so that there is (even though very unlikely) the possibility for the node to be freed while the device is still around. Thus, as there are indeed some of_xlate users which do access the node, a race is indeed possible. As such, we can only release the node after we are done with it. Fixes: 17d82b47a215d ("iio: Add OF support") Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20220715122903.332535-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/inkern.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b5966365d769..30a8ecb692f8 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -148,9 +148,10 @@ static int __of_iio_channel_get(struct iio_channel *channel, idev = bus_find_device(&iio_bus_type, NULL, iiospec.np, iio_dev_node_match); - of_node_put(iiospec.np); - if (idev == NULL) + if (idev == NULL) { + of_node_put(iiospec.np); return -EPROBE_DEFER; + } indio_dev = dev_to_iio_dev(idev); channel->indio_dev = indio_dev; @@ -158,6 +159,7 @@ static int __of_iio_channel_get(struct iio_channel *channel, index = indio_dev->info->of_xlate(indio_dev, &iiospec); else index = __of_iio_simple_xlate(indio_dev, &iiospec); + of_node_put(iiospec.np); if (index < 0) goto err_put; channel->channel = &indio_dev->channels[index]; From 8169da520e8f376aeaeae811438be9e451aebd27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Fri, 15 Jul 2022 14:28:50 +0200 Subject: [PATCH 269/610] iio: inkern: fix return value in devm_of_iio_channel_get_by_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9e878dbc0e8322f8b2f5ab0093c1e89926362dbe ] of_iio_channel_get_by_name() can either return NULL or an error pointer so that only doing IS_ERR() is not enough. Fix it by checking the NULL pointer case and return -ENODEV in that case. Note this is done like this so that users of the function (which only check for error pointers) do not need to be changed. This is not ideal since we are losing error codes and as such, in a follow up change, things will be unified so that of_iio_channel_get_by_name() only returns error codes. Fixes: 6e39b145cef7 ("iio: provide of_iio_channel_get_by_name() and devm_ version it") Signed-off-by: Nuno Sá Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220715122903.332535-3-nuno.sa@analog.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/inkern.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 30a8ecb692f8..bf9ce01c854b 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -395,6 +395,8 @@ struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev, channel = of_iio_channel_get_by_name(np, channel_name); if (IS_ERR(channel)) return channel; + if (!channel) + return ERR_PTR(-ENODEV); ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel); if (ret) From 23fafc2e2cf65887e9a2b8d8c0c001a7d078393f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 26 Jun 2022 13:29:23 +0100 Subject: [PATCH 270/610] iio: ABI: Fix wrong format of differential capacitance channel ABI. [ Upstream commit 1efc41035f1841acf0af2bab153158e27ce94f10 ] in_ only occurs once in these attributes. Fixes: 0baf29d658c7 ("staging:iio:documentation Add abi docs for capacitance adcs.") Signed-off-by: Jonathan Cameron Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220626122938.582107-3-jic23@kernel.org Signed-off-by: Sasha Levin --- Documentation/ABI/testing/sysfs-bus-iio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 6ad47a67521c..f41e767e702b 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -188,7 +188,7 @@ Description: Raw capacitance measurement from channel Y. Units after application of scale and offset are nanofarads. -What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw +What: /sys/.../iio:deviceX/in_capacitanceY-capacitanceZ_raw KernelVersion: 3.2 Contact: linux-iio@vger.kernel.org Description: From cd35ad9a7d66b90a030ab4a014c5ee8d0c375423 Mon Sep 17 00:00:00 2001 From: Jakob Hauser Date: Fri, 12 Aug 2022 23:54:06 +0200 Subject: [PATCH 271/610] iio: magnetometer: yas530: Change data type of hard_offsets to signed [ Upstream commit e137fafc8985cf152a4bb6f18ae83ebb06816df1 ] The "hard_offsets" are currently unsigned u8 but they should be signed as they can get negative. They are signed in function yas5xx_meaure_offsets() and in the Yamaha drivers [1][2]. [1] https://github.com/NovaFusion/android_kernel_samsung_golden/blob/cm-12.1/drivers/sensor/compass/yas.h#L156 [2] https://github.com/msm8916-mainline/android_kernel_qcom_msm8916/blob/GT-I9195I/drivers/iio/magnetometer/yas_mag_drv-yas532.c#L91 Fixes: de8860b1ed47 ("iio: magnetometer: Add driver for Yamaha YAS530") Signed-off-by: Jakob Hauser Reviewed-by: Linus Walleij Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/40f052bf6491457d0c5c0ed4c3534dc6fa251c3c.1660337264.git.jahau@rocketmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/magnetometer/yamaha-yas530.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c index b2bc637150bf..40192aa46b04 100644 --- a/drivers/iio/magnetometer/yamaha-yas530.c +++ b/drivers/iio/magnetometer/yamaha-yas530.c @@ -132,7 +132,7 @@ struct yas5xx { unsigned int version; char name[16]; struct yas5xx_calibration calibration; - u8 hard_offsets[3]; + s8 hard_offsets[3]; struct iio_mount_matrix orientation; struct regmap *map; struct regulator_bulk_data regs[2]; From c11f48764c8b14b71c8c3bfbbacf795c738211fd Mon Sep 17 00:00:00 2001 From: Aharon Landau Date: Sun, 31 Jul 2022 11:26:36 +0300 Subject: [PATCH 272/610] RDMA/mlx5: Don't compare mkey tags in DEVX indirect mkey [ Upstream commit 13ad1125b941a5f257d9d3ae70485773abd34792 ] According to the ib spec: If the CI supports the Base Memory Management Extensions defined in this specification, the L_Key format must consist of: 24 bit index in the most significant bits of the R_Key, and 8 bit key in the least significant bits of the R_Key Through a successful Allocate L_Key verb invocation, the CI must let the consumer own the key portion of the returned R_Key Therefore, when creating a mkey using DEVX, the consumer is allowed to change the key part. The kernel should compare only the index part of a R_Key to determine equality with another R_Key. Adding capability in order not to break backward compatibility. Fixes: 534fd7aac56a ("IB/mlx5: Manage indirection mkey upon DEVX flow for ODP") Link: https://lore.kernel.org/r/3d669aacea85a3a15c3b3b953b3eaba3f80ef9be.1659255945.git.leonro@nvidia.com Signed-off-by: Aharon Landau Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/main.c | 3 +++ drivers/infiniband/hw/mlx5/odp.c | 3 ++- include/uapi/rdma/mlx5-abi.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 8664bcf6d3f5..827ee3040bea 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1847,6 +1847,9 @@ static int set_ucontext_resp(struct ib_ucontext *uctx, if (MLX5_CAP_GEN(dev->mdev, drain_sigerr)) resp->comp_mask |= MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS; + resp->comp_mask |= + MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG; + return 0; } diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c index d0d98e584ebc..fcf6447b4a4e 100644 --- a/drivers/infiniband/hw/mlx5/odp.c +++ b/drivers/infiniband/hw/mlx5/odp.c @@ -792,7 +792,8 @@ static bool mkey_is_eq(struct mlx5_core_mkey *mmkey, u32 key) { if (!mmkey) return false; - if (mmkey->type == MLX5_MKEY_MW) + if (mmkey->type == MLX5_MKEY_MW || + mmkey->type == MLX5_MKEY_INDIRECT_DEVX) return mlx5_base_mkey(mmkey->key) == mlx5_base_mkey(key); return mmkey->key == key; } diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h index 86be4a92b67b..a96b7d2770e1 100644 --- a/include/uapi/rdma/mlx5-abi.h +++ b/include/uapi/rdma/mlx5-abi.h @@ -104,6 +104,7 @@ enum mlx5_ib_alloc_ucontext_resp_mask { MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE = 1UL << 2, MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS = 1UL << 3, MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_REAL_TIME_TS = 1UL << 4, + MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG = 1UL << 5, }; enum mlx5_user_cmds_supp_uhw { From e900ec4c4f741c0453322cdf8529a422ce11b7cb Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Wed, 27 Jul 2022 18:38:01 -0700 Subject: [PATCH 273/610] usb: common: debug: Check non-standard control requests [ Upstream commit b6155eaf6b05e558218b44b88a6cad03f15a586c ] Previously usb_decode_ctrl() only decodes standard control requests, but it was used for non-standard requests also. If it's non-standard or unknown standard bRequest, print the Setup data values. Fixes: af32423a2d86 ("usb: dwc3: trace: decode ctrl request") Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/8d6a30f2f2f953eff833a5bc5aac640a4cc2fc9f.1658971571.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/common/debug.c | 96 +++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 32 deletions(-) diff --git a/drivers/usb/common/debug.c b/drivers/usb/common/debug.c index a76a086b9c54..f0c0e8db7038 100644 --- a/drivers/usb/common/debug.c +++ b/drivers/usb/common/debug.c @@ -207,30 +207,28 @@ static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size) snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue); } -/** - * usb_decode_ctrl - Returns human readable representation of control request. - * @str: buffer to return a human-readable representation of control request. - * This buffer should have about 200 bytes. - * @size: size of str buffer. - * @bRequestType: matches the USB bmRequestType field - * @bRequest: matches the USB bRequest field - * @wValue: matches the USB wValue field (CPU byte order) - * @wIndex: matches the USB wIndex field (CPU byte order) - * @wLength: matches the USB wLength field (CPU byte order) - * - * Function returns decoded, formatted and human-readable description of - * control request packet. - * - * The usage scenario for this is for tracepoints, so function as a return - * use the same value as in parameters. This approach allows to use this - * function in TP_printk - * - * Important: wValue, wIndex, wLength parameters before invoking this function - * should be processed by le16_to_cpu macro. - */ -const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType, - __u8 bRequest, __u16 wValue, __u16 wIndex, - __u16 wLength) +static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType, + __u8 bRequest, __u16 wValue, __u16 wIndex, + __u16 wLength) +{ + u8 recip = bRequestType & USB_RECIP_MASK; + u8 type = bRequestType & USB_TYPE_MASK; + + snprintf(str, size, + "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u", + (type == USB_TYPE_STANDARD) ? "Standard" : + (type == USB_TYPE_VENDOR) ? "Vendor" : + (type == USB_TYPE_CLASS) ? "Class" : "Unknown", + (recip == USB_RECIP_DEVICE) ? "Device" : + (recip == USB_RECIP_INTERFACE) ? "Interface" : + (recip == USB_RECIP_ENDPOINT) ? "Endpoint" : "Unknown", + (bRequestType & USB_DIR_IN) ? "IN" : "OUT", + bRequest, wValue, wIndex, wLength); +} + +static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType, + __u8 bRequest, __u16 wValue, __u16 wIndex, + __u16 wLength) { switch (bRequest) { case USB_REQ_GET_STATUS: @@ -271,14 +269,48 @@ const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType, usb_decode_set_isoch_delay(wValue, str, size); break; default: - snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x", - bRequestType, bRequest, - (u8)(cpu_to_le16(wValue) & 0xff), - (u8)(cpu_to_le16(wValue) >> 8), - (u8)(cpu_to_le16(wIndex) & 0xff), - (u8)(cpu_to_le16(wIndex) >> 8), - (u8)(cpu_to_le16(wLength) & 0xff), - (u8)(cpu_to_le16(wLength) >> 8)); + usb_decode_ctrl_generic(str, size, bRequestType, bRequest, + wValue, wIndex, wLength); + break; + } +} + +/** + * usb_decode_ctrl - Returns human readable representation of control request. + * @str: buffer to return a human-readable representation of control request. + * This buffer should have about 200 bytes. + * @size: size of str buffer. + * @bRequestType: matches the USB bmRequestType field + * @bRequest: matches the USB bRequest field + * @wValue: matches the USB wValue field (CPU byte order) + * @wIndex: matches the USB wIndex field (CPU byte order) + * @wLength: matches the USB wLength field (CPU byte order) + * + * Function returns decoded, formatted and human-readable description of + * control request packet. + * + * The usage scenario for this is for tracepoints, so function as a return + * use the same value as in parameters. This approach allows to use this + * function in TP_printk + * + * Important: wValue, wIndex, wLength parameters before invoking this function + * should be processed by le16_to_cpu macro. + */ +const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType, + __u8 bRequest, __u16 wValue, __u16 wIndex, + __u16 wLength) +{ + switch (bRequestType & USB_TYPE_MASK) { + case USB_TYPE_STANDARD: + usb_decode_ctrl_standard(str, size, bRequestType, bRequest, + wValue, wIndex, wLength); + break; + case USB_TYPE_VENDOR: + case USB_TYPE_CLASS: + default: + usb_decode_ctrl_generic(str, size, bRequestType, bRequest, + wValue, wIndex, wLength); + break; } return str; From e0001a565c16a36ae60d8149192ffe22871aa89d Mon Sep 17 00:00:00 2001 From: Liang He Date: Tue, 28 Jun 2022 22:10:38 +0800 Subject: [PATCH 274/610] clk: meson: Hold reference returned by of_get_parent() [ Upstream commit 89ab396d712f7c91fe94f55cff23460426f5fc81 ] We should hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance. Fixes: 88e2da81241e ("clk: meson: aoclk: refactor common code into dedicated file") Fixes: 6682bd4d443f ("clk: meson: factorise meson64 peripheral clock controller drivers") Fixes: bb6eddd1d28c ("clk: meson: meson8b: use the HHI syscon if available") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220628141038.168383-1-windhl@126.com Reviewed-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/meson/meson-aoclk.c | 5 ++++- drivers/clk/meson/meson-eeclk.c | 5 ++++- drivers/clk/meson/meson8b.c | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index 27cd2c1f3f61..434cd8f9de82 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -38,6 +38,7 @@ int meson_aoclkc_probe(struct platform_device *pdev) struct meson_aoclk_reset_controller *rstc; struct meson_aoclk_data *data; struct device *dev = &pdev->dev; + struct device_node *np; struct regmap *regmap; int ret, clkid; @@ -49,7 +50,9 @@ int meson_aoclkc_probe(struct platform_device *pdev) if (!rstc) return -ENOMEM; - regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); + np = of_get_parent(dev->of_node); + regmap = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(regmap)) { dev_err(dev, "failed to get regmap\n"); return PTR_ERR(regmap); diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index 8d5a5dab955a..0e5e6b57eb20 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c @@ -18,6 +18,7 @@ int meson_eeclkc_probe(struct platform_device *pdev) { const struct meson_eeclkc_data *data; struct device *dev = &pdev->dev; + struct device_node *np; struct regmap *map; int ret, i; @@ -26,7 +27,9 @@ int meson_eeclkc_probe(struct platform_device *pdev) return -EINVAL; /* Get the hhi system controller node */ - map = syscon_node_to_regmap(of_get_parent(dev->of_node)); + np = of_get_parent(dev->of_node); + map = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(map)) { dev_err(dev, "failed to get HHI regmap\n"); diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index a844d35b553a..809a0bfb670d 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -3717,12 +3717,15 @@ static void __init meson8b_clkc_init_common(struct device_node *np, struct clk_hw_onecell_data *clk_hw_onecell_data) { struct meson8b_clk_reset *rstc; + struct device_node *parent_np; const char *notifier_clk_name; struct clk *notifier_clk; struct regmap *map; int i, ret; - map = syscon_node_to_regmap(of_get_parent(np)); + parent_np = of_get_parent(np); + map = syscon_node_to_regmap(parent_np); + of_node_put(parent_np); if (IS_ERR(map)) { pr_err("failed to get HHI regmap - Trying obsolete regs\n"); return; From a8cbce0305b26dbe05ca3fa28b62428de6e680a7 Mon Sep 17 00:00:00 2001 From: Liang He Date: Tue, 28 Jun 2022 22:31:55 +0800 Subject: [PATCH 275/610] clk: oxnas: Hold reference returned by of_get_parent() [ Upstream commit 1d6aa08c54cd0e005210ab8e3b1e92ede70f8a4f ] In oxnas_stdclk_probe(), we need to hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance. Fixes: 0bbd72b4c64f ("clk: Add Oxford Semiconductor OXNAS Standard Clocks") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220628143155.170550-1-windhl@126.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/clk-oxnas.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-oxnas.c b/drivers/clk/clk-oxnas.c index 78d5ea669fea..2fe36f579ac5 100644 --- a/drivers/clk/clk-oxnas.c +++ b/drivers/clk/clk-oxnas.c @@ -207,7 +207,7 @@ static const struct of_device_id oxnas_stdclk_dt_ids[] = { static int oxnas_stdclk_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = pdev->dev.of_node, *parent_np; const struct oxnas_stdclk_data *data; const struct of_device_id *id; struct regmap *regmap; @@ -219,7 +219,9 @@ static int oxnas_stdclk_probe(struct platform_device *pdev) return -ENODEV; data = id->data; - regmap = syscon_node_to_regmap(of_get_parent(np)); + parent_np = of_get_parent(np); + regmap = syscon_node_to_regmap(parent_np); + of_node_put(parent_np); if (IS_ERR(regmap)) { dev_err(&pdev->dev, "failed to have parent regmap\n"); return PTR_ERR(regmap); From 857b719bede43b03a1cce634c5e8b8464b36ccd9 Mon Sep 17 00:00:00 2001 From: Liang He Date: Tue, 28 Jun 2022 22:38:51 +0800 Subject: [PATCH 276/610] clk: qoriq: Hold reference returned by of_get_parent() [ Upstream commit a8ea4273bc26256ce3cce83164f0f51c5bf6e127 ] In legacy_init_clockgen(), we need to hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance. Beside, in create_sysclk(), we need to call of_node_put() on 'sysclk' also for refcount balance. Fixes: 0dfc86b3173f ("clk: qoriq: Move chip-specific knowledge into driver") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220628143851.171299-1-windhl@126.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/clk-qoriq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 88898b97a443..5eddb9f0d6bd 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -1063,8 +1063,13 @@ static void __init _clockgen_init(struct device_node *np, bool legacy); */ static void __init legacy_init_clockgen(struct device_node *np) { - if (!clockgen.node) - _clockgen_init(of_get_parent(np), true); + if (!clockgen.node) { + struct device_node *parent_np; + + parent_np = of_get_parent(np); + _clockgen_init(parent_np, true); + of_node_put(parent_np); + } } /* Legacy node */ @@ -1159,6 +1164,7 @@ static struct clk * __init create_sysclk(const char *name) sysclk = of_get_child_by_name(clockgen.node, "sysclk"); if (sysclk) { clk = sysclk_from_fixed(sysclk, name); + of_node_put(sysclk); if (!IS_ERR(clk)) return clk; } From 49343bdf95ebee048cac71727498b15f90f6b236 Mon Sep 17 00:00:00 2001 From: Liang He Date: Fri, 8 Jul 2022 16:49:00 +0800 Subject: [PATCH 277/610] clk: berlin: Add of_node_put() for of_get_parent() [ Upstream commit 37c381b812dcbfde9c3f1f3d3e75fdfc1b40d5bc ] In berlin2_clock_setup() and berlin2q_clock_setup(), we need to call of_node_put() for the reference returned by of_get_parent() which has increased the refcount. We should call *_put() in fail path or when it is not used anymore. Fixes: 26b3b6b959b2 ("clk: berlin: prepare simple-mfd conversion") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220708084900.311684-1-windhl@126.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/berlin/bg2.c | 5 ++++- drivers/clk/berlin/bg2q.c | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index bccdfa00fd37..67a9edbba29c 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c @@ -500,12 +500,15 @@ static void __init berlin2_clock_setup(struct device_node *np) int n, ret; clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); - if (!clk_data) + if (!clk_data) { + of_node_put(parent_np); return; + } clk_data->num = MAX_CLKS; hws = clk_data->hws; gbase = of_iomap(parent_np, 0); + of_node_put(parent_np); if (!gbase) return; diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index e9518d35f262..dd2784bb75b6 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -286,19 +286,23 @@ static void __init berlin2q_clock_setup(struct device_node *np) int n, ret; clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); - if (!clk_data) + if (!clk_data) { + of_node_put(parent_np); return; + } clk_data->num = MAX_CLKS; hws = clk_data->hws; gbase = of_iomap(parent_np, 0); if (!gbase) { + of_node_put(parent_np); pr_err("%pOF: Unable to map global base\n", np); return; } /* BG2Q CPU PLL is not part of global registers */ cpupll_base = of_iomap(parent_np, 1); + of_node_put(parent_np); if (!cpupll_base) { pr_err("%pOF: Unable to map cpupll base\n", np); iounmap(gbase); From ca5f338ef165311f4c924f6dfda1f701e11aa2d7 Mon Sep 17 00:00:00 2001 From: Liang He Date: Mon, 4 Jul 2022 08:47:29 +0800 Subject: [PATCH 278/610] clk: sprd: Hold reference returned by of_get_parent() [ Upstream commit 91e6455bf715fb1558a0bf8f645ec1c131254a3c ] We should hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance. Fixes: f95e8c7923d1 ("clk: sprd: support to get regmap from parent node") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220704004729.272481-1-windhl@126.com Reviewed-by: Orson Zhai Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/sprd/common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c index d620bbbcdfc8..ce81e4087a8f 100644 --- a/drivers/clk/sprd/common.c +++ b/drivers/clk/sprd/common.c @@ -41,7 +41,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev, { void __iomem *base; struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node; + struct device_node *node = dev->of_node, *np; struct regmap *regmap; if (of_find_property(node, "sprd,syscon", NULL)) { @@ -50,9 +50,10 @@ int sprd_clk_regmap_init(struct platform_device *pdev, pr_err("%s: failed to get syscon regmap\n", __func__); return PTR_ERR(regmap); } - } else if (of_device_is_compatible(of_get_parent(dev->of_node), - "syscon")) { - regmap = device_node_to_regmap(of_get_parent(dev->of_node)); + } else if (of_device_is_compatible(np = of_get_parent(node), "syscon") || + (of_node_put(np), 0)) { + regmap = device_node_to_regmap(np); + of_node_put(np); if (IS_ERR(regmap)) { dev_err(dev, "failed to get regmap from its parent.\n"); return PTR_ERR(regmap); From 417ed4432b1b40526b1cb50e535d46900505f6d9 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 23 May 2022 18:26:08 +0400 Subject: [PATCH 279/610] clk: tegra: Fix refcount leak in tegra210_clock_init [ Upstream commit 56c78cb1f00a9dde8cd762131ce8f4c5eb046fbb ] of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: 6b301a059eb2 ("clk: tegra: Add support for Tegra210 clocks") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220523142608.65074-1-linmq006@gmail.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/tegra/clk-tegra210.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index b9099012dc7b..499f999e91e1 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3748,6 +3748,7 @@ static void __init tegra210_clock_init(struct device_node *np) } pmc_base = of_iomap(node, 0); + of_node_put(node); if (!pmc_base) { pr_err("Can't map pmc registers\n"); WARN_ON(1); From e7a57fb92af52c4da69cd947752e8946e5ada50a Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 23 May 2022 18:38:34 +0400 Subject: [PATCH 280/610] clk: tegra: Fix refcount leak in tegra114_clock_init [ Upstream commit db16a80c76ea395766913082b1e3f939dde29b2c ] of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: 2cb5efefd6f7 ("clk: tegra: Implement clocks for Tegra114") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220523143834.7587-1-linmq006@gmail.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/tegra/clk-tegra114.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index bc9e47a4cb60..4e2b26e3e573 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1317,6 +1317,7 @@ static void __init tegra114_clock_init(struct device_node *np) } pmc_base = of_iomap(node, 0); + of_node_put(node); if (!pmc_base) { pr_err("Can't map pmc registers\n"); WARN_ON(1); From d6e750535b46e12cdde185b416c415e49e4e6e22 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 23 May 2022 19:28:11 +0400 Subject: [PATCH 281/610] clk: tegra20: Fix refcount leak in tegra20_clock_init [ Upstream commit 4e343bafe03ff68a62f48f8235cf98f2c685468b ] of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: 37c26a906527 ("clk: tegra: add clock support for Tegra20") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220523152811.19692-1-linmq006@gmail.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/tegra/clk-tegra20.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 3664593a5ba4..d246a39a6b4f 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -1128,6 +1128,7 @@ static void __init tegra20_clock_init(struct device_node *np) } pmc_base = of_iomap(node, 0); + of_node_put(node); if (!pmc_base) { pr_err("Can't map pmc registers\n"); BUG(); From 691f23a8475f04c988f7e98066b084e996b40fa0 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 4 Apr 2022 08:52:32 +0000 Subject: [PATCH 282/610] HSI: omap_ssi: Fix refcount leak in ssi_probe [ Upstream commit 9a2ea132df860177b33c9fd421b26c4e9a0a9396 ] When returning or breaking early from a for_each_available_child_of_node() loop, we need to explicitly call of_node_put() on the child node to possibly release the node. Fixes: b209e047bc74 ("HSI: Introduce OMAP SSI driver") Signed-off-by: Miaoqian Lin Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/hsi/controllers/omap_ssi_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c index 44a3f5660c10..eb9820158318 100644 --- a/drivers/hsi/controllers/omap_ssi_core.c +++ b/drivers/hsi/controllers/omap_ssi_core.c @@ -524,6 +524,7 @@ static int ssi_probe(struct platform_device *pd) if (!childpdev) { err = -ENODEV; dev_err(&pd->dev, "failed to create ssi controller port\n"); + of_node_put(child); goto out3; } } From 6225501072d3f2280eaad1e10a26a019fd5492a2 Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Fri, 26 Aug 2022 12:12:27 +0200 Subject: [PATCH 283/610] HSI: omap_ssi_port: Fix dma_map_sg error check [ Upstream commit 551e325bbd3fb8b5a686ac1e6cf76e5641461cf2 ] dma_map_sg return 0 on error, in case of error return -EIO to caller. Cc: Sebastian Reichel Cc: linux-kernel@vger.kernel.org (open list) Fixes: b209e047bc74 ("HSI: Introduce OMAP SSI driver") Signed-off-by: Jack Wang Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/hsi/controllers/omap_ssi_port.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index a0cb5be246e1..b9495b720f1b 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -230,10 +230,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) if (msg->ttype == HSI_MSG_READ) { err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, DMA_FROM_DEVICE); - if (err < 0) { + if (!err) { dev_dbg(&ssi->device, "DMA map SG failed !\n"); pm_runtime_put_autosuspend(omap_port->pdev); - return err; + return -EIO; } csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT | SSI_SRC_SINGLE_ACCESS0 | SSI_SRC_PERIPHERAL_PORT | @@ -247,10 +247,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) } else { err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, DMA_TO_DEVICE); - if (err < 0) { + if (!err) { dev_dbg(&ssi->device, "DMA map SG failed !\n"); pm_runtime_put_autosuspend(omap_port->pdev); - return err; + return -EIO; } csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT | SSI_DST_SINGLE_ACCESS0 | SSI_DST_PERIPHERAL_PORT | From a8d772c7b8537ed6cfd2907f9ebba038320c4fe5 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 20 Jul 2022 16:30:03 +0200 Subject: [PATCH 284/610] media: exynos4-is: fimc-is: Add of_node_put() when breaking out of loop [ Upstream commit 211f8304fa21aaedc2c247f0c9d6c7f1aaa61ad7 ] In fimc_is_register_subdevs(), we need to call of_node_put() for the reference 'i2c_bus' when breaking out of the for_each_compatible_node() which has increased the refcount. Fixes: 9a761e436843 ("[media] exynos4-is: Add Exynos4x12 FIMC-IS driver") Signed-off-by: Liang He Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/exynos4-is/fimc-is.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index e3072d69c49f..a7704ff069d6 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -213,6 +213,7 @@ static int fimc_is_register_subdevs(struct fimc_is *is) if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) { of_node_put(child); + of_node_put(i2c_bus); return ret; } index++; From aeffca4344262aae3301193df7f2760801981fcd Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Fri, 29 Jul 2022 17:17:45 +0530 Subject: [PATCH 285/610] tty: xilinx_uartps: Fix the ignore_status [ Upstream commit b8a6c3b3d4654fba19881cc77da61eac29f57cae ] Currently the ignore_status is not considered in the isr. Add a check to add the ignore_status. Fixes: 61ec9016988f ("tty/serial: add support for Xilinx PS UART") Signed-off-by: Shubhrajyoti Datta Link: https://lore.kernel.org/r/20220729114748.18332-5-shubhrajyoti.datta@xilinx.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/xilinx_uartps.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index d5e243908d9f..815e3e26ee20 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -375,6 +375,8 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) isrstatus &= ~CDNS_UART_IXR_TXEMPTY; } + isrstatus &= port->read_status_mask; + isrstatus &= ~port->ignore_status_mask; /* * Skip RX processing if RX is disabled as RXEMPTY will never be set * as read bytes will not be removed from the FIFO. From 4e2042f1adc73606c1ec4b75d050526ef32d8f10 Mon Sep 17 00:00:00 2001 From: Xu Qiang Date: Thu, 18 Aug 2022 08:57:53 +0200 Subject: [PATCH 286/610] media: meson: vdec: add missing clk_disable_unprepare on error in vdec_hevc_start() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 4029372233e13e281f8c387f279f9f064ced3810 ] Add the missing clk_disable_unprepare() before return from vdec_hevc_start() in the error handling case. Fixes: 823a7300340e (“media: meson: vdec: add common HEVC decoder support”) Signed-off-by: Xu Qiang Reviewed-by: Neil Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/staging/media/meson/vdec/vdec_hevc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/meson/vdec/vdec_hevc.c b/drivers/staging/media/meson/vdec/vdec_hevc.c index 9530e580e57a..afced435c907 100644 --- a/drivers/staging/media/meson/vdec/vdec_hevc.c +++ b/drivers/staging/media/meson/vdec/vdec_hevc.c @@ -167,8 +167,12 @@ static int vdec_hevc_start(struct amvdec_session *sess) clk_set_rate(core->vdec_hevc_clk, 666666666); ret = clk_prepare_enable(core->vdec_hevc_clk); - if (ret) + if (ret) { + if (core->platform->revision == VDEC_REVISION_G12A || + core->platform->revision == VDEC_REVISION_SM1) + clk_disable_unprepare(core->vdec_hevcf_clk); return ret; + } if (core->platform->revision == VDEC_REVISION_SM1) regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, From 6c5da92103bddd1f0c36cb69446ff7cae3043986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Date: Sat, 8 Jan 2022 18:04:39 +0100 Subject: [PATCH 287/610] media: uvcvideo: Fix memory leak in uvc_gpio_parse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f0f078457f18f10696888f8d0e6aba9deb9cde92 ] Previously the unit buffer was allocated before checking the IRQ for privacy GPIO. In case of error, the unit buffer was leaked. Allocate the unit buffer after the IRQ to avoid it. Addresses-Coverity-ID: 1474639 ("Resource leak") Fixes: 2886477ff987 ("media: uvcvideo: Implement UVC_EXT_GPIO_UNIT") Signed-off-by: José Expósito Reviewed-by: Ricardo Ribalda Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_driver.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 9a791d8ef200..72fff7264b54 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1534,10 +1534,6 @@ static int uvc_gpio_parse(struct uvc_device *dev) if (IS_ERR_OR_NULL(gpio_privacy)) return PTR_ERR_OR_ZERO(gpio_privacy); - unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); - if (!unit) - return -ENOMEM; - irq = gpiod_to_irq(gpio_privacy); if (irq < 0) { if (irq != EPROBE_DEFER) @@ -1546,6 +1542,10 @@ static int uvc_gpio_parse(struct uvc_device *dev) return irq; } + unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); + if (!unit) + return -ENOMEM; + unit->gpio.gpio_privacy = gpio_privacy; unit->gpio.irq = irq; unit->gpio.bControlSize = 1; From 23624abbc9c6951c9be6beba0f0141bc1d0bc4cf Mon Sep 17 00:00:00 2001 From: Yunke Cao Date: Thu, 7 Jul 2022 10:53:31 +0200 Subject: [PATCH 288/610] media: uvcvideo: Use entity get_cur in uvc_ctrl_set [ Upstream commit 5f36851c36b30f713f588ed2b60aa7b4512e2c76 ] Entity controls should get_cur using an entity-defined function instead of via a query. Fix this in uvc_ctrl_set. Fixes: 65900c581d01 ("media: uvcvideo: Allow entity-defined get_info and get_cur") Signed-off-by: Yunke Cao Reviewed-by: Ricardo Ribalda Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_ctrl.c | 83 ++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index b3dde98499f4..5bb29fc49538 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -988,35 +988,55 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, return value; } +static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain, + struct uvc_control *ctrl) +{ + u8 *data; + int ret; + + if (ctrl->loaded) + return 0; + + data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); + + if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { + memset(data, 0, ctrl->info.size); + ctrl->loaded = 1; + + return 0; + } + + if (ctrl->entity->get_cur) + ret = ctrl->entity->get_cur(chain->dev, ctrl->entity, + ctrl->info.selector, data, + ctrl->info.size); + else + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, + ctrl->entity->id, chain->dev->intfnum, + ctrl->info.selector, data, + ctrl->info.size); + + if (ret < 0) + return ret; + + ctrl->loaded = 1; + + return ret; +} + static int __uvc_ctrl_get(struct uvc_video_chain *chain, - struct uvc_control *ctrl, struct uvc_control_mapping *mapping, - s32 *value) + struct uvc_control *ctrl, + struct uvc_control_mapping *mapping, + s32 *value) { int ret; if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) return -EACCES; - if (!ctrl->loaded) { - if (ctrl->entity->get_cur) { - ret = ctrl->entity->get_cur(chain->dev, - ctrl->entity, - ctrl->info.selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info.size); - } else { - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, - ctrl->entity->id, - chain->dev->intfnum, - ctrl->info.selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info.size); - } - if (ret < 0) - return ret; - - ctrl->loaded = 1; - } + ret = __uvc_ctrl_load_cur(chain, ctrl); + if (ret < 0) + return ret; *value = __uvc_ctrl_get_value(mapping, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); @@ -1667,21 +1687,10 @@ int uvc_ctrl_set(struct uvc_fh *handle, * needs to be loaded from the device to perform the read-modify-write * operation. */ - if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { - if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { - memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - 0, ctrl->info.size); - } else { - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, - ctrl->entity->id, chain->dev->intfnum, - ctrl->info.selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info.size); - if (ret < 0) - return ret; - } - - ctrl->loaded = 1; + if ((ctrl->info.size * 8) != mapping->size) { + ret = __uvc_ctrl_load_cur(chain, ctrl); + if (ret < 0) + return ret; } /* Backup the current value in case we need to rollback later. */ From 2ea7caa9684687cf3adc1467cf4af3653a776192 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 1 Jun 2022 06:25:14 +0200 Subject: [PATCH 289/610] media: xilinx: vipp: Fix refcount leak in xvip_graph_dma_init [ Upstream commit 1c78f19c3a0ea312a8178a6bfd8934eb93e9b10a ] of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: df3305156f98 ("[media] v4l: xilinx: Add Xilinx Video IP core") Signed-off-by: Miaoqian Lin Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/xilinx/xilinx-vipp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index 2ce31d7ce1a6..5896a662da3b 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -472,7 +472,7 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) { struct device_node *ports; struct device_node *port; - int ret; + int ret = 0; ports = of_get_child_by_name(xdev->dev->of_node, "ports"); if (ports == NULL) { @@ -482,13 +482,14 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) for_each_child_of_node(ports, port) { ret = xvip_graph_dma_init_one(xdev, port); - if (ret < 0) { + if (ret) { of_node_put(port); - return ret; + break; } } - return 0; + of_node_put(ports); + return ret; } static void xvip_graph_cleanup(struct xvip_composite_device *xdev) From f2f405af70e6f0419e718d23fa304798a5405c41 Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Sun, 21 Aug 2022 21:16:13 -0400 Subject: [PATCH 290/610] RDMA/rxe: Fix "kernel NULL pointer dereference" error [ Upstream commit a625ca30eff806395175ebad3ac1399014bdb280 ] When rxe_queue_init in the function rxe_qp_init_req fails, both qp->req.task.func and qp->req.task.arg are not initialized. Because of creation of qp fails, the function rxe_create_qp will call rxe_qp_do_cleanup to handle allocated resource. Before calling __rxe_do_task, both qp->req.task.func and qp->req.task.arg should be checked. Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20220822011615.805603-2-yanjun.zhu@linux.dev Reported-by: syzbot+ab99dc4c6e961eed8b8e@syzkaller.appspotmail.com Signed-off-by: Zhu Yanjun Reviewed-by: Li Zhijian Reviewed-by: Bob Pearson Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/sw/rxe/rxe_qp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 661b83d65af3..4a6eb6de3b08 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -793,7 +793,9 @@ void rxe_qp_destroy(struct rxe_qp *qp) rxe_cleanup_task(&qp->comp.task); /* flush out any receive wr's or pending requests */ - __rxe_do_task(&qp->req.task); + if (qp->req.task.func) + __rxe_do_task(&qp->req.task); + if (qp->sq.queue) { __rxe_do_task(&qp->comp.task); __rxe_do_task(&qp->req.task); From c23c5e184550bc8df931c82969e688d4e48c7cd2 Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Sun, 21 Aug 2022 21:16:14 -0400 Subject: [PATCH 291/610] RDMA/rxe: Fix the error caused by qp->sk [ Upstream commit 548ce2e66725dcba4e27d1e8ac468d5dd17fd509 ] When sock_create_kern in the function rxe_qp_init_req fails, qp->sk is set to NULL. Then the function rxe_create_qp will call rxe_qp_do_cleanup to handle allocated resource. Before handling qp->sk, this variable should be checked. Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20220822011615.805603-3-yanjun.zhu@linux.dev Signed-off-by: Zhu Yanjun Reviewed-by: Li Zhijian Reviewed-by: Bob Pearson Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/sw/rxe/rxe_qp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 4a6eb6de3b08..57ebf4871608 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -835,8 +835,10 @@ static void rxe_qp_do_cleanup(struct work_struct *work) free_rd_atomic_resources(qp); - kernel_sock_shutdown(qp->sk, SHUT_RDWR); - sock_release(qp->sk); + if (qp->sk) { + kernel_sock_shutdown(qp->sk, SHUT_RDWR); + sock_release(qp->sk); + } } /* called when the last reference to the qp is dropped */ From 11bd8bbdf8f6f5c1145bb158793107a57e3a1f07 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Wed, 24 Aug 2022 16:26:00 +0800 Subject: [PATCH 292/610] misc: ocxl: fix possible refcount leak in afu_ioctl() [ Upstream commit c3b69ba5114c860d730870c03ab4ee45276e5e35 ] eventfd_ctx_put need to be called to put the refcount that gotten by eventfd_ctx_fdget when ocxl_irq_set_handler fails. Fixes: 060146614643 ("ocxl: move event_fd handling to frontend") Acked-by: Frederic Barrat Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20220824082600.36159-1-hbh25y@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/ocxl/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index d278f8ba2c76..134806c2e67e 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -259,6 +259,8 @@ static long afu_ioctl(struct file *file, unsigned int cmd, if (IS_ERR(ev_ctx)) return PTR_ERR(ev_ctx); rc = ocxl_irq_set_handler(ctx, irq_id, irq_handler, irq_free, ev_ctx); + if (rc) + eventfd_ctx_put(ev_ctx); break; case OCXL_IOCTL_GET_METADATA: From b94605f5cb99e90c8ca91523597a40e1bd59546b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 1 Sep 2022 08:18:45 +0300 Subject: [PATCH 293/610] fpga: prevent integer overflow in dfl_feature_ioctl_set_irq() [ Upstream commit 939bc5453b8cbdde9f1e5110ce8309aedb1b501a ] The "hdr.count * sizeof(s32)" multiplication can overflow on 32 bit systems leading to memory corruption. Use array_size() to fix that. Fixes: 322b598be4d9 ("fpga: dfl: introduce interrupt trigger setting API") Signed-off-by: Dan Carpenter Acked-by: Xu Yilun Link: https://lore.kernel.org/r/YxBAtYCM38dM7yzI@kili Signed-off-by: Xu Yilun Signed-off-by: Sasha Levin --- drivers/fpga/dfl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index f86666cf2c6a..c38143ef23c6 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -1864,7 +1864,7 @@ long dfl_feature_ioctl_set_irq(struct platform_device *pdev, return -EINVAL; fds = memdup_user((void __user *)(arg + sizeof(hdr)), - hdr.count * sizeof(s32)); + array_size(hdr.count, sizeof(s32))); if (IS_ERR(fds)) return PTR_ERR(fds); From e84aeeafe8b37ca65b98ab8a9ee5797fa1c03f51 Mon Sep 17 00:00:00 2001 From: Jie Hai Date: Tue, 30 Aug 2022 14:22:45 +0800 Subject: [PATCH 294/610] dmaengine: hisilicon: Disable channels when unregister hisi_dma [ Upstream commit e3bdaa04ada31f46d0586df83a2789b8913053c5 ] When hisi_dma is unloaded or unbinded, all of channels should be disabled. This patch disables DMA channels when driver is unloaded or unbinded. Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") Signed-off-by: Jie Hai Acked-by: Zhou Wang Link: https://lore.kernel.org/r/20220830062251.52993-2-haijie1@huawei.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/hisi_dma.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c index f680e9b40bf7..70a0d784a6a3 100644 --- a/drivers/dma/hisi_dma.c +++ b/drivers/dma/hisi_dma.c @@ -180,7 +180,8 @@ static void hisi_dma_reset_qp_point(struct hisi_dma_dev *hdma_dev, u32 index) hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, index, 0); } -static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan) +static void hisi_dma_reset_or_disable_hw_chan(struct hisi_dma_chan *chan, + bool disable) { struct hisi_dma_dev *hdma_dev = chan->hdma_dev; u32 index = chan->qp_num, tmp; @@ -201,8 +202,11 @@ static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan) hisi_dma_do_reset(hdma_dev, index); hisi_dma_reset_qp_point(hdma_dev, index); hisi_dma_pause_dma(hdma_dev, index, false); - hisi_dma_enable_dma(hdma_dev, index, true); - hisi_dma_unmask_irq(hdma_dev, index); + + if (!disable) { + hisi_dma_enable_dma(hdma_dev, index, true); + hisi_dma_unmask_irq(hdma_dev, index); + } ret = readl_relaxed_poll_timeout(hdma_dev->base + HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp, @@ -218,7 +222,7 @@ static void hisi_dma_free_chan_resources(struct dma_chan *c) struct hisi_dma_chan *chan = to_hisi_dma_chan(c); struct hisi_dma_dev *hdma_dev = chan->hdma_dev; - hisi_dma_reset_hw_chan(chan); + hisi_dma_reset_or_disable_hw_chan(chan, false); vchan_free_chan_resources(&chan->vc); memset(chan->sq, 0, sizeof(struct hisi_dma_sqe) * hdma_dev->chan_depth); @@ -394,7 +398,7 @@ static void hisi_dma_enable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index) static void hisi_dma_disable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index) { - hisi_dma_reset_hw_chan(&hdma_dev->chan[qp_index]); + hisi_dma_reset_or_disable_hw_chan(&hdma_dev->chan[qp_index], true); } static void hisi_dma_enable_qps(struct hisi_dma_dev *hdma_dev) From b88630d9aac0a748a53041533dcb5dcb455127e7 Mon Sep 17 00:00:00 2001 From: Jie Hai Date: Tue, 30 Aug 2022 14:22:46 +0800 Subject: [PATCH 295/610] dmaengine: hisilicon: Fix CQ head update [ Upstream commit 94477a79cf80e8ab55b68f14bc579a12ddea1e0b ] After completion of data transfer of one or multiple descriptors, the completion status and the current head pointer to submission queue are written into the CQ and interrupt can be generated to inform the software. In interrupt process CQ is read and cq_head is updated. hisi_dma_irq updates cq_head only when the completion status is success. When an abnormal interrupt reports, cq_head will not update which will cause subsequent interrupt processes read the error CQ and never report the correct status. This patch updates cq_head whenever CQ is accessed. Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") Signed-off-by: Jie Hai Acked-by: Zhou Wang Link: https://lore.kernel.org/r/20220830062251.52993-3-haijie1@huawei.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/hisi_dma.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c index 70a0d784a6a3..9e6ce3731ca5 100644 --- a/drivers/dma/hisi_dma.c +++ b/drivers/dma/hisi_dma.c @@ -436,12 +436,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data) desc = chan->desc; cqe = chan->cq + chan->cq_head; if (desc) { + chan->cq_head = (chan->cq_head + 1) % hdma_dev->chan_depth; + hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, + chan->qp_num, chan->cq_head); if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) { - chan->cq_head = (chan->cq_head + 1) % - hdma_dev->chan_depth; - hisi_dma_chan_write(hdma_dev->base, - HISI_DMA_CQ_HEAD_PTR, chan->qp_num, - chan->cq_head); vchan_cookie_complete(&desc->vd); } else { dev_err(&hdma_dev->pdev->dev, "task error!\n"); From 7cb9b20941e1fb20d22d0a2f460a3d4fa417274c Mon Sep 17 00:00:00 2001 From: Jie Hai Date: Tue, 30 Aug 2022 14:22:47 +0800 Subject: [PATCH 296/610] dmaengine: hisilicon: Add multi-thread support for a DMA channel [ Upstream commit 2cbb95883c990d0002a77e13d3278913ab26ad79 ] When we get a DMA channel and try to use it in multiple threads it will cause oops and hanging the system. % echo 100 > /sys/module/dmatest/parameters/threads_per_chan % echo 100 > /sys/module/dmatest/parameters/iterations % echo 1 > /sys/module/dmatest/parameters/run [383493.327077] Unable to handle kernel paging request at virtual address dead000000000108 [383493.335103] Mem abort info: [383493.335103] ESR = 0x96000044 [383493.335105] EC = 0x25: DABT (current EL), IL = 32 bits [383493.335107] SET = 0, FnV = 0 [383493.335108] EA = 0, S1PTW = 0 [383493.335109] FSC = 0x04: level 0 translation fault [383493.335110] Data abort info: [383493.335111] ISV = 0, ISS = 0x00000044 [383493.364739] CM = 0, WnR = 1 [383493.367793] [dead000000000108] address between user and kernel address ranges [383493.375021] Internal error: Oops: 96000044 [#1] PREEMPT SMP [383493.437574] CPU: 63 PID: 27895 Comm: dma0chan0-copy2 Kdump: loaded Tainted: GO 5.17.0-rc4+ #2 [383493.457851] pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [383493.465331] pc : vchan_tx_submit+0x64/0xa0 [383493.469957] lr : vchan_tx_submit+0x34/0xa0 This occurs because the transmission timed out, and that's due to data race. Each thread rewrite channels's descriptor as soon as device_issue_pending is called. It leads to the situation that the driver thinks that it uses the right descriptor in interrupt handler while channels's descriptor has been changed by other thread. The descriptor which in fact reported interrupt will not be handled any more, as well as its tx->callback. That's why timeout reports. With current fixes channels' descriptor changes it's value only when it has been used. A new descriptor is acquired from vc->desc_issued queue that is already filled with descriptors that are ready to be sent. Threads have no direct access to DMA channel descriptor. In case of channel's descriptor is busy, try to submit to HW again when a descriptor is completed. In this case, vc->desc_issued may be empty when hisi_dma_start_transfer is called, so delete error reporting on this. Now it is just possible to queue a descriptor for further processing. Fixes: e9f08b65250d ("dmaengine: hisilicon: Add Kunpeng DMA engine support") Signed-off-by: Jie Hai Acked-by: Zhou Wang Link: https://lore.kernel.org/r/20220830062251.52993-4-haijie1@huawei.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/hisi_dma.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c index 9e6ce3731ca5..df6be7ca340c 100644 --- a/drivers/dma/hisi_dma.c +++ b/drivers/dma/hisi_dma.c @@ -271,7 +271,6 @@ static void hisi_dma_start_transfer(struct hisi_dma_chan *chan) vd = vchan_next_desc(&chan->vc); if (!vd) { - dev_err(&hdma_dev->pdev->dev, "no issued task!\n"); chan->desc = NULL; return; } @@ -303,7 +302,7 @@ static void hisi_dma_issue_pending(struct dma_chan *c) spin_lock_irqsave(&chan->vc.lock, flags); - if (vchan_issue_pending(&chan->vc)) + if (vchan_issue_pending(&chan->vc) && !chan->desc) hisi_dma_start_transfer(chan); spin_unlock_irqrestore(&chan->vc.lock, flags); @@ -441,11 +440,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data) chan->qp_num, chan->cq_head); if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) { vchan_cookie_complete(&desc->vd); + hisi_dma_start_transfer(chan); } else { dev_err(&hdma_dev->pdev->dev, "task error!\n"); } - - chan->desc = NULL; } spin_unlock(&chan->vc.lock); From 49d85932f7d2e8d2b4dc06cf878c18a73dd72e35 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Sun, 4 Sep 2022 15:40:38 -0600 Subject: [PATCH 297/610] dyndbg: fix static_branch manipulation [ Upstream commit ee879be38bc87f8cedc79ae2742958db6533ca59 ] In https://lore.kernel.org/lkml/20211209150910.GA23668@axis.com/ Vincent's patch commented on, and worked around, a bug toggling static_branch's, when a 2nd PRINTK-ish flag was added. The bug results in a premature static_branch_disable when the 1st of 2 flags was disabled. The cited commit computed newflags, but then in the JUMP_LABEL block, failed to use that result, instead using just one of the terms in it. Using newflags instead made the code work properly. This is Vincents test-case, reduced. It needs the 2nd flag to demonstrate the bug, but it's explanatory here. pt_test() { echo 5 > /sys/module/dynamic_debug/verbose site="module tcp" # just one callsite echo " $site =_ " > /proc/dynamic_debug/control # clear it # A B ~A ~B for flg in +T +p "-T #broke here" -p; do echo " $site $flg " > /proc/dynamic_debug/control done; # A B ~B ~A for flg in +T +p "-p #broke here" -T; do echo " $site $flg " > /proc/dynamic_debug/control done } pt_test Fixes: 84da83a6ffc0 dyndbg: combine flags & mask into a struct, simplify with it CC: vincent.whitchurch@axis.com Acked-by: Jason Baron Acked-by: Daniel Vetter Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20220904214134.408619-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- lib/dynamic_debug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 84c16309cc63..00e6507972d8 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -207,10 +207,11 @@ static int ddebug_change(const struct ddebug_query *query, continue; #ifdef CONFIG_JUMP_LABEL if (dp->flags & _DPRINTK_FLAGS_PRINT) { - if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT)) + if (!(newflags & _DPRINTK_FLAGS_PRINT)) static_branch_disable(&dp->key.dd_key_true); - } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT) + } else if (newflags & _DPRINTK_FLAGS_PRINT) { static_branch_enable(&dp->key.dd_key_true); + } #endif dp->flags = newflags; v2pr_info("changed %s:%d [%s]%s =%s\n", From 0c0d9f38b0876613eba7ac1b7dc92cb384a83285 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Sun, 4 Sep 2022 15:40:39 -0600 Subject: [PATCH 298/610] dyndbg: fix module.dyndbg handling [ Upstream commit 85d6b66d31c35158364058ee98fb69ab5bb6a6b1 ] For CONFIG_DYNAMIC_DEBUG=N, the ddebug_dyndbg_module_param_cb() stub-fn is too permissive: bash-5.1# modprobe drm JUNKdyndbg bash-5.1# modprobe drm dyndbgJUNK [ 42.933220] dyndbg param is supported only in CONFIG_DYNAMIC_DEBUG builds [ 42.937484] ACPI: bus type drm_connector registered This caused no ill effects, because unknown parameters are either ignored by default with an "unknown parameter" warning, or ignored because dyndbg allows its no-effect use on non-dyndbg builds. But since the code has an explicit feedback message, it should be issued accurately. Fix with strcmp for exact param-name match. Fixes: b48420c1d301 dynamic_debug: make dynamic-debug work for module initialization Reported-by: Rasmus Villemoes Acked-by: Jason Baron Acked-by: Daniel Vetter Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20220904214134.408619-3-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/dynamic_debug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index dce631e678dd..f30b01aa9fa4 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -201,7 +201,7 @@ static inline int ddebug_remove_module(const char *mod) static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *modname) { - if (strstr(param, "dyndbg")) { + if (!strcmp(param, "dyndbg")) { /* avoid pr_warn(), which wants pr_fmt() fully defined */ printk(KERN_WARNING "dyndbg param is supported only in " "CONFIG_DYNAMIC_DEBUG builds\n"); From 0d4421f2cb544d12e5225317984b890125f14b06 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Sun, 4 Sep 2022 15:40:44 -0600 Subject: [PATCH 299/610] dyndbg: let query-modname override actual module name [ Upstream commit e75ef56f74965f426dd819a41336b640ffdd8fbc ] dyndbg's control-parser: ddebug_parse_query(), requires that search terms: module, func, file, lineno, are used only once in a query; a thing cannot be named both foo and bar. The cited commit added an overriding module modname, taken from the module loader, which is authoritative. So it set query.module 1st, which disallowed its use in the query-string. But now, its useful to allow a module-load to enable classes across a whole (or part of) a subsystem at once. # enable (dynamic-debug in) drm only modprobe drm dyndbg="class DRM_UT_CORE +p" # get drm_helper too modprobe drm dyndbg="class DRM_UT_CORE module drm* +p" # get everything that knows DRM_UT_CORE modprobe drm dyndbg="class DRM_UT_CORE module * +p" # also for boot-args: drm.dyndbg="class DRM_UT_CORE module * +p" So convert the override into a default, by filling it only when/after the query-string omitted the module. NB: the query class FOO handling is forthcoming. Fixes: 8e59b5cfb9a6 dynamic_debug: add modname arg to exec_query callchain Acked-by: Jason Baron Acked-by: Daniel Vetter Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20220904214134.408619-8-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- lib/dynamic_debug.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 00e6507972d8..60d453974155 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -380,10 +380,6 @@ static int ddebug_parse_query(char *words[], int nwords, return -EINVAL; } - if (modname) - /* support $modname.dyndbg= */ - query->module = modname; - for (i = 0; i < nwords; i += 2) { char *keyword = words[i]; char *arg = words[i+1]; @@ -424,6 +420,13 @@ static int ddebug_parse_query(char *words[], int nwords, if (rc) return rc; } + if (!query->module && modname) + /* + * support $modname.dyndbg=, when + * not given in the query itself + */ + query->module = modname; + vpr_info_dq(query, "parsed"); return 0; } From aecb632674b7a5f4260aec8b2dd8089bd885a053 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Sun, 4 Sep 2022 15:40:46 -0600 Subject: [PATCH 300/610] dyndbg: drop EXPORTed dynamic_debug_exec_queries [ Upstream commit e26ef3af964acfea311403126acee8c56c89e26b ] This exported fn is unused, and will not be needed. Lets dump it. The export was added to let drm control pr_debugs, as part of using them to avoid drm_debug_enabled overheads. But its better to just implement the drm.debug bitmap interface, then its available for everyone. Fixes: a2d375eda771 ("dyndbg: refine export, rename to dynamic_debug_exec_queries()") Fixes: 4c0d77828d4f ("dyndbg: export ddebug_exec_queries") Acked-by: Jason Baron Acked-by: Daniel Vetter Signed-off-by: Jim Cromie Link: https://lore.kernel.org/r/20220904214134.408619-10-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/dynamic_debug.h | 9 --------- lib/dynamic_debug.c | 29 ----------------------------- 2 files changed, 38 deletions(-) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index f30b01aa9fa4..8d9eec5f6d8b 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -55,9 +55,6 @@ struct _ddebug { #if defined(CONFIG_DYNAMIC_DEBUG_CORE) -/* exported for module authors to exercise >control */ -int dynamic_debug_exec_queries(const char *query, const char *modname); - int ddebug_add_module(struct _ddebug *tab, unsigned int n, const char *modname); extern int ddebug_remove_module(const char *mod_name); @@ -221,12 +218,6 @@ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, rowsize, groupsize, buf, len, ascii); \ } while (0) -static inline int dynamic_debug_exec_queries(const char *query, const char *modname) -{ - pr_warn("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n"); - return 0; -} - #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */ #endif diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 60d453974155..2ca56c22a169 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -552,35 +552,6 @@ static int ddebug_exec_queries(char *query, const char *modname) return nfound; } -/** - * dynamic_debug_exec_queries - select and change dynamic-debug prints - * @query: query-string described in admin-guide/dynamic-debug-howto - * @modname: string containing module name, usually &module.mod_name - * - * This uses the >/proc/dynamic_debug/control reader, allowing module - * authors to modify their dynamic-debug callsites. The modname is - * canonically struct module.mod_name, but can also be null or a - * module-wildcard, for example: "drm*". - */ -int dynamic_debug_exec_queries(const char *query, const char *modname) -{ - int rc; - char *qry; /* writable copy of query */ - - if (!query) { - pr_err("non-null query/command string expected\n"); - return -EINVAL; - } - qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL); - if (!qry) - return -ENOMEM; - - rc = ddebug_exec_queries(qry, modname); - kfree(qry); - return rc; -} -EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries); - #define PREFIX_SIZE 64 static int remaining(int wrote) From a0e4ac69889196a46683bff6e334e93a828e59b8 Mon Sep 17 00:00:00 2001 From: Dang Huynh Date: Sun, 11 Sep 2022 00:02:07 +0700 Subject: [PATCH 301/610] clk: qcom: sm6115: Select QCOM_GDSC [ Upstream commit 50ee65dc512b9b5c4de354cf3b4dded34f46c571 ] While working on the Fxtec Pro1X device, this error shows up with my own minimal configuration: gcc-sm6115: probe of 1400000.clock-controller failed with error -38 The clock driver depends on CONFIG_QCOM_GDSC and after enabling that, the driver probes successfully. Signed-off-by: Dang Huynh Fixes: cbe63bfdc54f ("clk: qcom: Add Global Clock controller (GCC) Reviewed-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220910170207.1592220-1-danct12@riseup.net Signed-off-by: Sasha Levin --- drivers/clk/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 9ef007b3cf9b..6ba86cffc413 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -550,6 +550,7 @@ config SM_DISPCC_8250 config SM_GCC_6115 tristate "SM6115 and SM4250 Global Clock Controller" + select QCOM_GDSC help Support for the global clock controller on SM6115 and SM4250 devices. Say Y if you want to use peripheral devices such as UART, SPI, From 88263152ff5673d044960d7419f43d8a9f29c84b Mon Sep 17 00:00:00 2001 From: William Dean Date: Fri, 22 Jul 2022 17:16:44 +0800 Subject: [PATCH 302/610] mtd: devices: docg3: check the return value of devm_ioremap() in the probe [ Upstream commit 26e784433e6c65735cd6d93a8db52531970d9a60 ] The function devm_ioremap() in docg3_probe() can fail, so its return value should be checked. Fixes: 82402aeb8c81e ("mtd: docg3: Use devm_*() functions") Reported-by: Hacash Robot Signed-off-by: William Dean Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220722091644.2937953-1-williamsukatube@163.com Signed-off-by: Sasha Levin --- drivers/mtd/devices/docg3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 5b0ae5ddad74..27c08f22dec8 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1974,9 +1974,14 @@ static int __init docg3_probe(struct platform_device *pdev) dev_err(dev, "No I/O memory resource defined\n"); return ret; } - base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); ret = -ENOMEM; + base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); + if (!base) { + dev_err(dev, "devm_ioremap dev failed\n"); + return ret; + } + cascade = devm_kcalloc(dev, DOC_MAX_NBFLOORS, sizeof(*cascade), GFP_KERNEL); if (!cascade) From e4be7c9495c812141be42fd5f7757246feb59435 Mon Sep 17 00:00:00 2001 From: Liang He Date: Thu, 15 Sep 2022 17:35:06 +0800 Subject: [PATCH 303/610] phy: amlogic: phy-meson-axg-mipi-pcie-analog: Hold reference returned by of_get_parent() [ Upstream commit c4c349be07aeec5f397a349046dc5fc0f2657691 ] As the of_get_parent() will increase the refcount of the node->parent and the reference will be discarded, so we should hold the reference with which we can decrease the refcount when done. Fixes: 8eff8b4e22d9 ("phy: amlogic: phy-meson-axg-mipi-pcie-analog: add support for MIPI DSI analog") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220915093506.4009456-1-windhl@126.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c index 1027ece6ca12..a3e1108b736d 100644 --- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c @@ -197,7 +197,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) struct phy_provider *phy; struct device *dev = &pdev->dev; struct phy_axg_mipi_pcie_analog_priv *priv; - struct device_node *np = dev->of_node; + struct device_node *np = dev->of_node, *parent_np; struct regmap *map; int ret; @@ -206,7 +206,9 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) return -ENOMEM; /* Get the hhi system controller node */ - map = syscon_node_to_regmap(of_get_parent(dev->of_node)); + parent_np = of_get_parent(dev->of_node); + map = syscon_node_to_regmap(parent_np); + of_node_put(parent_np); if (IS_ERR(map)) { dev_err(dev, "failed to get HHI regmap\n"); From cbbf9cca47acd305268ec54265d3ba3faaacb878 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Wed, 14 Sep 2022 14:07:46 +0800 Subject: [PATCH 304/610] phy: phy-mtk-tphy: fix the phy type setting issue [ Upstream commit 931c05a8cb1be029ef2fbc1e4af313d4cb297c47 ] The PHY type is not set if the index is non zero, prepare type value according to the index, like as mask value. Fixes: 39099a443358 ("phy: phy-mtk-tphy: support type switch by pericfg") Signed-off-by: Chunfeng Yun Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220914060746.10004-7-chunfeng.yun@mediatek.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/mediatek/phy-mtk-tphy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index db39b0c4649a..0649c08fe310 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -1039,7 +1039,7 @@ static int phy_type_syscon_get(struct mtk_phy_instance *instance, static int phy_type_set(struct mtk_phy_instance *instance) { int type; - u32 mask; + u32 offset; if (!instance->type_sw) return 0; @@ -1062,8 +1062,9 @@ static int phy_type_set(struct mtk_phy_instance *instance) return 0; } - mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE); - regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type); + offset = instance->type_sw_index * BITS_PER_BYTE; + regmap_update_bits(instance->type_sw, instance->type_sw_reg, + RG_PHY_SW_TYPE << offset, type << offset); return 0; } From 445395900b642602522c6dd73cc81e93727a7552 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 3 Jul 2022 01:12:22 +0200 Subject: [PATCH 305/610] mtd: rawnand: intel: Read the chip-select line from the correct OF node [ Upstream commit bfc618fcc3f167ad082053e81e9d664e724c6288 ] The chip select has to be read from the flash node which is a child node of the NAND controller. Fixes: 0b1039f016e8a3 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") Signed-off-by: Martin Blumenstingl Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-4-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/intel-nand-controller.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index e91b879b32bd..3df3f32423f9 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -580,6 +581,7 @@ static int ebu_nand_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ebu_nand_controller *ebu_host; + struct device_node *chip_np; struct nand_chip *nand; struct mtd_info *mtd; struct resource *res; @@ -604,7 +606,12 @@ static int ebu_nand_probe(struct platform_device *pdev) if (IS_ERR(ebu_host->hsnand)) return PTR_ERR(ebu_host->hsnand); - ret = device_property_read_u32(dev, "reg", &cs); + chip_np = of_get_next_child(dev->of_node, NULL); + if (!chip_np) + return dev_err_probe(dev, -EINVAL, + "Could not find child node for the NAND chip\n"); + + ret = of_property_read_u32(chip_np, "reg", &cs); if (ret) { dev_err(dev, "failed to get chip select: %d\n", ret); return ret; @@ -660,7 +667,7 @@ static int ebu_nand_probe(struct platform_device *pdev) writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN, ebu_host->ebu + EBU_ADDR_SEL(cs)); - nand_set_flash_node(&ebu_host->chip, dev->of_node); + nand_set_flash_node(&ebu_host->chip, chip_np); mtd = nand_to_mtd(&ebu_host->chip); if (!mtd->name) { From be424a7d53744f599d44a98df27ed2682e3d2268 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 3 Jul 2022 01:12:23 +0200 Subject: [PATCH 306/610] mtd: rawnand: intel: Remove undocumented compatible string [ Upstream commit 68c02ebaa34d41063ccbbc789a352537ddc3cd8a ] The "intel,nand-controller" compatible string is not part of the dt-bindings. Remove it from the driver as it's not supposed to be used without any documentation for it. Fixes: 0b1039f016e8a3 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") Signed-off-by: Martin Blumenstingl Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220702231227.1579176-5-martin.blumenstingl@googlemail.com Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/intel-nand-controller.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index 3df3f32423f9..056835fd4562 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -723,7 +723,6 @@ static int ebu_nand_remove(struct platform_device *pdev) } static const struct of_device_id ebu_nand_match[] = { - { .compatible = "intel,nand-controller" }, { .compatible = "intel,lgm-ebunand" }, {} }; From 84ce1a8e36bbd653ce2de2e6cfeb4e627b0ea80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 7 Jul 2022 20:43:28 +0200 Subject: [PATCH 307/610] mtd: rawnand: fsl_elbc: Fix none ECC mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 049e43b9fd8fd2966940485da163d67e96ee3fea ] Commit f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work") added support for specifying ECC mode via DTS and skipping autodetection. But it broke explicit specification of HW ECC mode in DTS as correct settings for HW ECC mode are applied only when NONE mode or nothing was specified in DTS file. Also it started aliasing NONE mode to be same as when ECC mode was not specified and disallowed usage of ON_DIE mode. Fix all these issues. Use autodetection of ECC mode only in case when mode was really not specified in DTS file by checking that ecc value is invalid. Set HW ECC settings either when HW ECC was specified in DTS or it was autodetected. And do not fail when ON_DIE mode is set. Fixes: f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work") Signed-off-by: Pali Rohár Reviewed-by: Marek Behún Reviewed-by: Marek Behún Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20220707184328.3845-1-pali@kernel.org Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/fsl_elbc_nand.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index aab93b9e6052..a18d121396aa 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c @@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip) struct fsl_lbc_regs __iomem *lbc = ctrl->regs; unsigned int al; - switch (chip->ecc.engine_type) { /* * if ECC was not chosen in DT, decide whether to use HW or SW ECC from * CS Base Register */ - case NAND_ECC_ENGINE_TYPE_NONE: + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) { /* If CS Base Register selects full hardware ECC then use it */ if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == BR_DECC_CHK_GEN) { - chip->ecc.read_page = fsl_elbc_read_page; - chip->ecc.write_page = fsl_elbc_write_page; - chip->ecc.write_subpage = fsl_elbc_write_subpage; - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; - mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); - chip->ecc.size = 512; - chip->ecc.bytes = 3; - chip->ecc.strength = 1; } else { /* otherwise fall back to default software ECC */ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; chip->ecc.algo = NAND_ECC_ALGO_HAMMING; } + } + + switch (chip->ecc.engine_type) { + /* if HW ECC was chosen, setup ecc and oob layout */ + case NAND_ECC_ENGINE_TYPE_ON_HOST: + chip->ecc.read_page = fsl_elbc_read_page; + chip->ecc.write_page = fsl_elbc_write_page; + chip->ecc.write_subpage = fsl_elbc_write_subpage; + mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); + chip->ecc.size = 512; + chip->ecc.bytes = 3; + chip->ecc.strength = 1; break; - /* if SW ECC was chosen in DT, we do not need to set anything here */ + /* if none or SW ECC was chosen, we do not need to set anything here */ + case NAND_ECC_ENGINE_TYPE_NONE: case NAND_ECC_ENGINE_TYPE_SOFT: + case NAND_ECC_ENGINE_TYPE_ON_DIE: break; - /* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */ default: return -EINVAL; } From dc9e4ef6b072cc448cac6f8a0229567731cf5356 Mon Sep 17 00:00:00 2001 From: Sindhu-Devale Date: Wed, 7 Sep 2022 14:13:23 -0500 Subject: [PATCH 308/610] RDMA/irdma: Align AE id codes to correct flush code and event [ Upstream commit 7f51a961f8c6b84752a48e950074a8c4a0808d91 ] A number of asynchronous event (AE) ids were not aligned to the correct flush_code and event_type. Fix these up so that the correct IBV error and event codes are returned to application. Also, add handling for new AE ids like IRDMA_AE_INVALID_REQUEST to return the correct WC error code. Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions") Signed-off-by: Sindhu-Devale Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20220907191324.1173-2-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/irdma/defs.h | 1 + drivers/infiniband/hw/irdma/hw.c | 53 +++++++++++++++++------------ drivers/infiniband/hw/irdma/type.h | 1 + drivers/infiniband/hw/irdma/user.h | 1 + drivers/infiniband/hw/irdma/utils.c | 3 ++ drivers/infiniband/hw/irdma/verbs.c | 2 ++ 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h index cc3d9a365b35..b8c10a6ccede 100644 --- a/drivers/infiniband/hw/irdma/defs.h +++ b/drivers/infiniband/hw/irdma/defs.h @@ -314,6 +314,7 @@ enum irdma_cqp_op_type { #define IRDMA_AE_IB_REMOTE_ACCESS_ERROR 0x020d #define IRDMA_AE_IB_REMOTE_OP_ERROR 0x020e #define IRDMA_AE_WQE_LSMM_TOO_LONG 0x0220 +#define IRDMA_AE_INVALID_REQUEST 0x0223 #define IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN 0x0301 #define IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER 0x0303 #define IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION 0x0304 diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c index 3d5d3f8d5ded..c14f19cff534 100644 --- a/drivers/infiniband/hw/irdma/hw.c +++ b/drivers/infiniband/hw/irdma/hw.c @@ -138,59 +138,68 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; switch (info->ae_id) { - case IRDMA_AE_AMP_UNALLOCATED_STAG: case IRDMA_AE_AMP_BOUNDS_VIOLATION: case IRDMA_AE_AMP_INVALID_STAG: - qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; - fallthrough; + case IRDMA_AE_AMP_RIGHTS_VIOLATION: + case IRDMA_AE_AMP_UNALLOCATED_STAG: case IRDMA_AE_AMP_BAD_PD: - case IRDMA_AE_UDA_XMIT_BAD_PD: - qp->flush_code = FLUSH_PROT_ERR; - break; case IRDMA_AE_AMP_BAD_QP: - case IRDMA_AE_WQE_UNEXPECTED_OPCODE: - qp->flush_code = FLUSH_LOC_QP_OP_ERR; - break; case IRDMA_AE_AMP_BAD_STAG_KEY: case IRDMA_AE_AMP_BAD_STAG_INDEX: case IRDMA_AE_AMP_TO_WRAP: - case IRDMA_AE_AMP_RIGHTS_VIOLATION: - case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS: case IRDMA_AE_PRIV_OPERATION_DENIED: - case IRDMA_AE_IB_INVALID_REQUEST: + qp->flush_code = FLUSH_PROT_ERR; + qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; + break; + case IRDMA_AE_UDA_XMIT_BAD_PD: + case IRDMA_AE_WQE_UNEXPECTED_OPCODE: + qp->flush_code = FLUSH_LOC_QP_OP_ERR; + qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; + break; + case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG: + case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT: + case IRDMA_AE_UDA_L4LEN_INVALID: + case IRDMA_AE_DDP_UBE_INVALID_MO: + case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER: + qp->flush_code = FLUSH_LOC_LEN_ERR; + qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; + break; + case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS: case IRDMA_AE_IB_REMOTE_ACCESS_ERROR: qp->flush_code = FLUSH_REM_ACCESS_ERR; qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; break; case IRDMA_AE_LLP_SEGMENT_TOO_SMALL: - case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER: - case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG: - case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT: - case IRDMA_AE_UDA_L4LEN_INVALID: + case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR: case IRDMA_AE_ROCE_RSP_LENGTH_ERROR: - qp->flush_code = FLUSH_LOC_LEN_ERR; + case IRDMA_AE_IB_REMOTE_OP_ERROR: + qp->flush_code = FLUSH_REM_OP_ERR; + qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; break; case IRDMA_AE_LCE_QP_CATASTROPHIC: qp->flush_code = FLUSH_FATAL_ERR; + qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; break; - case IRDMA_AE_DDP_UBE_INVALID_MO: case IRDMA_AE_IB_RREQ_AND_Q1_FULL: - case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR: qp->flush_code = FLUSH_GENERAL_ERR; break; case IRDMA_AE_LLP_TOO_MANY_RETRIES: qp->flush_code = FLUSH_RETRY_EXC_ERR; + qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; break; case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS: case IRDMA_AE_AMP_MWBIND_BIND_DISABLED: case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS: qp->flush_code = FLUSH_MW_BIND_ERR; + qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; break; - case IRDMA_AE_IB_REMOTE_OP_ERROR: - qp->flush_code = FLUSH_REM_OP_ERR; + case IRDMA_AE_IB_INVALID_REQUEST: + qp->flush_code = FLUSH_REM_INV_REQ_ERR; + qp->event_type = IRDMA_QP_EVENT_REQ_ERR; break; default: - qp->flush_code = FLUSH_FATAL_ERR; + qp->flush_code = FLUSH_GENERAL_ERR; + qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC; break; } } diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h index 874bc25a938b..1241e5988c10 100644 --- a/drivers/infiniband/hw/irdma/type.h +++ b/drivers/infiniband/hw/irdma/type.h @@ -99,6 +99,7 @@ enum irdma_term_mpa_errors { enum irdma_qp_event_type { IRDMA_QP_EVENT_CATASTROPHIC, IRDMA_QP_EVENT_ACCESS_ERR, + IRDMA_QP_EVENT_REQ_ERR, }; enum irdma_hw_stats_index_32b { diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h index 3dcbb1fbf2c6..7c3cb4288969 100644 --- a/drivers/infiniband/hw/irdma/user.h +++ b/drivers/infiniband/hw/irdma/user.h @@ -104,6 +104,7 @@ enum irdma_flush_opcode { FLUSH_FATAL_ERR, FLUSH_RETRY_EXC_ERR, FLUSH_MW_BIND_ERR, + FLUSH_REM_INV_REQ_ERR, }; enum irdma_cmpl_status { diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c index 85d4212f59db..db7d0a300069 100644 --- a/drivers/infiniband/hw/irdma/utils.c +++ b/drivers/infiniband/hw/irdma/utils.c @@ -2535,6 +2535,9 @@ void irdma_ib_qp_event(struct irdma_qp *iwqp, enum irdma_qp_event_type event) case IRDMA_QP_EVENT_ACCESS_ERR: ibevent.event = IB_EVENT_QP_ACCESS_ERR; break; + case IRDMA_QP_EVENT_REQ_ERR: + ibevent.event = IB_EVENT_QP_REQ_ERR; + break; } ibevent.device = iwqp->ibqp.device; ibevent.element.qp = &iwqp->ibqp; diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index 5275616398d8..911902d2b93e 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -3359,6 +3359,8 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcode return IB_WC_RETRY_EXC_ERR; case FLUSH_MW_BIND_ERR: return IB_WC_MW_BIND_ERR; + case FLUSH_REM_INV_REQ_ERR: + return IB_WC_REM_INV_REQ_ERR; case FLUSH_FATAL_ERR: default: return IB_WC_FATAL_ERR; From e58a0b9100ba288d9d3d9ce40d09e45ae86943db Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 8 Sep 2022 16:31:39 -0700 Subject: [PATCH 309/610] RDMA/srp: Fix srp_abort() [ Upstream commit 6dbe4a8dead84de474483910b02ec9e6a10fc1a9 ] Fix the code for converting a SCSI command pointer into an SRP request pointer. Cc: Xiao Yang Fixes: ad215aaea4f9 ("RDMA/srp: Make struct scsi_cmnd and struct srp_request adjacent") Signed-off-by: Bart Van Assche Link: https://lore.kernel.org/r/20220908233139.3042628-1-bvanassche@acm.org Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/ulp/srp/ib_srp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 473b3a08cf96..2f4991cea98c 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2783,7 +2783,7 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun, static int srp_abort(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); - struct srp_request *req = (struct srp_request *) scmnd->host_scribble; + struct srp_request *req = scsi_cmd_priv(scmnd); u32 tag; u16 ch_idx; struct srp_rdma_ch *ch; @@ -2791,8 +2791,6 @@ static int srp_abort(struct scsi_cmnd *scmnd) shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); - if (!req) - return SUCCESS; tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmnd)); ch_idx = blk_mq_unique_tag_to_hwq(tag); if (WARN_ON_ONCE(ch_idx >= target->ch_count)) From 308cd50f174c95a507527037f4de1a0396aa4325 Mon Sep 17 00:00:00 2001 From: Bernard Metzler Date: Tue, 20 Sep 2022 10:12:02 +0200 Subject: [PATCH 310/610] RDMA/siw: Always consume all skbuf data in sk_data_ready() upcall. [ Upstream commit 754209850df8367c954ac1de7671c7430b1f342c ] For header and trailer/padding processing, siw did not consume new skb data until minimum amount present to fill current header or trailer structure, including potential payload padding. Not consuming any data during upcall may cause a receive stall, since tcp_read_sock() is not upcalling again if no new data arrive. A NFSoRDMA client got stuck at RDMA Write reception of unaligned payload, if the current skb did contain only the expected 3 padding bytes, but not the 4 bytes CRC trailer. Expecting 4 more bytes already arrived in another skb, and not consuming those 3 bytes in the current upcall left the Write incomplete, waiting for the CRC forever. Fixes: 8b6a361b8c48 ("rdma/siw: receive path") Reported-by: Olga Kornievskaia Tested-by: Olga Kornievskaia Signed-off-by: Bernard Metzler Link: https://lore.kernel.org/r/20220920081202.223629-1-bmt@zurich.ibm.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/sw/siw/siw_qp_rx.c | 29 +++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c index 875ea6f1b04a..fd721cc19682 100644 --- a/drivers/infiniband/sw/siw/siw_qp_rx.c +++ b/drivers/infiniband/sw/siw/siw_qp_rx.c @@ -961,27 +961,28 @@ out: static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx) { struct sk_buff *skb = srx->skb; + int avail = min(srx->skb_new, srx->fpdu_part_rem); u8 *tbuf = (u8 *)&srx->trailer.crc - srx->pad; __wsum crc_in, crc_own = 0; siw_dbg_qp(qp, "expected %d, available %d, pad %u\n", srx->fpdu_part_rem, srx->skb_new, srx->pad); - if (srx->skb_new < srx->fpdu_part_rem) + skb_copy_bits(skb, srx->skb_offset, tbuf, avail); + + srx->skb_new -= avail; + srx->skb_offset += avail; + srx->skb_copied += avail; + srx->fpdu_part_rem -= avail; + + if (srx->fpdu_part_rem) return -EAGAIN; - skb_copy_bits(skb, srx->skb_offset, tbuf, srx->fpdu_part_rem); - - if (srx->mpa_crc_hd && srx->pad) - crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad); - - srx->skb_new -= srx->fpdu_part_rem; - srx->skb_offset += srx->fpdu_part_rem; - srx->skb_copied += srx->fpdu_part_rem; - if (!srx->mpa_crc_hd) return 0; + if (srx->pad) + crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad); /* * CRC32 is computed, transmitted and received directly in NBO, * so there's never a reason to convert byte order. @@ -1083,10 +1084,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx) * completely received. */ if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) { - bytes = iwarp_pktinfo[opcode].hdr_len - MIN_DDP_HDR; + int hdrlen = iwarp_pktinfo[opcode].hdr_len; - if (srx->skb_new < bytes) - return -EAGAIN; + bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new); skb_copy_bits(skb, srx->skb_offset, (char *)c_hdr + srx->fpdu_part_rcvd, bytes); @@ -1096,6 +1096,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx) srx->skb_new -= bytes; srx->skb_offset += bytes; srx->skb_copied += bytes; + + if (srx->fpdu_part_rcvd < hdrlen) + return -EAGAIN; } /* From 5c75d608fad58301b63e7d69200c13c3a1d411da Mon Sep 17 00:00:00 2001 From: Bernard Metzler Date: Tue, 20 Sep 2022 10:25:03 +0200 Subject: [PATCH 311/610] RDMA/siw: Fix QP destroy to wait for all references dropped. [ Upstream commit a3c278807a459e6f50afee6971cabe74cccfb490 ] Delay QP destroy completion until all siw references to QP are dropped. The calling RDMA core will free QP structure after successful return from siw_qp_destroy() call, so siw must not hold any remaining reference to the QP upon return. A use-after-free was encountered in xfstest generic/460, while testing NFSoRDMA. Here, after a TCP connection drop by peer, the triggered siw_cm_work_handler got delayed until after QP destroy call, referencing a QP which has already freed. Fixes: 303ae1cdfdf7 ("rdma/siw: application interface") Reported-by: Olga Kornievskaia Signed-off-by: Bernard Metzler Link: https://lore.kernel.org/r/20220920082503.224189-1-bmt@zurich.ibm.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/sw/siw/siw.h | 1 + drivers/infiniband/sw/siw/siw_qp.c | 2 +- drivers/infiniband/sw/siw/siw_verbs.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h index df03d84c6868..2f3a9cda3850 100644 --- a/drivers/infiniband/sw/siw/siw.h +++ b/drivers/infiniband/sw/siw/siw.h @@ -418,6 +418,7 @@ struct siw_qp { struct ib_qp base_qp; struct siw_device *sdev; struct kref ref; + struct completion qp_free; struct list_head devq; int tx_cpu; struct siw_qp_attrs attrs; diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c index 7e01f2438afc..e6f634971228 100644 --- a/drivers/infiniband/sw/siw/siw_qp.c +++ b/drivers/infiniband/sw/siw/siw_qp.c @@ -1342,6 +1342,6 @@ void siw_free_qp(struct kref *ref) vfree(qp->orq); siw_put_tx_cpu(qp->tx_cpu); - + complete(&qp->qp_free); atomic_dec(&sdev->num_qp); } diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c index aa3f60d54a70..ff33659acffa 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.c +++ b/drivers/infiniband/sw/siw/siw_verbs.c @@ -478,6 +478,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, list_add_tail(&qp->devq, &sdev->qp_list); spin_unlock_irqrestore(&sdev->lock, flags); + init_completion(&qp->qp_free); + return 0; err_out_xa: @@ -622,6 +624,7 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) qp->scq = qp->rcq = NULL; siw_qp_put(qp); + wait_for_completion(&qp->qp_free); return 0; } From 204cc767dcb581523f77dae5675b24187ee9713d Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Fri, 16 Sep 2022 14:28:32 +0200 Subject: [PATCH 312/610] ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() [ Upstream commit 690aa8c3ae308bc696ec8b1b357b995193927083 ] ACS-5 section 7.13.6.41 Words 85..87, 120: Commands and feature sets supported or enabled states that: If bit 15 of word 86 is set to one, bit 14 of word 119 is set to one, and bit 15 of word 119 is cleared to zero, then word 119 is valid. If bit 15 of word 86 is set to one, bit 14 of word 120 is set to one, and bit 15 of word 120 is cleared to zero, then word 120 is valid. (This text also exists in really old ACS standards, e.g. ACS-3.) Currently, ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() both check bit 15 of word 86, but neither of them check that bit 14 of word 119 is set to one, or that bit 15 of word 119 is cleared to zero. Additionally, make ata_id_sense_reporting_enabled() return false if !ata_id_has_sense_reporting(), similar to how e.g. ata_id_flush_ext_enabled() returns false if !ata_id_has_flush_ext(). Fixes: e87fd28cf9a2 ("libata: Implement support for sense data reporting") Signed-off-by: Niklas Cassel Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin --- include/linux/ata.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/include/linux/ata.h b/include/linux/ata.h index 1b44f40c7700..5d43716e5047 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -770,16 +770,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id) static inline bool ata_id_has_sense_reporting(const u16 *id) { - if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) + if (!(id[ATA_ID_CFS_ENABLE_2] & BIT(15))) return false; - return id[ATA_ID_COMMAND_SET_3] & (1 << 6); + if ((id[ATA_ID_COMMAND_SET_3] & (BIT(15) | BIT(14))) != BIT(14)) + return false; + return id[ATA_ID_COMMAND_SET_3] & BIT(6); } static inline bool ata_id_sense_reporting_enabled(const u16 *id) { - if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15))) + if (!ata_id_has_sense_reporting(id)) return false; - return id[ATA_ID_COMMAND_SET_4] & (1 << 6); + /* ata_id_has_sense_reporting() == true, word 86 must have bit 15 set */ + if ((id[ATA_ID_COMMAND_SET_4] & (BIT(15) | BIT(14))) != BIT(14)) + return false; + return id[ATA_ID_COMMAND_SET_4] & BIT(6); } /** From 21faddeff7bfc0074a425dd3f448635924c81717 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Fri, 16 Sep 2022 14:28:33 +0200 Subject: [PATCH 313/610] ata: fix ata_id_has_devslp() [ Upstream commit 9c6e09a434e1317e09b78b3b69cd384022ec9a03 ] ACS-5 section 7.13.6.36 Word 78: Serial ATA features supported states that: If word 76 is not 0000h or FFFFh, word 78 reports the features supported by the device. If this word is not supported, the word shall be cleared to zero. (This text also exists in really old ACS standards, e.g. ACS-3.) Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros (which already have this check), thus making it more likely that the next ATA_ID_FEATURE_SUPP macro that is added will include this check. Fixes: 65fe1f0f66a5 ("ahci: implement aggressive SATA device sleep support") Signed-off-by: Niklas Cassel Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin --- include/linux/ata.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/ata.h b/include/linux/ata.h index 5d43716e5047..0dab64eb5cbc 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -565,6 +565,10 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2))) +#define ata_id_has_devslp(id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))) #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) #define ata_id_u32(id,n) \ @@ -577,7 +581,6 @@ struct ata_bmdma_prd { #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) -#define ata_id_has_devslp(id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)) #define ata_id_has_ncq_autosense(id) \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)) From dad910a6d4a52330c6322f9e4834b99c78381e7b Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Fri, 16 Sep 2022 14:28:34 +0200 Subject: [PATCH 314/610] ata: fix ata_id_has_ncq_autosense() [ Upstream commit a5fb6bf853148974dbde092ec1bde553bea5e49f ] ACS-5 section 7.13.6.36 Word 78: Serial ATA features supported states that: If word 76 is not 0000h or FFFFh, word 78 reports the features supported by the device. If this word is not supported, the word shall be cleared to zero. (This text also exists in really old ACS standards, e.g. ACS-3.) Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros (which already have this check), thus making it more likely that the next ATA_ID_FEATURE_SUPP macro that is added will include this check. Fixes: 5b01e4b9efa0 ("libata: Implement NCQ autosense") Signed-off-by: Niklas Cassel Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin --- include/linux/ata.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/linux/ata.h b/include/linux/ata.h index 0dab64eb5cbc..295a6c6b506d 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -569,6 +569,10 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))) +#define ata_id_has_ncq_autosense(id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))) #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) #define ata_id_u32(id,n) \ @@ -581,8 +585,6 @@ struct ata_bmdma_prd { #define ata_id_cdb_intr(id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20) #define ata_id_has_da(id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) -#define ata_id_has_ncq_autosense(id) \ - ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)) static inline bool ata_id_has_hipm(const u16 *id) { From 058833dbeb8d95745435cdb4f4d2bf2ff73d63cf Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Fri, 16 Sep 2022 14:28:35 +0200 Subject: [PATCH 315/610] ata: fix ata_id_has_dipm() [ Upstream commit 630624cb1b5826d753ac8e01a0e42de43d66dedf ] ACS-5 section 7.13.6.36 Word 78: Serial ATA features supported states that: If word 76 is not 0000h or FFFFh, word 78 reports the features supported by the device. If this word is not supported, the word shall be cleared to zero. (This text also exists in really old ACS standards, e.g. ACS-3.) The problem with ata_id_has_dipm() is that the while it performs a check against 0 and 0xffff, it performs the check against ATA_ID_FEATURE_SUPP (word 78), the same word where the feature bit is stored. Fix this by performing the check against ATA_ID_SATA_CAPABILITY (word 76), like required by the spec. The feature bit check itself is of course still performed against ATA_ID_FEATURE_SUPP (word 78). Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros (which already have this check), thus making it more likely that the next ATA_ID_FEATURE_SUPP macro that is added will include this check. Fixes: ca77329fb713 ("[libata] Link power management infrastructure") Signed-off-by: Niklas Cassel Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin --- include/linux/ata.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/include/linux/ata.h b/include/linux/ata.h index 295a6c6b506d..3b1ad57d0e01 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -573,6 +573,10 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))) +#define ata_id_has_dipm(id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 3))) #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10)) #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11)) #define ata_id_u32(id,n) \ @@ -596,17 +600,6 @@ static inline bool ata_id_has_hipm(const u16 *id) return val & (1 << 9); } -static inline bool ata_id_has_dipm(const u16 *id) -{ - u16 val = id[ATA_ID_FEATURE_SUPP]; - - if (val == 0 || val == 0xffff) - return false; - - return val & (1 << 3); -} - - static inline bool ata_id_has_fua(const u16 *id) { if ((id[ATA_ID_CFSSE] & 0xC000) != 0x4000) From 9e92d5ca5424ad9226996bd78f5a3126896022a5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Jul 2022 10:12:12 +0300 Subject: [PATCH 316/610] mtd: rawnand: meson: fix bit map use in meson_nfc_ecc_correct() [ Upstream commit 3e4ad3212cf22687410b1e8f4e68feec50646113 ] The meson_nfc_ecc_correct() function accidentally does a right shift instead of a left shift so it only works for BIT(0). Also use BIT_ULL() because "correct_bitmap" is a u64 and we want to avoid shift wrapping bugs. Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller") Signed-off-by: Dan Carpenter Acked-by: Liang Yang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/YuI2zF1hP65+LE7r@kili Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/meson_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index 032180183339..b97adeee4cc1 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -454,7 +454,7 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) { mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); *bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info)); - *correct_bitmap |= 1 >> i; + *correct_bitmap |= BIT_ULL(i); continue; } if ((nand->options & NAND_NEED_SCRAMBLING) && @@ -800,7 +800,7 @@ static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, u8 *data = buf + i * ecc->size; u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); - if (correct_bitmap & (1 << i)) + if (correct_bitmap & BIT_ULL(i)) continue; ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, ecc->bytes + 2, From 5d8259c9d1915a50c60c7d6e9e7fb9b7da64a175 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Tue, 23 Aug 2022 11:51:04 -0700 Subject: [PATCH 317/610] md: Replace snprintf with scnprintf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 1727fd5015d8f93474148f94e34cda5aa6ad4a43 ] Current code produces a warning as shown below when total characters in the constituent block device names plus the slashes exceeds 200. snprintf() returns the number of characters generated from the given input, which could cause the expression “200 – len” to wrap around to a large positive number. Fix this by using scnprintf() instead, which returns the actual number of characters written into the buffer. [ 1513.267938] ------------[ cut here ]------------ [ 1513.267943] WARNING: CPU: 15 PID: 37247 at /lib/vsprintf.c:2509 vsnprintf+0x2c8/0x510 [ 1513.267944] Modules linked in: [ 1513.267969] CPU: 15 PID: 37247 Comm: mdadm Not tainted 5.4.0-1085-azure #90~18.04.1-Ubuntu [ 1513.267969] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 05/09/2022 [ 1513.267971] RIP: 0010:vsnprintf+0x2c8/0x510 <-snip-> [ 1513.267982] Call Trace: [ 1513.267986] snprintf+0x45/0x70 [ 1513.267990] ? disk_name+0x71/0xa0 [ 1513.267993] dump_zones+0x114/0x240 [raid0] [ 1513.267996] ? _cond_resched+0x19/0x40 [ 1513.267998] raid0_run+0x19e/0x270 [raid0] [ 1513.268000] md_run+0x5e0/0xc50 [ 1513.268003] ? security_capable+0x3f/0x60 [ 1513.268005] do_md_run+0x19/0x110 [ 1513.268006] md_ioctl+0x195e/0x1f90 [ 1513.268007] blkdev_ioctl+0x91f/0x9f0 [ 1513.268010] block_ioctl+0x3d/0x50 [ 1513.268012] do_vfs_ioctl+0xa9/0x640 [ 1513.268014] ? __fput+0x162/0x260 [ 1513.268016] ksys_ioctl+0x75/0x80 [ 1513.268017] __x64_sys_ioctl+0x1a/0x20 [ 1513.268019] do_syscall_64+0x5e/0x200 [ 1513.268021] entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 766038846e875 ("md/raid0: replace printk() with pr_*()") Reviewed-by: Michael Kelley Acked-by: Guoqing Jiang Signed-off-by: Saurabh Sengar Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/raid0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 8495045eb989..c16fa65a3ffd 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -48,7 +48,7 @@ static void dump_zones(struct mddev *mddev) int len = 0; for (k = 0; k < conf->strip_zone[j].nb_dev; k++) - len += snprintf(line+len, 200-len, "%s%s", k?"/":"", + len += scnprintf(line+len, 200-len, "%s%s", k?"/":"", bdevname(conf->devlist[j*raid_disks + k]->bdev, b)); pr_debug("md: zone%d=[%s]\n", j, line); From b467d9460ec2120f9fecbe9454c2a19835eb3c0e Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 25 Aug 2022 09:46:27 -0600 Subject: [PATCH 318/610] md/raid5: Ensure stripe_fill happens on non-read IO with journal [ Upstream commit e2eed85bc75138a9eeb63863d20f8904ac42a577 ] When doing degrade/recover tests using the journal a kernel BUG is hit at drivers/md/raid5.c:4381 in handle_parity_checks5(): BUG_ON(!test_bit(R5_UPTODATE, &dev->flags)); This was found to occur because handle_stripe_fill() was skipped for stripes in the journal due to a condition in that function. Thus blocks were not fetched and R5_UPTODATE was not set when the code reached handle_parity_checks5(). To fix this, don't skip handle_stripe_fill() unless the stripe is for read. Fixes: 07e83364845e ("md/r5cache: shift complex rmw from read path to write path") Link: https://lore.kernel.org/linux-raid/e05c4239-41a9-d2f7-3cfa-4aa9d2cea8c1@deltatee.com/ Suggested-by: Song Liu Signed-off-by: Logan Gunthorpe Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 19e497a7e747..dc63a544d670 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3936,7 +3936,7 @@ static void handle_stripe_fill(struct stripe_head *sh, * back cache (prexor with orig_page, and then xor with * page) in the read path */ - if (s->injournal && s->failed) { + if (s->to_read && s->injournal && s->failed) { if (test_bit(STRIPE_R5C_CACHING, &sh->state)) r5c_make_stripe_write_out(sh); goto out; From 7a37c58ee72e1fadd22c4ee990cb74c2ca2280e7 Mon Sep 17 00:00:00 2001 From: David Sloan Date: Thu, 8 Sep 2022 10:15:14 -0600 Subject: [PATCH 319/610] md/raid5: Remove unnecessary bio_put() in raid5_read_one_chunk() [ Upstream commit c66a6f41e09ad386fd2cce22b9cded837bbbc704 ] When running chunk-sized reads on disks with badblocks duplicate bio free/puts are observed: ============================================================================= BUG bio-200 (Not tainted): Object already free ----------------------------------------------------------------------------- Allocated in mempool_alloc_slab+0x17/0x20 age=3 cpu=2 pid=7504 __slab_alloc.constprop.0+0x5a/0xb0 kmem_cache_alloc+0x31e/0x330 mempool_alloc_slab+0x17/0x20 mempool_alloc+0x100/0x2b0 bio_alloc_bioset+0x181/0x460 do_mpage_readpage+0x776/0xd00 mpage_readahead+0x166/0x320 blkdev_readahead+0x15/0x20 read_pages+0x13f/0x5f0 page_cache_ra_unbounded+0x18d/0x220 force_page_cache_ra+0x181/0x1c0 page_cache_sync_ra+0x65/0xb0 filemap_get_pages+0x1df/0xaf0 filemap_read+0x1e1/0x700 blkdev_read_iter+0x1e5/0x330 vfs_read+0x42a/0x570 Freed in mempool_free_slab+0x17/0x20 age=3 cpu=2 pid=7504 kmem_cache_free+0x46d/0x490 mempool_free_slab+0x17/0x20 mempool_free+0x66/0x190 bio_free+0x78/0x90 bio_put+0x100/0x1a0 raid5_make_request+0x2259/0x2450 md_handle_request+0x402/0x600 md_submit_bio+0xd9/0x120 __submit_bio+0x11f/0x1b0 submit_bio_noacct_nocheck+0x204/0x480 submit_bio_noacct+0x32e/0xc70 submit_bio+0x98/0x1a0 mpage_readahead+0x250/0x320 blkdev_readahead+0x15/0x20 read_pages+0x13f/0x5f0 page_cache_ra_unbounded+0x18d/0x220 Slab 0xffffea000481b600 objects=21 used=0 fp=0xffff8881206d8940 flags=0x17ffffc0010201(locked|slab|head|node=0|zone=2|lastcpupid=0x1fffff) CPU: 0 PID: 34525 Comm: kworker/u24:2 Not tainted 6.0.0-rc2-localyes-265166-gf11c5343fa3f #143 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014 Workqueue: raid5wq raid5_do_work Call Trace: dump_stack_lvl+0x5a/0x78 dump_stack+0x10/0x16 print_trailer+0x158/0x165 object_err+0x35/0x50 free_debug_processing.cold+0xb7/0xbe __slab_free+0x1ae/0x330 kmem_cache_free+0x46d/0x490 mempool_free_slab+0x17/0x20 mempool_free+0x66/0x190 bio_free+0x78/0x90 bio_put+0x100/0x1a0 mpage_end_io+0x36/0x150 bio_endio+0x2fd/0x360 md_end_io_acct+0x7e/0x90 bio_endio+0x2fd/0x360 handle_failed_stripe+0x960/0xb80 handle_stripe+0x1348/0x3760 handle_active_stripes.constprop.0+0x72a/0xaf0 raid5_do_work+0x177/0x330 process_one_work+0x616/0xb20 worker_thread+0x2bd/0x6f0 kthread+0x179/0x1b0 ret_from_fork+0x22/0x30 The double free is caused by an unnecessary bio_put() in the if(is_badblock(...)) error path in raid5_read_one_chunk(). The error path was moved ahead of bio_alloc_clone() in c82aa1b76787c ("md/raid5: move checking badblock before clone bio in raid5_read_one_chunk"). The previous code checked and freed align_bio which required a bio_put. After the move that is no longer needed as raid_bio is returned to the control of the common io path which performs its own endio resulting in a double free on bad device blocks. Fixes: c82aa1b76787c ("md/raid5: move checking badblock before clone bio in raid5_read_one_chunk") Signed-off-by: David Sloan Signed-off-by: Logan Gunthorpe Reviewed-by: Christoph Hellwig Acked-by: Guoqing Jiang Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/raid5.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index dc63a544d670..03bfb70f54bf 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5430,7 +5430,6 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio) if (is_badblock(rdev, sector, bio_sectors(raid_bio), &first_bad, &bad_sectors)) { - bio_put(raid_bio); rdev_dec_pending(rdev, mddev); return 0; } From e221b4f16e9e1bb2c1efbb0a62cbd4505e9184b1 Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Thu, 8 Sep 2022 13:09:02 +0300 Subject: [PATCH 320/610] RDMA/cm: Use SLID in the work completion as the DLID in responder side [ Upstream commit b7d95040c13f61a4a6a859c5355faf583eff9658 ] The responder should always use WC's SLID as the dlid, to follow the IB SPEC section "13.5.4.2 COMMON RESPONSE ACTIONS": A responder always takes the following actions in constructing a response packet: - The SLID of the received packet is used as the DLID in the response packet. Fixes: ac3a949fb2ff ("IB/CM: Set appropriate slid and dlid when handling CM request") Signed-off-by: Mark Zhang Reviewed-by: Mark Bloch Link: https://lore.kernel.org/r/cd17c240231e059d2fc07c17dfe555d548b917eb.1662631201.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/core/cm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index b985e0d9bc05..5c910f5c01b3 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -1632,14 +1632,13 @@ static void cm_path_set_rec_type(struct ib_device *ib_device, u32 port_num, static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg, struct sa_path_rec *primary_path, - struct sa_path_rec *alt_path) + struct sa_path_rec *alt_path, + struct ib_wc *wc) { u32 lid; if (primary_path->rec_type != SA_PATH_REC_TYPE_OPA) { - sa_path_set_dlid(primary_path, - IBA_GET(CM_REQ_PRIMARY_LOCAL_PORT_LID, - req_msg)); + sa_path_set_dlid(primary_path, wc->slid); sa_path_set_slid(primary_path, IBA_GET(CM_REQ_PRIMARY_REMOTE_PORT_LID, req_msg)); @@ -1676,7 +1675,8 @@ static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg, static void cm_format_paths_from_req(struct cm_req_msg *req_msg, struct sa_path_rec *primary_path, - struct sa_path_rec *alt_path) + struct sa_path_rec *alt_path, + struct ib_wc *wc) { primary_path->dgid = *IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg); @@ -1734,7 +1734,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg, if (sa_path_is_roce(alt_path)) alt_path->roce.route_resolved = false; } - cm_format_path_lid_from_req(req_msg, primary_path, alt_path); + cm_format_path_lid_from_req(req_msg, primary_path, alt_path, wc); } static u16 cm_get_bth_pkey(struct cm_work *work) @@ -2148,7 +2148,7 @@ static int cm_req_handler(struct cm_work *work) if (cm_req_has_alt_path(req_msg)) work->path[1].rec_type = work->path[0].rec_type; cm_format_paths_from_req(req_msg, &work->path[0], - &work->path[1]); + &work->path[1], work->mad_recv_wc->wc); if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE) sa_path_set_dmac(&work->path[0], cm_id_priv->av.ah_attr.roce.dmac); From 4d7d8f5cb28443cafef073a3733ce658d2694787 Mon Sep 17 00:00:00 2001 From: Daisuke Matsuda Date: Wed, 21 Sep 2022 17:08:43 +0900 Subject: [PATCH 321/610] IB: Set IOVA/LENGTH on IB_MR in core/uverbs layers [ Upstream commit 241f9a27e0fc0eaf23e3d52c8450f10648cd11f1 ] Set 'iova' and 'length' on ib_mr in ib_uverbs and ib_core layers to let all drivers have the members filled. Also, this commit removes redundancy in the respective drivers. Previously, commit 04c0a5fcfcf65 ("IB/uverbs: Set IOVA on IB MR in uverbs layer") changed to set 'iova', but seems to have missed 'length' and the ib_core layer at that time. Fixes: 04c0a5fcfcf65 ("IB/uverbs: Set IOVA on IB MR in uverbs layer") Signed-off-by: Daisuke Matsuda Link: https://lore.kernel.org/r/20220921080844.1616883-1-matsuda-daisuke@fujitsu.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/core/uverbs_cmd.c | 5 ++++- drivers/infiniband/core/verbs.c | 2 ++ drivers/infiniband/hw/hns/hns_roce_mr.c | 1 - drivers/infiniband/hw/mlx4/mr.c | 1 - 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index d1345d76d9b1..9f0e0402fbc0 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -739,6 +739,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs) mr->uobject = uobj; atomic_inc(&pd->usecnt); mr->iova = cmd.hca_va; + mr->length = cmd.length; rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR); rdma_restrack_set_name(&mr->res, NULL); @@ -861,8 +862,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) mr->pd = new_pd; atomic_inc(&new_pd->usecnt); } - if (cmd.flags & IB_MR_REREG_TRANS) + if (cmd.flags & IB_MR_REREG_TRANS) { mr->iova = cmd.hca_va; + mr->length = cmd.length; + } } memset(&resp, 0, sizeof(resp)); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 59e20936b800..b721085bb597 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -2157,6 +2157,8 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, mr->pd = pd; mr->dm = NULL; atomic_inc(&pd->usecnt); + mr->iova = virt_addr; + mr->length = length; rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR); rdma_restrack_parent_name(&mr->res, &pd->res); diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index 7089ac780291..20360df25771 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -272,7 +272,6 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_alloc_pbl; mr->ibmr.rkey = mr->ibmr.lkey = mr->key; - mr->ibmr.length = length; return &mr->ibmr; diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 04a67b481608..a40bf58bcdd3 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -439,7 +439,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_mr; mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; - mr->ibmr.length = length; mr->ibmr.page_size = 1U << shift; return &mr->ibmr; From ed2c66b752803d83c3059f7b2297ed23c26bb14d Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 21 Sep 2022 15:34:47 +0300 Subject: [PATCH 322/610] xhci: Don't show warning for reinit on known broken suspend [ Upstream commit 484d6f7aa3283d082c87654b7fe7a7f725423dfb ] commit 8b328f8002bc ("xhci: re-initialize the HC during resume if HCE was set") introduced a new warning message when the host controller error was set and re-initializing. This is expected behavior on some designs which already set `xhci->broken_suspend` so the new warning is alarming to some users. Modify the code to only show the warning if this was a surprising behavior to the XHCI driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216470 Fixes: 8b328f8002bc ("xhci: re-initialize the HC during resume if HCE was set") Reported-by: Artem S. Tashkinov Signed-off-by: Mario Limonciello Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20220921123450.671459-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3cac7e40456e..8c7710698428 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1165,7 +1165,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) /* re-initialize the HC on Restore Error, or Host Controller Error */ if (temp & (STS_SRE | STS_HCE)) { reinit_xhc = true; - xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp); + if (!xhci->broken_suspend) + xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp); } if (reinit_xhc) { From 1d05df7757f4114dd0e6be267cda745dc7527857 Mon Sep 17 00:00:00 2001 From: Albert Briscoe Date: Sun, 11 Sep 2022 15:37:55 -0700 Subject: [PATCH 323/610] usb: gadget: function: fix dangling pnp_string in f_printer.c [ Upstream commit 24b7ba2f88e04800b54d462f376512e8c41b8a3c ] When opts->pnp_string is changed with configfs, new memory is allocated for the string. It does not, however, update dev->pnp_string, even though the memory is freed. When rquesting the string, the host then gets old or corrupted data rather than the new string. The ieee 1284 id string should be allowed to change while the device is connected. The bug was introduced in commit fdc01cc286be ("usb: gadget: printer: Remove pnp_string static buffer"), which changed opts->pnp_string from a char[] to a char*. This patch changes dev->pnp_string from a char* to a char** pointing to opts->pnp_string. Fixes: fdc01cc286be ("usb: gadget: printer: Remove pnp_string static buffer") Signed-off-by: Albert Briscoe Link: https://lore.kernel.org/r/20220911223753.20417-1-albertsbriscoe@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/function/f_printer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index abec5c58f525..a881c69b1f2b 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -89,7 +89,7 @@ struct printer_dev { u8 printer_cdev_open; wait_queue_head_t wait; unsigned q_len; - char *pnp_string; /* We don't own memory! */ + char **pnp_string; /* We don't own memory! */ struct usb_function function; }; @@ -1000,16 +1000,16 @@ static int printer_func_setup(struct usb_function *f, if ((wIndex>>8) != dev->interface) break; - if (!dev->pnp_string) { + if (!*dev->pnp_string) { value = 0; break; } - value = strlen(dev->pnp_string); + value = strlen(*dev->pnp_string); buf[0] = (value >> 8) & 0xFF; buf[1] = value & 0xFF; - memcpy(buf + 2, dev->pnp_string, value); + memcpy(buf + 2, *dev->pnp_string, value); DBG(dev, "1284 PNP String: %x %s\n", value, - dev->pnp_string); + *dev->pnp_string); break; case GET_PORT_STATUS: /* Get Port Status */ @@ -1475,7 +1475,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi) kref_init(&dev->kref); ++opts->refcnt; dev->minor = opts->minor; - dev->pnp_string = opts->pnp_string; + dev->pnp_string = &opts->pnp_string; dev->q_len = opts->q_len; mutex_unlock(&opts->lock); From 6be8e565a4a60530797a974d0a3d0e30656166a1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 22 Sep 2022 14:22:47 +0300 Subject: [PATCH 324/610] drivers: serial: jsm: fix some leaks in probe [ Upstream commit 1d5859ef229e381f4db38dce8ed58e4bf862006b ] This error path needs to unwind instead of just returning directly. Fixes: 03a8482c17dd ("drivers: serial: jsm: Enable support for Digi Classic adapters") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/YyxFh1+lOeZ9WfKO@kili Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/jsm/jsm_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 0ea799bf8dbb..417a5b6bffc3 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -211,7 +211,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) break; default: - return -ENXIO; + rc = -ENXIO; + goto out_kfree_brd; } rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "JSM", brd); From a91a3c2d8db82fa4829cb37833d7cb9f36d8c00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Thu, 22 Sep 2022 10:00:05 +0300 Subject: [PATCH 325/610] serial: 8250: Toggle IER bits on only after irq has been set up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 039d4926379b1d1c17b51cf21c500a5eed86899e ] Invoking TIOCVHANGUP on 8250_mid port on Ice Lake-D and then reopening the port triggers these faults during serial8250_do_startup(): DMAR: DRHD: handling fault status reg 3 DMAR: [DMA Write NO_PASID] Request device [00:1a.0] fault addr 0x0 [fault reason 0x05] PTE Write access is not set If the IRQ hasn't been set up yet, the UART will have zeroes in its MSI address/data registers. Disabling the IRQ at the interrupt controller won't stop the UART from performing a DMA write to the address programmed in its MSI address register (zero) when it wants to signal an interrupt. The UARTs (in Ice Lake-D) implement PCI 2.1 style MSI without masking capability, so there is no way to mask the interrupt at the source PCI function level, except disabling the MSI capability entirely, but that would cause it to fall back to INTx# assertion, and the PCI specification prohibits disabling the MSI capability as a way to mask a function's interrupt service request. The MSI address register is zeroed by the hangup as the irq is freed. The interrupt is signalled during serial8250_do_startup() performing a THRE test that temporarily toggles THRI in IER. The THRE test currently occurs before UART's irq (and MSI address) is properly set up. Refactor serial8250_do_startup() such that irq is set up before the THRE test. The current irq setup code is intermixed with the timer setup code. As THRE test must be performed prior to the timer setup, extract it into own function and call it only after the THRE test. The ->setup_timer() needs to be part of the struct uart_8250_ops in order to not create circular dependency between 8250 and 8250_base modules. Fixes: 40b36daad0ac ("[PATCH] 8250 UART backup timer") Reported-by: Lennert Buytenhek Tested-by: Lennert Buytenhek Reviewed-by: Andy Shevchenko Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20220922070005.2965-1-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/8250/8250_core.c | 16 +++++++++++----- drivers/tty/serial/8250/8250_port.c | 8 +++++--- include/linux/serial_8250.h | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 30b7890645ac..c3348d5af922 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -300,10 +300,9 @@ static void serial8250_backup_timeout(struct timer_list *t) jiffies + uart_poll_timeout(&up->port) + HZ / 5); } -static int univ8250_setup_irq(struct uart_8250_port *up) +static void univ8250_setup_timer(struct uart_8250_port *up) { struct uart_port *port = &up->port; - int retval = 0; /* * The above check will only give an accurate result the first time @@ -324,10 +323,16 @@ static int univ8250_setup_irq(struct uart_8250_port *up) */ if (!port->irq) mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); - else - retval = serial_link_irq_chain(up); +} - return retval; +static int univ8250_setup_irq(struct uart_8250_port *up) +{ + struct uart_port *port = &up->port; + + if (port->irq) + return serial_link_irq_chain(up); + + return 0; } static void univ8250_release_irq(struct uart_8250_port *up) @@ -383,6 +388,7 @@ static struct uart_ops univ8250_port_ops; static const struct uart_8250_ops univ8250_driver_ops = { .setup_irq = univ8250_setup_irq, .release_irq = univ8250_release_irq, + .setup_timer = univ8250_setup_timer, }; static struct uart_8250_port serial8250_ports[UART_NR]; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index b07326b71834..ee457f5d504f 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2280,6 +2280,10 @@ int serial8250_do_startup(struct uart_port *port) if (port->irq && (up->port.flags & UPF_SHARE_IRQ)) up->port.irqflags |= IRQF_SHARED; + retval = up->ops->setup_irq(up); + if (retval) + goto out; + if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) { unsigned char iir1; @@ -2322,9 +2326,7 @@ int serial8250_do_startup(struct uart_port *port) } } - retval = up->ops->setup_irq(up); - if (retval) - goto out; + up->ops->setup_timer(up); /* * Now, initialize the UART diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 5db211f43b29..68abc6bdd891 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -74,6 +74,7 @@ struct uart_8250_port; struct uart_8250_ops { int (*setup_irq)(struct uart_8250_port *); void (*release_irq)(struct uart_8250_port *); + void (*setup_timer)(struct uart_8250_port *); }; struct uart_8250_em485 { From c4293def8860fd587a84400ccba5b49cec56e2c3 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Tue, 20 Sep 2022 19:17:03 +0800 Subject: [PATCH 326/610] tty: serial: fsl_lpuart: disable dma rx/tx use flags in lpuart_dma_shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 316ae95c175a7d770d1bfe4c011192712f57aa4a ] lpuart_dma_shutdown tears down lpuart dma, but lpuart_flush_buffer can still occur which in turn tries to access dma apis if lpuart_dma_tx_use flag is true. At this point since dma is torn down, these dma apis can abort. Set lpuart_dma_tx_use and the corresponding rx flag lpuart_dma_rx_use to false in lpuart_dma_shutdown so that dmas are not accessed after they are relinquished. Otherwise, when try to kill btattach, kernel may panic. This patch may fix this issue. root@imx8ulpevk:~# btattach -B /dev/ttyLP2 -S 115200 ^C[ 90.182296] Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP [ 90.189806] Modules linked in: moal(O) mlan(O) [ 90.194258] CPU: 0 PID: 503 Comm: btattach Tainted: G O 5.15.32-06136-g34eecdf2f9e4 #37 [ 90.203554] Hardware name: NXP i.MX8ULP 9X9 EVK (DT) [ 90.208513] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 90.215470] pc : fsl_edma3_disable_request+0x8/0x60 [ 90.220358] lr : fsl_edma3_terminate_all+0x34/0x20c [ 90.225237] sp : ffff800013f0bac0 [ 90.228548] x29: ffff800013f0bac0 x28: 0000000000000001 x27: ffff000008404800 [ 90.235681] x26: ffff000008404960 x25: ffff000008404a08 x24: ffff000008404a00 [ 90.242813] x23: ffff000008404a60 x22: 0000000000000002 x21: 0000000000000000 [ 90.249946] x20: ffff800013f0baf8 x19: ffff00000559c800 x18: 0000000000000000 [ 90.257078] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 [ 90.264211] x14: 0000000000000003 x13: 0000000000000000 x12: 0000000000000040 [ 90.271344] x11: ffff00000600c248 x10: ffff800013f0bb10 x9 : ffff000057bcb090 [ 90.278477] x8 : fffffc0000241a08 x7 : ffff00000534ee00 x6 : ffff000008404804 [ 90.285609] x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff0000055b3480 [ 90.292742] x2 : ffff8000135c0000 x1 : ffff00000534ee00 x0 : ffff00000559c800 [ 90.299876] Call trace: [ 90.302321] fsl_edma3_disable_request+0x8/0x60 [ 90.306851] lpuart_flush_buffer+0x40/0x160 [ 90.311037] uart_flush_buffer+0x88/0x120 [ 90.315050] tty_driver_flush_buffer+0x20/0x30 [ 90.319496] hci_uart_flush+0x44/0x90 [ 90.323162] +0x34/0x12c [ 90.327253] tty_ldisc_close+0x38/0x70 [ 90.331005] tty_ldisc_release+0xa8/0x190 [ 90.335018] tty_release_struct+0x24/0x8c [ 90.339022] tty_release+0x3ec/0x4c0 [ 90.342593] __fput+0x70/0x234 [ 90.345652] ____fput+0x14/0x20 [ 90.348790] task_work_run+0x84/0x17c [ 90.352455] do_exit+0x310/0x96c [ 90.355688] do_group_exit+0x3c/0xa0 [ 90.359259] __arm64_sys_exit_group+0x1c/0x20 [ 90.363609] invoke_syscall+0x48/0x114 [ 90.367362] el0_svc_common.constprop.0+0xd4/0xfc [ 90.372068] do_el0_svc+0x2c/0x94 [ 90.375379] el0_svc+0x28/0x80 [ 90.378438] el0t_64_sync_handler+0xa8/0x130 [ 90.382711] el0t_64_sync+0x1a0/0x1a4 [ 90.386376] Code: 17ffffda d503201f d503233f f9409802 (b9400041) [ 90.392467] ---[ end trace 2f60524b4a43f1f6 ]--- [ 90.397073] note: btattach[503] exited with preempt_count 1 [ 90.402636] Fixing recursive fault but reboot is needed! Fixes: 6250cc30c4c4 ("tty: serial: fsl_lpuart: Use scatter/gather DMA for Tx") Reviewed-by: Ilpo Järvinen Signed-off-by: Thara Gopinath Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20220920111703.1532-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/fsl_lpuart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index b6548b910d94..185dd417fc49 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1787,6 +1787,7 @@ 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; } if (sport->lpuart_dma_tx_use) { @@ -1795,6 +1796,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport) sport->dma_tx_in_progress = false; dmaengine_terminate_all(sport->dma_tx_chan); } + sport->lpuart_dma_tx_use = false; } if (sport->dma_tx_chan) From 433c33c554d764a8da41b56b8c6098d02c61fda9 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Wed, 14 Sep 2022 13:13:33 +0800 Subject: [PATCH 327/610] phy: qualcomm: call clk_disable_unprepare in the error handling [ Upstream commit c3966ced8eb8dc53b6c8d7f97d32cc8a2107d83e ] Smatch reports the following error: drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on() warn: 'uphy->cal_clk' from clk_prepare_enable() not released on lines: 58. drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on() warn: 'uphy->cal_sleep_clk' from clk_prepare_enable() not released on lines: 58. drivers/phy/qualcomm/phy-qcom-usb-hsic.c:82 qcom_usb_hsic_phy_power_on() warn: 'uphy->phy_clk' from clk_prepare_enable() not released on lines: 58. Fix this by calling proper clk_disable_unprepare calls. Fixes: 0b56e9a7e835 ("phy: Group vendor specific phy drivers") Signed-off-by: Dongliang Mu Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20220914051334.69282-1-dzm91@hust.edu.cn Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c index 04d18d52f700..d4741c2dbbb5 100644 --- a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c +++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c @@ -54,8 +54,10 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy) /* Configure pins for HSIC functionality */ pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT); - if (IS_ERR(pins_default)) - return PTR_ERR(pins_default); + if (IS_ERR(pins_default)) { + ret = PTR_ERR(pins_default); + goto err_ulpi; + } ret = pinctrl_select_state(uphy->pctl, pins_default); if (ret) From f19e5b7df54590c831f350381963f25585c8f7d5 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Mon, 12 Sep 2022 19:04:31 +0200 Subject: [PATCH 328/610] staging: vt6655: fix some erroneous memory clean-up loops [ Upstream commit 2a2db520e3ca5aafba7c211abfd397666c9b5f9d ] In some initialization functions of this driver, memory is allocated with 'i' acting as an index variable and increasing from 0. The commit in "Fixes" introduces some clean-up codes in case of allocation failure, which free memory in reverse order with 'i' decreasing to 0. However, there are some problems: - The case i=0 is left out. Thus memory is leaked. - In case memory allocation fails right from the start, the memory freeing loops will start with i=-1 and invalid memory locations will be accessed. One of these loops has been fixed in commit c8ff91535880 ("staging: vt6655: fix potential memory leak"). Fix the remaining erroneous loops. Link: https://lore.kernel.org/linux-staging/Yx9H1zSpxmNqx6Xc@kadam/ Fixes: 5341ee0adb17 ("staging: vt6655: check for memory allocation failures") Reported-by: Dan Carpenter Tested-by: Philipp Hortmann Signed-off-by: Nam Cao Link: https://lore.kernel.org/r/20220912170429.29852-1-namcaov@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/vt6655/device_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index d40c2ac14928..43e32360b6d9 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -565,7 +565,7 @@ err_free_rd: kfree(desc->rd_info); err_free_desc: - while (--i) { + while (i--) { desc = &priv->aRD0Ring[i]; device_free_rx_buf(priv, desc); kfree(desc->rd_info); @@ -611,7 +611,7 @@ err_free_rd: kfree(desc->rd_info); err_free_desc: - while (--i) { + while (i--) { desc = &priv->aRD1Ring[i]; device_free_rx_buf(priv, desc); kfree(desc->rd_info); @@ -716,7 +716,7 @@ static int device_init_td1_ring(struct vnt_private *priv) return 0; err_free_desc: - while (--i) { + while (i--) { desc = &priv->apTD1Rings[i]; kfree(desc->td_info); } From 60d14575d0baa9207e463c2d034dbc3f0a861337 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 16 Sep 2022 13:29:10 +0100 Subject: [PATCH 329/610] slimbus: qcom-ngd-ctrl: allow compile testing without QCOM_RPROC_COMMON [ Upstream commit e291691c69776ad278cd39dec2306dd39d681a9f ] The Qualcomm common remote-proc code (CONFIG_QCOM_RPROC_COMMON) has necessary stubs, so it is not needed for compile testing. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220916122910.170730-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 42992cf187e4 ("slimbus: qcom-ngd: Add error handling in of_qcom_slim_ngd_register") Signed-off-by: Sasha Levin --- drivers/slimbus/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig index 1235b7dc8496..2ed821f75816 100644 --- a/drivers/slimbus/Kconfig +++ b/drivers/slimbus/Kconfig @@ -22,7 +22,8 @@ config SLIM_QCOM_CTRL config SLIM_QCOM_NGD_CTRL tristate "Qualcomm SLIMbus Satellite Non-Generic Device Component" - depends on HAS_IOMEM && DMA_ENGINE && NET && QCOM_RPROC_COMMON + depends on HAS_IOMEM && DMA_ENGINE && NET + depends on QCOM_RPROC_COMMON || COMPILE_TEST depends on ARCH_QCOM || COMPILE_TEST select QCOM_QMI_HELPERS select QCOM_PDR_HELPERS From a5dba09338344937679b3fe62f5f5d04527ef4a5 Mon Sep 17 00:00:00 2001 From: "Guilherme G. Piccoli" Date: Fri, 9 Sep 2022 17:07:55 -0300 Subject: [PATCH 330/610] firmware: google: Test spinlock on panic path to avoid lockups [ Upstream commit 3e081438b8e639cc76ef1a5ce0c1bd8a154082c7 ] Currently the gsmi driver registers a panic notifier as well as reboot and die notifiers. The callbacks registered are called in atomic and very limited context - for instance, panic disables preemption and local IRQs, also all secondary CPUs (not executing the panic path) are shutdown. With that said, taking a spinlock in this scenario is a dangerous invitation for lockup scenarios. So, fix that by checking if the spinlock is free to acquire in the panic notifier callback - if not, bail-out and avoid a potential hang. Fixes: 74c5b31c6618 ("driver: Google EFI SMI") Cc: Andrew Morton Cc: Ard Biesheuvel Cc: David Gow Cc: Greg Kroah-Hartman Cc: Julius Werner Cc: Petr Mladek Reviewed-by: Evan Green Signed-off-by: Guilherme G. Piccoli Link: https://lore.kernel.org/r/20220909200755.189679-1-gpiccoli@igalia.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/firmware/google/gsmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c index adaa492c3d2d..4e2575dfeb90 100644 --- a/drivers/firmware/google/gsmi.c +++ b/drivers/firmware/google/gsmi.c @@ -681,6 +681,15 @@ static struct notifier_block gsmi_die_notifier = { static int gsmi_panic_callback(struct notifier_block *nb, unsigned long reason, void *arg) { + + /* + * Panic callbacks are executed with all other CPUs stopped, + * so we must not attempt to spin waiting for gsmi_dev.lock + * to be released. + */ + if (spin_is_locked(&gsmi_dev.lock)) + return NOTIFY_DONE; + gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC); return NOTIFY_DONE; } From 6a54f769748bd0b8dda61bb0796ba9cf22493ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 24 Sep 2022 12:43:24 +0200 Subject: [PATCH 331/610] serial: 8250: Fix restoring termios speed after suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 379a33786d489ab81885ff0b3935cfeb36137fea ] Since commit edc6afc54968 ("tty: switch to ktermios and new framework") termios speed is no longer stored only in c_cflag member but also in new additional c_ispeed and c_ospeed members. If BOTHER flag is set in c_cflag then termios speed is stored only in these new members. Since commit 027b57170bf8 ("serial: core: Fix initializing and restoring termios speed") termios speed is available also in struct console. So properly restore also c_ispeed and c_ospeed members after suspend to fix restoring termios speed which is not represented by Bnnn constant. Fixes: 4516d50aabed ("serial: 8250: Use canary to restart console after suspend") Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20220924104324.4035-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/8250/8250_port.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index ee457f5d504f..ec7846223f3a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -3318,8 +3318,13 @@ static void serial8250_console_restore(struct uart_8250_port *up) unsigned int baud, quot, frac = 0; termios.c_cflag = port->cons->cflag; - if (port->state->port.tty && termios.c_cflag == 0) + termios.c_ispeed = port->cons->ispeed; + termios.c_ospeed = port->cons->ospeed; + if (port->state->port.tty && termios.c_cflag == 0) { termios.c_cflag = port->state->port.tty->termios.c_cflag; + termios.c_ispeed = port->state->port.tty->termios.c_ispeed; + termios.c_ospeed = port->state->port.tty->termios.c_ospeed; + } baud = serial8250_get_baud_rate(port, &termios, NULL); quot = serial8250_get_divisor(port, baud, &frac); From e45a1516d2933703a4823d9db71e17c3abeba24f Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Tue, 20 Sep 2022 22:42:13 +0800 Subject: [PATCH 332/610] scsi: libsas: Fix use-after-free bug in smp_execute_task_sg() [ Upstream commit 46ba53c30666717cb06c2b3c5d896301cd00d0c0 ] When executing SMP task failed, the smp_execute_task_sg() calls del_timer() to delete "slow_task->timer". However, if the timer handler sas_task_internal_timedout() is running, the del_timer() in smp_execute_task_sg() will not stop it and a UAF will happen. The process is shown below: (thread 1) | (thread 2) smp_execute_task_sg() | sas_task_internal_timedout() ... | del_timer() | ... | ... sas_free_task(task) | kfree(task->slow_task) //FREE| | task->slow_task->... //USE Fix by calling del_timer_sync() in smp_execute_task_sg(), which makes sure the timer handler have finished before the "task->slow_task" is deallocated. Link: https://lore.kernel.org/r/20220920144213.10536-1-duoming@zju.edu.cn Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") Reviewed-by: Jason Yan Signed-off-by: Duoming Zhou Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/libsas/sas_expander.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index c2150a818423..9ae35631135d 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -85,7 +85,7 @@ static int smp_execute_task_sg(struct domain_device *dev, res = i->dft->lldd_execute_task(task, GFP_KERNEL); if (res) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); pr_notice("executing SMP task failed:%d\n", res); break; } From d6aafc21bef1b0221a6b5707488db2cd2e687241 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 16 Jun 2022 17:45:49 -0500 Subject: [PATCH 333/610] scsi: iscsi: Rename iscsi_conn_queue_work() [ Upstream commit 4b9f8ce4d5e823e42944c5a0a4842b0f936365ad ] Rename iscsi_conn_queue_work() to iscsi_conn_queue_xmit() to reflect that it handles queueing of xmits only. Link: https://lore.kernel.org/r/20220616224557.115234-2-michael.christie@oracle.com Reviewed-by: Lee Duncan Reviewed-by: Wu Bo Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()") Signed-off-by: Sasha Levin --- drivers/scsi/cxgbi/libcxgbi.c | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libiscsi.c | 12 ++++++------ include/scsi/libiscsi.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 32abdf0fa9aa..af281e271f88 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -1455,7 +1455,7 @@ void cxgbi_conn_tx_open(struct cxgbi_sock *csk) if (conn) { log_debug(1 << CXGBI_DBG_SOCK, "csk 0x%p, cid %d.\n", csk, conn->id); - iscsi_conn_queue_work(conn); + iscsi_conn_queue_xmit(conn); } } EXPORT_SYMBOL_GPL(cxgbi_conn_tx_open); diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 0e52c6499eaf..e7976785dae6 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -205,7 +205,7 @@ static void iscsi_sw_tcp_write_space(struct sock *sk) old_write_space(sk); ISCSI_SW_TCP_DBG(conn, "iscsi_write_space\n"); - iscsi_conn_queue_work(conn); + iscsi_conn_queue_xmit(conn); } static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 78de36250b31..1cb18b80d182 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -83,7 +83,7 @@ MODULE_PARM_DESC(debug_libiscsi_eh, "%s " dbg_fmt, __func__, ##arg); \ } while (0); -inline void iscsi_conn_queue_work(struct iscsi_conn *conn) +inline void iscsi_conn_queue_xmit(struct iscsi_conn *conn) { struct Scsi_Host *shost = conn->session->host; struct iscsi_host *ihost = shost_priv(shost); @@ -91,7 +91,7 @@ inline void iscsi_conn_queue_work(struct iscsi_conn *conn) if (ihost->workq) queue_work(ihost->workq, &conn->xmitwork); } -EXPORT_SYMBOL_GPL(iscsi_conn_queue_work); +EXPORT_SYMBOL_GPL(iscsi_conn_queue_xmit); static void __iscsi_update_cmdsn(struct iscsi_session *session, uint32_t exp_cmdsn, uint32_t max_cmdsn) @@ -765,7 +765,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto free_task; } else { list_add_tail(&task->running, &conn->mgmtqueue); - iscsi_conn_queue_work(conn); + iscsi_conn_queue_xmit(conn); } return task; @@ -1513,7 +1513,7 @@ void iscsi_requeue_task(struct iscsi_task *task) */ iscsi_put_task(task); } - iscsi_conn_queue_work(conn); + iscsi_conn_queue_xmit(conn); spin_unlock_bh(&conn->session->frwd_lock); } EXPORT_SYMBOL_GPL(iscsi_requeue_task); @@ -1782,7 +1782,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) } } else { list_add_tail(&task->running, &conn->cmdqueue); - iscsi_conn_queue_work(conn); + iscsi_conn_queue_xmit(conn); } session->queued_cmdsn++; @@ -1963,7 +1963,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_tx); static void iscsi_start_tx(struct iscsi_conn *conn) { clear_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); - iscsi_conn_queue_work(conn); + iscsi_conn_queue_xmit(conn); } /* diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index a071f6ffd7fa..ffffce144fdb 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -442,7 +442,7 @@ extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, enum iscsi_param param, char *buf); extern void iscsi_suspend_tx(struct iscsi_conn *conn); extern void iscsi_suspend_queue(struct iscsi_conn *conn); -extern void iscsi_conn_queue_work(struct iscsi_conn *conn); +extern void iscsi_conn_queue_xmit(struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ From c2af03a7c1b5f3cfa091718ce4f6cc572c112fff Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 16 Jun 2022 17:45:50 -0500 Subject: [PATCH 334/610] scsi: iscsi: Add recv workqueue helpers [ Upstream commit 8af809966c0b34cfacd8da9a412689b8e9910354 ] Add helpers to allow the drivers to run their recv paths from libiscsi's workqueue. Link: https://lore.kernel.org/r/20220616224557.115234-3-michael.christie@oracle.com Reviewed-by: Lee Duncan Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()") Signed-off-by: Sasha Levin --- drivers/scsi/libiscsi.c | 29 +++++++++++++++++++++++++++-- include/scsi/libiscsi.h | 4 ++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 1cb18b80d182..73d235540b98 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -93,6 +93,16 @@ inline void iscsi_conn_queue_xmit(struct iscsi_conn *conn) } EXPORT_SYMBOL_GPL(iscsi_conn_queue_xmit); +inline void iscsi_conn_queue_recv(struct iscsi_conn *conn) +{ + struct Scsi_Host *shost = conn->session->host; + struct iscsi_host *ihost = shost_priv(shost); + + if (ihost->workq && !test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags)) + queue_work(ihost->workq, &conn->recvwork); +} +EXPORT_SYMBOL_GPL(iscsi_conn_queue_recv); + static void __iscsi_update_cmdsn(struct iscsi_session *session, uint32_t exp_cmdsn, uint32_t max_cmdsn) { @@ -1943,7 +1953,7 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_queue); /** * iscsi_suspend_tx - suspend iscsi_data_xmit - * @conn: iscsi conn tp stop processing IO on. + * @conn: iscsi conn to stop processing IO on. * * This function sets the suspend bit to prevent iscsi_data_xmit * from sending new IO, and if work is queued on the xmit thread @@ -1956,7 +1966,7 @@ void iscsi_suspend_tx(struct iscsi_conn *conn) set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags); if (ihost->workq) - flush_workqueue(ihost->workq); + flush_work(&conn->xmitwork); } EXPORT_SYMBOL_GPL(iscsi_suspend_tx); @@ -1966,6 +1976,21 @@ static void iscsi_start_tx(struct iscsi_conn *conn) iscsi_conn_queue_xmit(conn); } +/** + * iscsi_suspend_rx - Prevent recvwork from running again. + * @conn: iscsi conn to stop. + */ +void iscsi_suspend_rx(struct iscsi_conn *conn) +{ + struct Scsi_Host *shost = conn->session->host; + struct iscsi_host *ihost = shost_priv(shost); + + set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, &conn->flags); + if (ihost->workq) + flush_work(&conn->recvwork); +} +EXPORT_SYMBOL_GPL(iscsi_suspend_rx); + /* * We want to make sure a ping is in flight. It has timed out. * And we are not busy processing a pdu that is making diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index ffffce144fdb..5cf84228b51d 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -201,6 +201,8 @@ struct iscsi_conn { struct list_head cmdqueue; /* data-path cmd queue */ struct list_head requeue; /* tasks needing another run */ struct work_struct xmitwork; /* per-conn. xmit workqueue */ + /* recv */ + struct work_struct recvwork; unsigned long flags; /* ISCSI_CONN_FLAGs */ /* negotiated params */ @@ -441,8 +443,10 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, enum iscsi_param param, char *buf); extern void iscsi_suspend_tx(struct iscsi_conn *conn); +extern void iscsi_suspend_rx(struct iscsi_conn *conn); extern void iscsi_suspend_queue(struct iscsi_conn *conn); extern void iscsi_conn_queue_xmit(struct iscsi_conn *conn); +extern void iscsi_conn_queue_recv(struct iscsi_conn *conn); #define iscsi_conn_printk(prefix, _c, fmt, a...) \ iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \ From e87fb1fcf88f4afd56b007d9163c3073b3d73f81 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 16 Jun 2022 17:45:51 -0500 Subject: [PATCH 335/610] scsi: iscsi: Run recv path from workqueue [ Upstream commit f1d269765ee29da56b32818b7a08054484ed89f2 ] We don't always want to run the recv path from the network softirq because when we have to have multiple sessions sharing the same CPUs, some sessions can eat up the NAPI softirq budget and affect other sessions or users. Allow us to queue the recv handling to the iscsi workqueue so we can have the scheduler/wq code try to balance the work and CPU use across all sessions' worker threads. Note: It wasn't the original intent of the change but a nice side effect is that for some workloads/configs we get a nice performance boost. For a simple read heavy test: fio --direct=1 --filename=/dev/dm-0 --rw=randread --bs=256K --ioengine=libaio --iodepth=128 --numjobs=4 where the iscsi threads, fio jobs, and rps_cpus share CPUs we see a 32% throughput boost. We also see increases for small I/O IOPs tests but it's not as high. Link: https://lore.kernel.org/r/20220616224557.115234-4-michael.christie@oracle.com Reviewed-by: Lee Duncan Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen Stable-dep-of: 57569c37f0ad ("scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()") Signed-off-by: Sasha Levin --- drivers/scsi/iscsi_tcp.c | 65 ++++++++++++++++++++++++++++++++-------- drivers/scsi/iscsi_tcp.h | 2 ++ 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index e7976785dae6..20b4394d560b 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -52,6 +52,10 @@ static struct iscsi_transport iscsi_sw_tcp_transport; static unsigned int iscsi_max_lun = ~0; module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); +static bool iscsi_recv_from_iscsi_q; +module_param_named(recv_from_iscsi_q, iscsi_recv_from_iscsi_q, bool, 0644); +MODULE_PARM_DESC(recv_from_iscsi_q, "Set to true to read iSCSI data/headers from the iscsi_q workqueue. The default is false which will perform reads from the network softirq context."); + static int iscsi_sw_tcp_dbg; module_param_named(debug_iscsi_tcp, iscsi_sw_tcp_dbg, int, S_IRUGO | S_IWUSR); @@ -122,20 +126,13 @@ static inline int iscsi_sw_sk_state_check(struct sock *sk) return 0; } -static void iscsi_sw_tcp_data_ready(struct sock *sk) +static void iscsi_sw_tcp_recv_data(struct iscsi_conn *conn) { - struct iscsi_conn *conn; - struct iscsi_tcp_conn *tcp_conn; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; + struct sock *sk = tcp_sw_conn->sock->sk; read_descriptor_t rd_desc; - read_lock_bh(&sk->sk_callback_lock); - conn = sk->sk_user_data; - if (!conn) { - read_unlock_bh(&sk->sk_callback_lock); - return; - } - tcp_conn = conn->dd_data; - /* * Use rd_desc to pass 'conn' to iscsi_tcp_recv. * We set count to 1 because we want the network layer to @@ -144,13 +141,48 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk) */ rd_desc.arg.data = conn; rd_desc.count = 1; - tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv); - iscsi_sw_sk_state_check(sk); + tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv); /* If we had to (atomically) map a highmem page, * unmap it now. */ iscsi_tcp_segment_unmap(&tcp_conn->in.segment); + + iscsi_sw_sk_state_check(sk); +} + +static void iscsi_sw_tcp_recv_data_work(struct work_struct *work) +{ + struct iscsi_conn *conn = container_of(work, struct iscsi_conn, + recvwork); + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; + struct sock *sk = tcp_sw_conn->sock->sk; + + lock_sock(sk); + iscsi_sw_tcp_recv_data(conn); + release_sock(sk); +} + +static void iscsi_sw_tcp_data_ready(struct sock *sk) +{ + struct iscsi_sw_tcp_conn *tcp_sw_conn; + struct iscsi_tcp_conn *tcp_conn; + struct iscsi_conn *conn; + + read_lock_bh(&sk->sk_callback_lock); + conn = sk->sk_user_data; + if (!conn) { + read_unlock_bh(&sk->sk_callback_lock); + return; + } + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + + if (tcp_sw_conn->queue_recv) + iscsi_conn_queue_recv(conn); + else + iscsi_sw_tcp_recv_data(conn); read_unlock_bh(&sk->sk_callback_lock); } @@ -276,6 +308,9 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn, if (segment->total_copied + segment->size < segment->total_size) flags |= MSG_MORE; + if (tcp_sw_conn->queue_recv) + flags |= MSG_DONTWAIT; + /* Use sendpage if we can; else fall back to sendmsg */ if (!segment->data) { sg = segment->sg; @@ -557,6 +592,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session, conn = cls_conn->dd_data; tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; + INIT_WORK(&conn->recvwork, iscsi_sw_tcp_recv_data_work); + tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) @@ -610,6 +647,8 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn) iscsi_sw_tcp_conn_restore_callbacks(conn); sock_put(sock->sk); + iscsi_suspend_rx(conn); + spin_lock_bh(&session->frwd_lock); tcp_sw_conn->sock = NULL; spin_unlock_bh(&session->frwd_lock); diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index 791453195099..850a018aefb9 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -28,6 +28,8 @@ struct iscsi_sw_tcp_send { struct iscsi_sw_tcp_conn { struct socket *sock; + struct work_struct recvwork; + bool queue_recv; struct iscsi_sw_tcp_send out; /* old values for socket callbacks */ From a26b0658751bb0a3b28386fca715333b104d32a2 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 7 Sep 2022 17:17:00 -0500 Subject: [PATCH 336/610] scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername() [ Upstream commit 57569c37f0add1b6489e1a1563c71519daf732cf ] Fix a NULL pointer crash that occurs when we are freeing the socket at the same time we access it via sysfs. The problem is that: 1. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() take the frwd_lock and do sock_hold() then drop the frwd_lock. sock_hold() does a get on the "struct sock". 2. iscsi_sw_tcp_release_conn() does sockfd_put() which does the last put on the "struct socket" and that does __sock_release() which sets the sock->ops to NULL. 3. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() then call kernel_getpeername() which accesses the NULL sock->ops. Above we do a get on the "struct sock", but we needed a get on the "struct socket". Originally, we just held the frwd_lock the entire time but in commit bcf3a2953d36 ("scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername()") we switched to refcount based because the network layer changed and started taking a mutex in that path, so we could no longer hold the frwd_lock. Instead of trying to maintain multiple refcounts, this just has us use a mutex for accessing the socket in the interface code paths. Link: https://lore.kernel.org/r/20220907221700.10302-1-michael.christie@oracle.com Fixes: bcf3a2953d36 ("scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername()") Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/iscsi_tcp.c | 73 ++++++++++++++++++++++++++++------------ drivers/scsi/iscsi_tcp.h | 3 ++ 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 20b4394d560b..4d2f33087806 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -595,6 +595,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session, INIT_WORK(&conn->recvwork, iscsi_sw_tcp_recv_data_work); tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; + mutex_init(&tcp_sw_conn->sock_lock); + tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) goto free_conn; @@ -629,11 +631,15 @@ free_conn: static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn) { - struct iscsi_session *session = conn->session; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; struct socket *sock = tcp_sw_conn->sock; + /* + * The iscsi transport class will make sure we are not called in + * parallel with start, stop, bind and destroys. However, this can be + * called twice if userspace does a stop then a destroy. + */ if (!sock) return; @@ -649,9 +655,9 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn) iscsi_suspend_rx(conn); - spin_lock_bh(&session->frwd_lock); + mutex_lock(&tcp_sw_conn->sock_lock); tcp_sw_conn->sock = NULL; - spin_unlock_bh(&session->frwd_lock); + mutex_unlock(&tcp_sw_conn->sock_lock); sockfd_put(sock); } @@ -703,7 +709,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, int is_leading) { - struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; @@ -723,10 +728,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, if (err) goto free_socket; - spin_lock_bh(&session->frwd_lock); + mutex_lock(&tcp_sw_conn->sock_lock); /* bind iSCSI connection and socket */ tcp_sw_conn->sock = sock; - spin_unlock_bh(&session->frwd_lock); + mutex_unlock(&tcp_sw_conn->sock_lock); /* setup Socket parameters */ sk = sock->sk; @@ -763,8 +768,15 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn, break; case ISCSI_PARAM_DATADGST_EN: iscsi_set_param(cls_conn, param, buf, buflen); + + mutex_lock(&tcp_sw_conn->sock_lock); + if (!tcp_sw_conn->sock) { + mutex_unlock(&tcp_sw_conn->sock_lock); + return -ENOTCONN; + } tcp_sw_conn->sendpage = conn->datadgst_en ? sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage; + mutex_unlock(&tcp_sw_conn->sock_lock); break; case ISCSI_PARAM_MAX_R2T: return iscsi_tcp_set_max_r2t(conn, buf); @@ -779,8 +791,8 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; + struct iscsi_sw_tcp_conn *tcp_sw_conn; + struct iscsi_tcp_conn *tcp_conn; struct sockaddr_in6 addr; struct socket *sock; int rc; @@ -790,21 +802,36 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, case ISCSI_PARAM_CONN_ADDRESS: case ISCSI_PARAM_LOCAL_PORT: spin_lock_bh(&conn->session->frwd_lock); - if (!tcp_sw_conn || !tcp_sw_conn->sock) { + if (!conn->session->leadconn) { spin_unlock_bh(&conn->session->frwd_lock); return -ENOTCONN; } - sock = tcp_sw_conn->sock; - sock_hold(sock->sk); + /* + * The conn has been setup and bound, so just grab a ref + * incase a destroy runs while we are in the net layer. + */ + iscsi_get_conn(conn->cls_conn); spin_unlock_bh(&conn->session->frwd_lock); + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + + mutex_lock(&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; + if (!sock) { + rc = -ENOTCONN; + goto sock_unlock; + } + if (param == ISCSI_PARAM_LOCAL_PORT) rc = kernel_getsockname(sock, (struct sockaddr *)&addr); else rc = kernel_getpeername(sock, (struct sockaddr *)&addr); - sock_put(sock->sk); +sock_unlock: + mutex_unlock(&tcp_sw_conn->sock_lock); + iscsi_put_conn(conn->cls_conn); if (rc < 0) return rc; @@ -842,17 +869,21 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, } tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; - sock = tcp_sw_conn->sock; - if (!sock) { - spin_unlock_bh(&session->frwd_lock); - return -ENOTCONN; - } - sock_hold(sock->sk); + /* + * The conn has been setup and bound, so just grab a ref + * incase a destroy runs while we are in the net layer. + */ + iscsi_get_conn(conn->cls_conn); spin_unlock_bh(&session->frwd_lock); - rc = kernel_getsockname(sock, - (struct sockaddr *)&addr); - sock_put(sock->sk); + mutex_lock(&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; + if (!sock) + rc = -ENOTCONN; + else + rc = kernel_getsockname(sock, (struct sockaddr *)&addr); + mutex_unlock(&tcp_sw_conn->sock_lock); + iscsi_put_conn(conn->cls_conn); if (rc < 0) return rc; diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index 850a018aefb9..68e14a344904 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -28,6 +28,9 @@ struct iscsi_sw_tcp_send { struct iscsi_sw_tcp_conn { struct socket *sock; + /* Taken when accessing the sock from the netlink/sysfs interface */ + struct mutex sock_lock; + struct work_struct recvwork; bool queue_recv; From 8e556f5573684b3d4126a4fea88141ee56a407ab Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 19 Aug 2022 00:06:22 +0200 Subject: [PATCH 337/610] clk: qcom: apss-ipq6018: mark apcs_alias0_core_clk as critical [ Upstream commit 86e78995c93ee182433f965babfccd48417d4dcf ] While fixing up the driver I noticed that my IPQ8074 board was hanging after CPUFreq switched the frequency during boot, WDT would eventually reset it. So mark apcs_alias0_core_clk as critical since its the clock feeding the CPU cluster and must never be disabled. Fixes: 5e77b4ef1b19 ("clk: qcom: Add ipq6018 apss clock controller") Signed-off-by: Robert Marko Reviewed-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220818220628.339366-3-robimarko@gmail.com Signed-off-by: Sasha Levin --- drivers/clk/qcom/apss-ipq6018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c index d78ff2f310bf..b5d93657e1ee 100644 --- a/drivers/clk/qcom/apss-ipq6018.c +++ b/drivers/clk/qcom/apss-ipq6018.c @@ -57,7 +57,7 @@ static struct clk_branch apcs_alias0_core_clk = { .parent_hws = (const struct clk_hw *[]){ &apcs_alias0_clk_src.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, From 959d4ee095e9816b722c76e3f127b0893d9444d6 Mon Sep 17 00:00:00 2001 From: Adam Skladowski Date: Tue, 30 Aug 2022 10:56:18 +0300 Subject: [PATCH 338/610] clk: qcom: gcc-sm6115: Override default Alpha PLL regs [ Upstream commit 068a0605ef5a6b430e7278c169bfcd25b680b28f ] The DEFAULT and BRAMMO PLL offsets are non-standard in downstream, but currently only BRAMMO ones are overridden. Override DEFAULT ones too. A very similar thing is happening in gcc-qcm2290 driver. Fixes: cbe63bfdc54f ("clk: qcom: Add Global Clock controller (GCC) driver for SM6115") Signed-off-by: Adam Skladowski Signed-off-by: Iskren Chernev Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220830075620.974009-2-iskren.chernev@gmail.com Signed-off-by: Sasha Levin --- drivers/clk/qcom/gcc-sm6115.c | 46 +++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c index 68fe9f6f0d2f..e24a977c2580 100644 --- a/drivers/clk/qcom/gcc-sm6115.c +++ b/drivers/clk/qcom/gcc-sm6115.c @@ -53,11 +53,25 @@ static struct pll_vco gpll10_vco[] = { { 750000000, 1500000000, 1 }, }; +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_DEFAULT] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_ALPHA_VAL_U] = 0x0c, + [PLL_OFF_TEST_CTL] = 0x10, + [PLL_OFF_TEST_CTL_U] = 0x14, + [PLL_OFF_USER_CTL] = 0x18, + [PLL_OFF_USER_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_STATUS] = 0x24, + }, +}; + static struct clk_alpha_pll gpll0 = { .offset = 0x0, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(0), @@ -83,7 +97,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { .post_div_table = post_div_table_gpll0_out_aux2, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_aux2", .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw }, @@ -115,7 +129,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = { .post_div_table = post_div_table_gpll0_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw }, @@ -137,7 +151,7 @@ static struct clk_alpha_pll gpll10 = { .offset = 0xa000, .vco_table = gpll10_vco, .num_vco = ARRAY_SIZE(gpll10_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(10), @@ -163,7 +177,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = { .post_div_table = post_div_table_gpll10_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll10_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw }, @@ -189,7 +203,7 @@ static struct clk_alpha_pll gpll11 = { .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), .flags = SUPPORTS_DYNAMIC_UPDATE, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(11), @@ -215,7 +229,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = { .post_div_table = post_div_table_gpll11_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll11_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw }, @@ -229,7 +243,7 @@ static struct clk_alpha_pll gpll3 = { .offset = 0x3000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(3), @@ -248,7 +262,7 @@ static struct clk_alpha_pll gpll4 = { .offset = 0x4000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(4), @@ -274,7 +288,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = { .post_div_table = post_div_table_gpll4_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll4_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw }, @@ -287,7 +301,7 @@ static struct clk_alpha_pll gpll6 = { .offset = 0x6000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(6), @@ -313,7 +327,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = { .post_div_table = post_div_table_gpll6_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll6_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw }, @@ -326,7 +340,7 @@ static struct clk_alpha_pll gpll7 = { .offset = 0x7000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(7), @@ -352,7 +366,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = { .post_div_table = post_div_table_gpll7_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll7_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw }, @@ -380,7 +394,7 @@ static struct clk_alpha_pll gpll8 = { .offset = 0x8000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x79000, @@ -407,7 +421,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = { .post_div_table = post_div_table_gpll8_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll8_out_main", .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw }, From 041c79f6aefbafe6a516d83397ad6d3390915307 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Thu, 25 Aug 2022 17:14:47 -0500 Subject: [PATCH 339/610] RDMA/rxe: Fix resize_finish() in rxe_queue.c [ Upstream commit fda5d0cf8aef12f0a4f714a96a4b2fce039a3e55 ] Currently in resize_finish() in rxe_queue.c there is a loop which copies the entries in the original queue into a newly allocated queue. The termination logic for this loop is incorrect. The call to queue_next_index() updates cons but has no effect on whether the queue is empty. So if the queue starts out empty nothing is copied but if it is not then the loop will run forever. This patch changes the loop to compare the value of cons to the original producer index. Fixes: ae6e843fe08d0 ("RDMA/rxe: Add memory barriers to kernel queues") Link: https://lore.kernel.org/r/20220825221446.6512-1-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Reviewed-by: Li Zhijian Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/sw/rxe/rxe_queue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_queue.c b/drivers/infiniband/sw/rxe/rxe_queue.c index 6e6e023c1b45..03157de52f5f 100644 --- a/drivers/infiniband/sw/rxe/rxe_queue.c +++ b/drivers/infiniband/sw/rxe/rxe_queue.c @@ -112,23 +112,25 @@ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q, unsigned int num_elem) { enum queue_type type = q->type; + u32 new_prod; u32 prod; u32 cons; if (!queue_empty(q, q->type) && (num_elem < queue_count(q, type))) return -EINVAL; - prod = queue_get_producer(new_q, type); + new_prod = queue_get_producer(new_q, type); + prod = queue_get_producer(q, type); cons = queue_get_consumer(q, type); - while (!queue_empty(q, type)) { - memcpy(queue_addr_from_index(new_q, prod), + while ((prod - cons) & q->index_mask) { + memcpy(queue_addr_from_index(new_q, new_prod), queue_addr_from_index(q, cons), new_q->elem_size); - prod = queue_next_index(new_q, prod); + new_prod = queue_next_index(new_q, new_prod); cons = queue_next_index(q, cons); } - new_q->buf->producer_index = prod; + new_q->buf->producer_index = new_prod; q->buf->consumer_index = cons; /* update private index copies */ From 2f921d62c236ac823ce271a8b7ee80504b62c19c Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 11 Jan 2022 15:34:11 +0800 Subject: [PATCH 340/610] fsi: core: Check error number after calling ida_simple_get [ Upstream commit 35af9fb49bc5c6d61ef70b501c3a56fe161cce3e ] If allocation fails, the ida_simple_get() will return error number. So master->idx could be error number and be used in dev_set_name(). Therefore, it should be better to check it and return error if fails, like the ida_simple_get() in __fsi_get_new_minor(). Fixes: 09aecfab93b8 ("drivers/fsi: Add fsi master definition") Signed-off-by: Jiasheng Jiang Reviewed-by: Eddie James Link: https://lore.kernel.org/r/20220111073411.614138-1-jiasheng@iscas.ac.cn Signed-off-by: Joel Stanley Signed-off-by: Sasha Levin --- drivers/fsi/fsi-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 59ddc9fd5bca..92e6eebd1851 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -1309,6 +1309,9 @@ int fsi_master_register(struct fsi_master *master) mutex_init(&master->scan_lock); master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL); + if (master->idx < 0) + return master->idx; + dev_set_name(&master->dev, "fsi%d", master->idx); master->dev.class = &fsi_master_class; From 53bfc1c3c751b818c224bb6d56b170813b48edb2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 1 Aug 2022 14:42:02 +0300 Subject: [PATCH 341/610] mfd: intel_soc_pmic: Fix an error handling path in intel_soc_pmic_i2c_probe() [ Upstream commit 48749cabba109397b4e7dd556e85718ec0ec114d ] The commit in Fixes: has added a pwm_add_table() call in the probe() and a pwm_remove_table() call in the remove(), but forget to update the error handling path of the probe. Add the missing pwm_remove_table() call. Fixes: a3aa9a93df9f ("mfd: intel_soc_pmic_core: ADD PWM lookup table for CRC PMIC based PWM") Signed-off-by: Christophe JAILLET Signed-off-by: Andy Shevchenko Reviewed-by: Hans de Goede Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220801114211.36267-1-andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin --- drivers/mfd/intel_soc_pmic_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c index ddd64f9e3341..926653e1f603 100644 --- a/drivers/mfd/intel_soc_pmic_core.c +++ b/drivers/mfd/intel_soc_pmic_core.c @@ -95,6 +95,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, return 0; err_del_irq_chip: + pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); return ret; } From aec1f073f91f0f721f6b5d42321f77a2715933a0 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 31 Jul 2022 14:06:23 +0200 Subject: [PATCH 342/610] mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq() [ Upstream commit 3fa9e4cfb55da512ebfd57336fde468830719298 ] If devm_of_platform_populate() fails, some resources need to be released. Introduce a mx25_tsadc_unset_irq() function that undoes mx25_tsadc_setup_irq() and call it both from the new error handling path of the probe and in the remove function. Fixes: a55196eff6d6 ("mfd: fsl-imx25: Use devm_of_platform_populate()") Signed-off-by: Christophe JAILLET Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/d404e04828fc06bcfddf81f9f3e9b4babbe35415.1659269156.git.christophe.jaillet@wanadoo.fr Signed-off-by: Sasha Levin --- drivers/mfd/fsl-imx25-tsadc.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c index 37e5e02a1d05..85f7982d26d2 100644 --- a/drivers/mfd/fsl-imx25-tsadc.c +++ b/drivers/mfd/fsl-imx25-tsadc.c @@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev, return 0; } +static int mx25_tsadc_unset_irq(struct platform_device *pdev) +{ + struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); + int irq = platform_get_irq(pdev, 0); + + if (irq) { + irq_set_chained_handler_and_data(irq, NULL, NULL); + irq_domain_remove(tsadc->domain); + } + + return 0; +} + static void mx25_tsadc_setup_clk(struct platform_device *pdev, struct mx25_tsadc *tsadc) { @@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tsadc); - return devm_of_platform_populate(dev); + ret = devm_of_platform_populate(dev); + if (ret) + goto err_irq; + + return 0; + +err_irq: + mx25_tsadc_unset_irq(pdev); + + return ret; } static int mx25_tsadc_remove(struct platform_device *pdev) { - struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); - int irq = platform_get_irq(pdev, 0); - - if (irq) { - irq_set_chained_handler_and_data(irq, NULL, NULL); - irq_domain_remove(tsadc->domain); - } + mx25_tsadc_unset_irq(pdev); return 0; } From 0715005c483e71263e16a8d9caca6786dbc1740c Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 31 Jul 2022 11:55:27 +0200 Subject: [PATCH 343/610] mfd: lp8788: Fix an error handling path in lp8788_probe() [ Upstream commit becfdcd75126b20b8ec10066c5e85b34f8994ad5 ] Should an error occurs in mfd_add_devices(), some resources need to be released, as already done in the .remove() function. Add an error handling path and a lp8788_irq_exit() call to undo a previous lp8788_irq_init(). Fixes: eea6b7cc53aa ("mfd: Add lp8788 mfd driver") Signed-off-by: Christophe JAILLET Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/18398722da9df9490722d853e4797350189ae79b.1659261275.git.christophe.jaillet@wanadoo.fr Signed-off-by: Sasha Levin --- drivers/mfd/lp8788.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c index c223d2c6a363..998e8cc408a0 100644 --- a/drivers/mfd/lp8788.c +++ b/drivers/mfd/lp8788.c @@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id) if (ret) return ret; - return mfd_add_devices(lp->dev, -1, lp8788_devs, - ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); + ret = mfd_add_devices(lp->dev, -1, lp8788_devs, + ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); + if (ret) + goto err_exit_irq; + + return 0; + +err_exit_irq: + lp8788_irq_exit(lp); + return ret; } static int lp8788_remove(struct i2c_client *cl) From b940bb3c81544f5f021e22114c39a22c96ef1a0d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 31 Jul 2022 11:55:38 +0200 Subject: [PATCH 344/610] mfd: lp8788: Fix an error handling path in lp8788_irq_init() and lp8788_irq_init() [ Upstream commit 557244f6284f30613f2d61f14b579303165876c3 ] In lp8788_irq_init(), if an error occurs after a successful irq_domain_add_linear() call, it must be undone by a corresponding irq_domain_remove() call. irq_domain_remove() should also be called in lp8788_irq_exit() for the same reason. Fixes: eea6b7cc53aa ("mfd: Add lp8788 mfd driver") Signed-off-by: Christophe JAILLET Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/bcd5a72c9c1c383dd6324680116426e32737655a.1659261275.git.christophe.jaillet@wanadoo.fr Signed-off-by: Sasha Levin --- drivers/mfd/lp8788-irq.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c index 348439a3fbbd..39006297f3d2 100644 --- a/drivers/mfd/lp8788-irq.c +++ b/drivers/mfd/lp8788-irq.c @@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq) IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lp8788-irq", irqd); if (ret) { + irq_domain_remove(lp->irqdm); dev_err(lp->dev, "failed to create a thread for IRQ_N\n"); return ret; } @@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp) { if (lp->irq) free_irq(lp->irq, lp->irqdm); + if (lp->irqdm) + irq_domain_remove(lp->irqdm); } From d43d93dbd8aad34b30b446a5f637783160641333 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 11 Aug 2022 13:53:05 +0300 Subject: [PATCH 345/610] mfd: fsl-imx25: Fix check for platform_get_irq() errors [ Upstream commit 75db7907355ca5e2ff606e9dd3e86b6c3a455fe2 ] The mx25_tsadc_remove() function assumes all non-zero returns are success but the platform_get_irq() function returns negative on error and positive non-zero values on success. It never returns zero, but if it did then treat that as a success. Fixes: 18f773937968 ("mfd: fsl-imx25: Clean up irq settings during removal") Signed-off-by: Dan Carpenter Reviewed-by: Martin Kaiser Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/YvTfkbVQWYKMKS/t@kili Signed-off-by: Sasha Levin --- drivers/mfd/fsl-imx25-tsadc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c index 85f7982d26d2..823595bcc9b7 100644 --- a/drivers/mfd/fsl-imx25-tsadc.c +++ b/drivers/mfd/fsl-imx25-tsadc.c @@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev, int irq; irq = platform_get_irq(pdev, 0); - if (irq <= 0) + if (irq < 0) return irq; tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops, @@ -89,7 +89,7 @@ static int mx25_tsadc_unset_irq(struct platform_device *pdev) struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); int irq = platform_get_irq(pdev, 0); - if (irq) { + if (irq >= 0) { irq_set_chained_handler_and_data(irq, NULL, NULL); irq_domain_remove(tsadc->domain); } From 2dafc5afd9d674956714fc748884c809fb20d098 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 13 Sep 2022 17:11:12 +0800 Subject: [PATCH 346/610] mfd: sm501: Add check for platform_driver_register() [ Upstream commit 8325a6c24ad78b8c1acc3c42b098ee24105d68e5 ] As platform_driver_register() can return error numbers, it should be better to check platform_driver_register() and deal with the exception. Fixes: b6d6454fdb66 ("[PATCH] mfd: SM501 core driver") Signed-off-by: Jiasheng Jiang Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20220913091112.1739138-1-jiasheng@iscas.ac.cn Signed-off-by: Sasha Levin --- drivers/mfd/sm501.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index bc0a2c38653e..3ac4508a6742 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = { static int __init sm501_base_init(void) { - platform_driver_register(&sm501_plat_driver); + int ret; + + ret = platform_driver_register(&sm501_plat_driver); + if (ret < 0) + return ret; + return pci_register_driver(&sm501_pci_driver); } From 8aa96c5bc393a4d18a2f8037ac0e0e288a4ee9b2 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 27 Sep 2022 12:11:20 +0200 Subject: [PATCH 347/610] clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent [ Upstream commit 9f94f545f258b15bfa6357eb62e1e307b712851e ] The only clock in the MT8183 MFGCFG block feeds the GPU. Propagate its rate change requests to its parent, so that DVFS for the GPU can work properly. Fixes: acddfc2c261b ("clk: mediatek: Add MT8183 clock support") Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220927101128.44758-3-angelogioacchino.delregno@collabora.com Signed-off-by: Chen-Yu Tsai Signed-off-by: Sasha Levin --- drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c index 37b4162c5882..3a33014eee7f 100644 --- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c +++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c @@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = { .sta_ofs = 0x0, }; -#define GATE_MFG(_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ - &mtk_clk_gate_ops_setclr) +#define GATE_MFG(_id, _name, _parent, _shift) \ + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT) static const struct mtk_gate mfg_clks[] = { GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0) From 57f66534a41a75f0ab12250030827777cb38f8aa Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Mon, 19 Sep 2022 09:58:42 -0700 Subject: [PATCH 348/610] dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup() [ Upstream commit 898ec89dbb55b8294695ad71694a0684e62b2a73 ] User reports observing timer event report channel halted but no error observed in CHANERR register. The driver finished self-test and released channel resources. Debug shows that __cleanup() can call mod_timer() after the timer has been deleted and thus resurrect the timer. While harmless, it causes suprious error message to be emitted. Use mod_timer_pending() call to prevent deleted timer from being resurrected. Fixes: 3372de5813e4 ("dmaengine: ioatdma: removal of dma_v3.c and relevant ioat3 references") Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/166360672197.3851724.17040290563764838369.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/ioat/dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 37ff4ec7db76..e2070df6cad2 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete) if (active - i == 0) { dev_dbg(to_dev(ioat_chan), "%s: cancel completion timeout\n", __func__); - mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); } /* microsecond delay by sysfs variable per pending descriptor */ @@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan) if (chanerr & (IOAT_CHANERR_HANDLE_MASK | IOAT_CHANERR_RECOVER_MASK)) { - mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); ioat_eh(ioat_chan); } } @@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan) } if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state)) - mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); } static void ioat_reboot_chan(struct ioatdma_chan *ioat_chan) From faabbb103d604e52bb5b0591b4fe86e349856131 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Thu, 29 Sep 2022 14:44:59 +0800 Subject: [PATCH 349/610] usb: mtu3: fix failed runtime suspend in host only mode [ Upstream commit 1c703e29da5efac6180e4c189029fa34b7e48e97 ] When the dr_mode is "host", after the host enter runtime suspend, the mtu3 can't do it, because the mtu3's device wakeup function is not enabled, instead it's enabled in gadget init function, to fix the issue, init wakeup early in mtu3's probe() Fixes: 6b587394c65c ("usb: mtu3: support suspend/resume for dual-role mode") Reviewed-by: AngeloGioacchino Del Regno Reported-by: Tianping Fang Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/20220929064459.32522-1-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/mtu3/mtu3_core.c | 2 -- drivers/usb/mtu3/mtu3_plat.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index c4a2c37abf62..3ea5145a842b 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -971,8 +971,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) goto irq_err; } - device_init_wakeup(dev, true); - /* power down device IP for power saving by default */ mtu3_stop(mtu); diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index f13531022f4a..4c4dcbf17518 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -332,6 +332,8 @@ static int mtu3_probe(struct platform_device *pdev) pm_runtime_enable(dev); pm_runtime_get_sync(dev); + device_init_wakeup(dev, true); + ret = ssusb_rscs_init(ssusb); if (ret) goto comm_init_err; From b0bc75fe6775ca65c3e225a450eaefd4fae6a3a7 Mon Sep 17 00:00:00 2001 From: David Collins Date: Thu, 29 Sep 2022 17:50:16 -0700 Subject: [PATCH 350/610] spmi: pmic-arb: correct duplicate APID to PPID mapping logic [ Upstream commit 1f1693118c2476cb1666ad357edcf3cf48bf9b16 ] Correct the way that duplicate PPID mappings are handled for PMIC arbiter v5. The final APID mapped to a given PPID should be the one which has write owner = APPS EE, if it exists, or if not that, then the first APID mapped to the PPID, if it exists. Fixes: 40f318f0ed67 ("spmi: pmic-arb: add support for HW version 5") Signed-off-by: David Collins Signed-off-by: Fenglin Wu Link: https://lore.kernel.org/r/1655004286-11493-7-git-send-email-quic_fenglinw@quicinc.com Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20220930005019.2663064-8-sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/spmi/spmi-pmic-arb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index bbbd311eda03..e6de2aeece8d 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -887,7 +887,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) * version 5, there is more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID - * for a given PPID will receive interrupts from the PPID. + * which has the IRQ owner bit set for a given PPID will receive + * interrupts from the PPID. */ for (i = 0; ; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset(i); @@ -910,16 +911,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; prev_apidd = &pmic_arb->apid_data[apid]; - if (valid && is_irq_ee && - prev_apidd->write_ee == pmic_arb->ee) { + if (!valid || apidd->write_ee == pmic_arb->ee) { + /* First PPID mapping or one for this EE */ + pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; + } else if (valid && is_irq_ee && + prev_apidd->write_ee == pmic_arb->ee) { /* * Duplicate PPID mapping after the one for this EE; * override the irq owner */ prev_apidd->irq_ee = apidd->irq_ee; - } else if (!valid || is_irq_ee) { - /* First PPID mapping or duplicate for another EE */ - pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; } apidd->ppid = ppid; From 435a8a39c6aebb177ee12601d8da9df71d1262c4 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 30 Sep 2022 01:53:55 +0300 Subject: [PATCH 351/610] clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD [ Upstream commit c388cc804016cf0f65afdc2362b120aa594ff3e6 ] We have discovered random glitches during the system boot up procedure. The problem investigation led us to the weird outcomes: when none of the Renesas 5P49V6901 ports are explicitly enabled by the kernel driver, the glitches disappeared. It was a mystery since the SoC external clock domains were fed with different 5P49V6901 outputs. The driver code didn't seem like bogus either. We almost despaired to find out a root cause when the solution has been found for a more modern revision of the chip. It turned out the 5P49V6901 clock generator stopped its output for a short period of time during the VC5_OUT_DIV_CONTROL register writing. The same problem was found for the 5P49V6965 revision of the chip and was successfully fixed in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") by enabling the "bypass_sync" flag hidden inside "Unused Factory Reserved Register". Even though the 5P49V6901 registers description and programming guide doesn't provide any intel regarding that flag, setting it up anyway in the officially unused register completely eliminated the denoted glitches. Thus let's activate the functionality submitted in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") for the Renesas 5P49V6901 chip too in order to remove the ports implicit inter-dependency. Fixes: dbf6b16f5683 ("clk: vc5: Add support for IDT VersaClock 5P49V6901") Signed-off-by: Serge Semin Reviewed-by: Luca Ceresoli Link: https://lore.kernel.org/r/20220929225402.9696-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/clk-versaclock5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index c6d3b1ab3d55..5f8bd49b0810 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = { .model = IDT_VC6_5P49V6901, .clk_fod_cnt = 4, .clk_out_cnt = 5, - .flags = VC5_HAS_PFD_FREQ_DBL, + .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT, }; static const struct vc5_chip_info idt_5p49v6965_info = { From b2db8b2c539128a1cb825ef9d200f2867797b428 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 30 Sep 2022 01:53:56 +0300 Subject: [PATCH 352/610] clk: baikal-t1: Fix invalid xGMAC PTP clock divider [ Upstream commit 3c742088686ce922704aec5b11d09bcc5a396589 ] Most likely due to copy-paste mistake the divider has been set to 10 while according to the SoC reference manual it's supposed to be 8 thus having PTP clock frequency of 156.25 MHz. Fixes: 353afa3a8d2e ("clk: Add Baikal-T1 CCU Dividers driver") Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20220929225402.9696-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/baikal-t1/clk-ccu-div.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c index f141fda12b09..ea77eec40ddd 100644 --- a/drivers/clk/baikal-t1/clk-ccu-div.c +++ b/drivers/clk/baikal-t1/clk-ccu-div.c @@ -207,7 +207,7 @@ static const struct ccu_div_info sys_info[] = { CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", "eth_clk", CCU_SYS_XGMAC_BASE, 8), CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk", - "eth_clk", 10), + "eth_clk", 8), CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk", "eth_clk", CCU_SYS_USB_BASE, 10), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk", From 35b766027580bf0f378fed99209ff51560a6c825 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 30 Sep 2022 01:53:57 +0300 Subject: [PATCH 353/610] clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent [ Upstream commit e2eef312762e0b5a5a70d29fe59a245c0a3cffa0 ] Baikal-T1 CCU reference manual says that both xGMAC reference and xGMAC PTP clocks are generated by two different wrappers with the same constant divider thus each producing a 156.25 MHz signal. But for some reason both of these clock sources are gated by a single switch-flag in the CCU registers space - CCU_SYS_XGMAC_BASE.BIT(0). In order to make the clocks handled independently we need to define a shared parental gate so the base clock signal would be switched off only if both of the child-clocks are disabled. Note the ID is intentionally set to -2 since we are going to add a one more internal clock identifier in the next commit. Fixes: 353afa3a8d2e ("clk: Add Baikal-T1 CCU Dividers driver") Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20220929225402.9696-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/baikal-t1/ccu-div.c | 1 + drivers/clk/baikal-t1/ccu-div.h | 6 ++++++ drivers/clk/baikal-t1/clk-ccu-div.c | 8 +++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c index 4062092d67f9..bbfa3526ee10 100644 --- a/drivers/clk/baikal-t1/ccu-div.c +++ b/drivers/clk/baikal-t1/ccu-div.c @@ -579,6 +579,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) goto err_free_div; } parent_data.fw_name = div_init->parent_name; + parent_data.name = div_init->parent_name; hw_init.parent_data = &parent_data; hw_init.num_parents = 1; diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h index 795665caefbd..b6a9c8e45318 100644 --- a/drivers/clk/baikal-t1/ccu-div.h +++ b/drivers/clk/baikal-t1/ccu-div.h @@ -13,6 +13,12 @@ #include #include +/* + * CCU Divider private clock IDs + * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock + */ +#define CCU_SYS_XGMAC_CLK -2 + /* * CCU Divider private flags * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1. diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c index ea77eec40ddd..3953ae5664be 100644 --- a/drivers/clk/baikal-t1/clk-ccu-div.c +++ b/drivers/clk/baikal-t1/clk-ccu-div.c @@ -204,10 +204,12 @@ static const struct ccu_div_info sys_info[] = { "eth_clk", CCU_SYS_GMAC1_BASE, 5), CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk", "eth_clk", 10), - CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", - "eth_clk", CCU_SYS_XGMAC_BASE, 8), + CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk", + "eth_clk", CCU_SYS_XGMAC_BASE, 1), + CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk", + "sys_xgmac_clk", 8), CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk", - "eth_clk", 8), + "sys_xgmac_clk", 8), CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk", "eth_clk", CCU_SYS_USB_BASE, 10), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk", From e338131e980b2f9861b09bfcc29dcd972584b483 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 30 Sep 2022 01:53:58 +0300 Subject: [PATCH 354/610] clk: baikal-t1: Add SATA internal ref clock buffer [ Upstream commit 081a9b7c74eae4e12b2cb1b86720f836a8f29247 ] It turns out the internal SATA reference clock signal will stay unavailable for the SATA interface consumer until the buffer on it's way is ungated. So aside with having the actual clock divider enabled we need to ungate a buffer placed on the signal way to the SATA controller (most likely some rudiment from the initial SoC release). Seeing the switch flag is placed in the same register as the SATA-ref clock divider at a non-standard ffset, let's implement it as a separate clock controller with the set-rate propagation to the parental clock divider wrapper. As such we'll be able to disable/enable and still change the original clock source rate. Fixes: 353afa3a8d2e ("clk: Add Baikal-T1 CCU Dividers driver") Signed-off-by: Serge Semin Link: https://lore.kernel.org/r/20220929225402.9696-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/baikal-t1/ccu-div.c | 64 +++++++++++++++++++++++++++++ drivers/clk/baikal-t1/ccu-div.h | 4 ++ drivers/clk/baikal-t1/clk-ccu-div.c | 18 +++++++- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c index bbfa3526ee10..a6642f3d33d4 100644 --- a/drivers/clk/baikal-t1/ccu-div.c +++ b/drivers/clk/baikal-t1/ccu-div.c @@ -34,6 +34,7 @@ #define CCU_DIV_CTL_CLKDIV_MASK(_width) \ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD) #define CCU_DIV_CTL_LOCK_SHIFTED BIT(27) +#define CCU_DIV_CTL_GATE_REF_BUF BIT(28) #define CCU_DIV_CTL_LOCK_NORMAL BIT(31) #define CCU_DIV_RST_DELAY_US 1 @@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw) return !!(val & CCU_DIV_CTL_EN); } +static int ccu_div_buf_enable(struct clk_hw *hw) +{ + struct ccu_div *div = to_ccu_div(hw); + unsigned long flags; + + spin_lock_irqsave(&div->lock, flags); + regmap_update_bits(div->sys_regs, div->reg_ctl, + CCU_DIV_CTL_GATE_REF_BUF, 0); + spin_unlock_irqrestore(&div->lock, flags); + + return 0; +} + +static void ccu_div_buf_disable(struct clk_hw *hw) +{ + struct ccu_div *div = to_ccu_div(hw); + unsigned long flags; + + spin_lock_irqsave(&div->lock, flags); + regmap_update_bits(div->sys_regs, div->reg_ctl, + CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF); + spin_unlock_irqrestore(&div->lock, flags); +} + +static int ccu_div_buf_is_enabled(struct clk_hw *hw) +{ + struct ccu_div *div = to_ccu_div(hw); + u32 val = 0; + + regmap_read(div->sys_regs, div->reg_ctl, &val); + + return !(val & CCU_DIV_CTL_GATE_REF_BUF); +} + static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = { CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN), CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST), CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV), + CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF), CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL) }; @@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry) continue; } + if (!strcmp("div_buf", name)) + continue; + bits[didx] = ccu_div_bits[bidx]; bits[didx].div = div; @@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) &ccu_div_dbgfs_fixed_clkdiv_fops); } +static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry) +{ + struct ccu_div *div = to_ccu_div(hw); + struct ccu_div_dbgfs_bit *bit; + + bit = kmalloc(sizeof(*bit), GFP_KERNEL); + if (!bit) + return; + + *bit = ccu_div_bits[3]; + bit->div = div; + debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit, + &ccu_div_dbgfs_bit_fops); +} + static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry) { struct ccu_div *div = to_ccu_div(hw); @@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry) #define ccu_div_var_debug_init NULL #define ccu_div_gate_debug_init NULL +#define ccu_div_buf_debug_init NULL #define ccu_div_fixed_debug_init NULL #endif /* !CONFIG_DEBUG_FS */ @@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = { .debug_init = ccu_div_gate_debug_init }; +static const struct clk_ops ccu_div_buf_ops = { + .enable = ccu_div_buf_enable, + .disable = ccu_div_buf_disable, + .is_enabled = ccu_div_buf_is_enabled, + .debug_init = ccu_div_buf_debug_init +}; + static const struct clk_ops ccu_div_fixed_ops = { .recalc_rate = ccu_div_fixed_recalc_rate, .round_rate = ccu_div_fixed_round_rate, @@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) } else if (div_init->type == CCU_DIV_GATE) { hw_init.ops = &ccu_div_gate_ops; div->divider = div_init->divider; + } else if (div_init->type == CCU_DIV_BUF) { + hw_init.ops = &ccu_div_buf_ops; } else if (div_init->type == CCU_DIV_FIXED) { hw_init.ops = &ccu_div_fixed_ops; div->divider = div_init->divider; diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h index b6a9c8e45318..4eb49ff4803c 100644 --- a/drivers/clk/baikal-t1/ccu-div.h +++ b/drivers/clk/baikal-t1/ccu-div.h @@ -15,8 +15,10 @@ /* * CCU Divider private clock IDs + * @CCU_SYS_SATA_CLK: CCU SATA internal clock * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock */ +#define CCU_SYS_SATA_CLK -1 #define CCU_SYS_XGMAC_CLK -2 /* @@ -37,11 +39,13 @@ * enum ccu_div_type - CCU Divider types * @CCU_DIV_VAR: Clocks gate with variable divider. * @CCU_DIV_GATE: Clocks gate with fixed divider. + * @CCU_DIV_BUF: Clock gate with no divider. * @CCU_DIV_FIXED: Ungateable clock with fixed divider. */ enum ccu_div_type { CCU_DIV_VAR, CCU_DIV_GATE, + CCU_DIV_BUF, CCU_DIV_FIXED }; diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c index 3953ae5664be..90f4fda406ee 100644 --- a/drivers/clk/baikal-t1/clk-ccu-div.c +++ b/drivers/clk/baikal-t1/clk-ccu-div.c @@ -76,6 +76,16 @@ .divider = _divider \ } +#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags) \ + { \ + .id = _id, \ + .name = _name, \ + .parent_name = _pname, \ + .base = _base, \ + .type = CCU_DIV_BUF, \ + .flags = _flags \ + } + #define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider) \ { \ .id = _id, \ @@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = { * for the SoC devices registers IO-operations. */ static const struct ccu_div_info sys_info[] = { - CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk", + CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk", "sata_clk", CCU_SYS_SATA_REF_BASE, 4, CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED | CCU_DIV_RESET_DOMAIN), + CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk", + "sys_sata_clk", CCU_SYS_SATA_REF_BASE, + CLK_SET_RATE_PARENT), CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk", "pcie_clk", CCU_SYS_APB_BASE, 5, CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN), @@ -398,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data) init.base = info->base; init.sys_regs = data->sys_regs; init.divider = info->divider; + } else if (init.type == CCU_DIV_BUF) { + init.base = info->base; + init.sys_regs = data->sys_regs; } else { init.divider = info->divider; } From bdf72f2d649b4602171c1a1d24404b57d71dee02 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 4 Sep 2022 16:10:37 +0200 Subject: [PATCH 355/610] clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration [ Upstream commit 0b919a3728691c172312dee99ba654055ccd8c84 ] The return value of bcm2835_clock_rate_from_divisor is always unsigned and also all caller expect this. So fix the declaration accordingly. Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain clocks") Signed-off-by: Stefan Wahren Link: https://lore.kernel.org/r/20220904141037.38816-1-stefan.wahren@i2se.com Reviewed-by: Ivan T. Ivanov Reviewed-by: Florian Fainelli Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/bcm/clk-bcm2835.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 3667b4d731e7..2200305a722d 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -967,9 +967,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, return div; } -static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, - unsigned long parent_rate, - u32 div) +static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, + unsigned long parent_rate, + u32 div) { const struct bcm2835_clock_data *data = clock->data; u64 temp; From 9209e6bab75d4008d9f4248c66008f3ffd24c931 Mon Sep 17 00:00:00 2001 From: Lin Yujun Date: Wed, 14 Sep 2022 11:32:06 +0800 Subject: [PATCH 356/610] clk: imx: scu: fix memleak on platform_device_add() fails [ Upstream commit 855ae87a2073ebf1b395e020de54fdf9ce7d166f ] No error handling is performed when platform_device_add() fails. Add error processing before return, and modified the return value. Fixes: 77d8f3068c63 ("clk: imx: scu: add two cells binding support") Signed-off-by: Lin Yujun Link: https://lore.kernel.org/r/20220914033206.98046-1-linyujun809@huawei.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/imx/clk-scu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 083da31dc3ea..dc933fd5d5a0 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -690,7 +690,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, pr_warn("%s: failed to attached the power domain %d\n", name, ret); - platform_device_add(pdev); + ret = platform_device_add(pdev); + if (ret) { + platform_device_put(pdev); + return ERR_PTR(ret); + } /* For API backwards compatiblilty, simply return NULL for success */ return NULL; From 3441076f83aace85f5d6ccd9ffb301ac6b874776 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 2 Jun 2022 07:08:36 +0400 Subject: [PATCH 357/610] clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe [ Upstream commit 9c59a01caba26ec06fefd6ca1f22d5fd1de57d63 ] pm_runtime_get_sync() will increment pm usage counter. Forgetting to putting operation will result in reference leak. Add missing pm_runtime_put_sync in some error paths. Fixes: 9ac33b0ce81f ("CLK: TI: Driver for DRA7 ATL (Audio Tracking Logic)") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220602030838.52057-1-linmq006@gmail.com Reviewed-by: Tony Lindgren Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/ti/clk-dra7-atl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c index 8d4c08b034bd..e2e59d78c173 100644 --- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -251,14 +251,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev) if (rc) { pr_err("%s: failed to lookup atl clock %d\n", __func__, i); - return -EINVAL; + ret = -EINVAL; + goto pm_put; } clk = of_clk_get_from_provider(&clkspec); if (IS_ERR(clk)) { pr_err("%s: failed to get atl clock %d from provider\n", __func__, i); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto pm_put; } cdesc = to_atl_desc(__clk_get_hw(clk)); @@ -291,8 +293,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev) if (cdesc->enabled) atl_clk_enable(__clk_get_hw(clk)); } - pm_runtime_put_sync(cinfo->dev); +pm_put: + pm_runtime_put_sync(cinfo->dev); return ret; } From fad007a315fed9e6db8bb84ef986d854e39187c7 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 21 Apr 2022 13:34:26 +0930 Subject: [PATCH 358/610] clk: ast2600: BCLK comes from EPLL [ Upstream commit b8c1dc9c00b252b3be853720a71b05ed451ddd9f ] This correction was made in the u-boot SDK recently. There are no in-tree users of this clock so the impact is minimal. Fixes: d3d04f6c330a ("clk: Add support for AST2600 SoC") Link: https://github.com/AspeedTech-BMC/u-boot/commit/8ad54a5ae15f27fea5e894cc2539a20d90019717 Signed-off-by: Joel Stanley Link: https://lore.kernel.org/r/20220421040426.171256-1-joel@jms.id.au Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/clk-ast2600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index 24dab2312bc6..9c3305bcb27a 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */ /* P-Bus (BCLK) clock divider */ - hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0, + hw = clk_hw_register_divider_table(dev, "bclk", "epll", 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0, ast2600_div_table, &aspeed_g6_clk_lock); From ba2264359525d5515399d30403f2534c34c8b37f Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 24 Aug 2022 08:08:11 +0100 Subject: [PATCH 359/610] mailbox: mpfs: fix handling of the reg property [ Upstream commit 2e10289d1f304f5082a4dda55a677b72b3bdb581 ] The "data" region of the PolarFire SoC's system controller mailbox is not one continuous register space - the system controller's QSPI sits between the control and data registers. Split the "data" reg into two parts: "data" & "control". Optionally get the "data" register address from the 3rd reg property in the devicetree & fall back to using the old base + MAILBOX_REG_OFFSET that the current code uses. Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox") Signed-off-by: Conor Dooley Signed-off-by: Jassi Brar Signed-off-by: Sasha Levin --- drivers/mailbox/mailbox-mpfs.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c index 4e34854d1238..e432a8f0d148 100644 --- a/drivers/mailbox/mailbox-mpfs.c +++ b/drivers/mailbox/mailbox-mpfs.c @@ -62,6 +62,7 @@ struct mpfs_mbox { struct mbox_controller controller; struct device *dev; int irq; + void __iomem *ctrl_base; void __iomem *mbox_base; void __iomem *int_reg; struct mbox_chan chans[1]; @@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) { u32 status; - status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET); + status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET); return status & SCB_STATUS_BUSY_MASK; } @@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) for (index = 0; index < (msg->cmd_data_size / 4); index++) writel_relaxed(word_buf[index], - mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); + mbox->mbox_base + index * 0x4); if (extra_bits) { u8 i; u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); u8 *byte_buf = msg->cmd_data + byte_off; - val = readl_relaxed(mbox->mbox_base + - MAILBOX_REG_OFFSET + index * 0x4); + val = readl_relaxed(mbox->mbox_base + index * 0x4); for (i = 0u; i < extra_bits; i++) { val &= ~(0xffu << (i * 8u)); @@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) } writel_relaxed(val, - mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); + mbox->mbox_base + index * 0x4); } } opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu)); tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK; tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK; - writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET); + writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET); return 0; } @@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan) if (!mpfs_mbox_busy(mbox)) { for (i = 0; i < num_words; i++) { response->resp_msg[i] = - readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET + readl_relaxed(mbox->mbox_base + mbox->resp_offset + i * 0x4); } } @@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev) if (!mbox) return -ENOMEM; - mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); - if (IS_ERR(mbox->mbox_base)) - return PTR_ERR(mbox->mbox_base); + mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); + if (IS_ERR(mbox->ctrl_base)) + return PTR_ERR(mbox->ctrl_base); mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, ®s); if (IS_ERR(mbox->int_reg)) return PTR_ERR(mbox->int_reg); + mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, ®s); + if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs + mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET; + mbox->irq = platform_get_irq(pdev, 0); if (mbox->irq < 0) return mbox->irq; From b8fcd9ab0f6596bc3c3b601ad859181cf84dbade Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 24 Aug 2022 08:08:12 +0100 Subject: [PATCH 360/610] mailbox: mpfs: account for mbox offsets while sending [ Upstream commit 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 ] The mailbox offset is not only used for receiving messages, but it is also used by messages sent to the system controller by Linux that have a payload, such as the "digital signature service". It is also overloaded by certain other services (reprogramming of the FPGA fabric, see Link:) to have a meaning other than the offset the system controller should read from. When the driver was written, no such services of the latter type were in use & those of the former used an offset of zero so this has gone un-noticed. Link: https://www.microsemi.com/document-portal/doc_download/1245815-polarfire-fpga-and-polarfire-soc-fpga-system-services-user-guide # Section 5.2 Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox") Signed-off-by: Conor Dooley Signed-off-by: Jassi Brar Signed-off-by: Sasha Levin --- drivers/mailbox/mailbox-mpfs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c index e432a8f0d148..cfacb3f320a6 100644 --- a/drivers/mailbox/mailbox-mpfs.c +++ b/drivers/mailbox/mailbox-mpfs.c @@ -100,21 +100,20 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) for (index = 0; index < (msg->cmd_data_size / 4); index++) writel_relaxed(word_buf[index], - mbox->mbox_base + index * 0x4); + mbox->mbox_base + msg->mbox_offset + index * 0x4); if (extra_bits) { u8 i; u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); u8 *byte_buf = msg->cmd_data + byte_off; - val = readl_relaxed(mbox->mbox_base + index * 0x4); + val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4); for (i = 0u; i < extra_bits; i++) { val &= ~(0xffu << (i * 8u)); val |= (byte_buf[i] << (i * 8u)); } - writel_relaxed(val, - mbox->mbox_base + index * 0x4); + writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4); } } From 25a4fb0e1a763d2cc9aa5049d584790e74355a38 Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Fri, 26 Aug 2022 12:13:35 +0200 Subject: [PATCH 361/610] mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg [ Upstream commit 6b207ce8a96a71e966831e3a13c38143ba9a73c1 ] dma_map_sg return 0 on error, fix the error check, and return -EIO to caller. Fixes: dbc049eee730 ("mailbox: Add driver for Broadcom FlexRM ring manager") Signed-off-by: Jack Wang Signed-off-by: Jassi Brar Signed-off-by: Sasha Levin --- drivers/mailbox/bcm-flexrm-mailbox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c index 78073ad1f2f1..b7e9fd53d47d 100644 --- a/drivers/mailbox/bcm-flexrm-mailbox.c +++ b/drivers/mailbox/bcm-flexrm-mailbox.c @@ -632,15 +632,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg) rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src), DMA_TO_DEVICE); - if (rc < 0) - return rc; + if (!rc) + return -EIO; rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst), DMA_FROM_DEVICE); - if (rc < 0) { + if (!rc) { dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src), DMA_TO_DEVICE); - return rc; + return -EIO; } return 0; From 93379dc92de0b7c0a2a80919cb36e27a5dfb4f4b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 1 Sep 2022 11:42:53 +1000 Subject: [PATCH 362/610] powerpc/configs: Properly enable PAPR_SCM in pseries_defconfig [ Upstream commit aa398d88aea4ec863bd7aea35d5035a37096dc59 ] My commit to add PAPR_SCM to pseries_defconfig failed to add the required dependencies, meaning the driver doesn't get built. Add the required LIBNVDIMM=m. Fixes: d6481a7195df ("powerpc/configs: Add PAPR_SCM to pseries_defconfig") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220901014253.252927-1-mpe@ellerman.id.au Signed-off-by: Sasha Levin --- arch/powerpc/configs/pseries_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index d0494fbb4961..6011977d43c9 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -41,6 +41,7 @@ CONFIG_DTL=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y CONFIG_IBMEBUS=y +CONFIG_LIBNVDIMM=m CONFIG_PAPR_SCM=m CONFIG_PPC_SVM=y # CONFIG_PPC_PMAC is not set From b0c0490b3c57b78ecad59a5bdd11a7126b2f78bd Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Fri, 2 Sep 2022 18:00:08 +0200 Subject: [PATCH 363/610] powerpc/math_emu/efp: Include module.h [ Upstream commit cfe0d370e0788625ce0df3239aad07a2506c1796 ] When building with a recent version of clang, there are a couple of errors around the call to module_init(): arch/powerpc/math-emu/math_efp.c:927:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] module_init(spe_mathemu_init); ^ int arch/powerpc/math-emu/math_efp.c:927:13: error: a parameter list without types is only allowed in a function definition module_init(spe_mathemu_init); ^ 2 errors generated. module_init() is a macro, which is not getting expanded because module.h is not included in this file. Add the include so that the macro can expand properly, clearing up the build failure. Fixes: ac6f120369ff ("powerpc/85xx: Workaroudn e500 CPU erratum A005") [chleroy: added fixes tag] Reported-by: kernel test robot Signed-off-by: Nathan Chancellor Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Reviewed-by: Christophe Leroy Link: https://lore.kernel.org/r/8403854a4c187459b2f4da3537f51227b70b9223.1662134272.git.christophe.leroy@csgroup.eu Signed-off-by: Sasha Levin --- arch/powerpc/math-emu/math_efp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c index 39b84e7452e1..aa3bb8da1cb9 100644 --- a/arch/powerpc/math-emu/math_efp.c +++ b/arch/powerpc/math-emu/math_efp.c @@ -17,6 +17,7 @@ #include #include +#include #include #include From 5a13d3f1af1c3b10033ede03c899b2a61cd44f6b Mon Sep 17 00:00:00 2001 From: Liang He Date: Mon, 4 Jul 2022 22:52:33 +0800 Subject: [PATCH 364/610] powerpc/sysdev/fsl_msi: Add missing of_node_put() [ Upstream commit def435c04ee984a5f9ed2711b2bfe946936c6a21 ] In fsl_setup_msi_irqs(), use of_node_put() to drop the reference returned by of_parse_phandle(). Fixes: 895d603f945ba ("powerpc/fsl_msi: add support for the fsl, msi property in PCI nodes") Co-authored-by: Miaoqian Lin Signed-off-by: Liang He Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220704145233.278539-1-windhl@126.com Signed-off-by: Sasha Levin --- arch/powerpc/sysdev/fsl_msi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index e6b06c3f8197..c55ccec0a169 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -211,8 +211,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) dev_err(&pdev->dev, "node %pOF has an invalid fsl,msi phandle %u\n", hose->dn, np->phandle); + of_node_put(np); return -EINVAL; } + of_node_put(np); } for_each_pci_msi_entry(entry, pdev) { From 5be9cb6c06fa1a6fa6ae45f2fa61f7e4c10794b9 Mon Sep 17 00:00:00 2001 From: Liang He Date: Fri, 1 Jul 2022 21:17:50 +0800 Subject: [PATCH 365/610] powerpc/pci_dn: Add missing of_node_put() [ Upstream commit 110a1fcb6c4d55144d8179983a475f17a1d6f832 ] In pci_add_device_node_info(), use of_node_put() to drop the reference to 'parent' returned by of_get_parent() to keep refcount balance. Fixes: cca87d303c85 ("powerpc/pci: Refactor pci_dn") Co-authored-by: Miaoqian Lin Signed-off-by: Liang He Signed-off-by: Michael Ellerman Reviewed-by: Tyrel Datwyler Link: https://lore.kernel.org/r/20220701131750.240170-1-windhl@126.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/pci_dn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index 61571ae23953..335767cea137 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose, INIT_LIST_HEAD(&pdn->list); parent = of_get_parent(dn); pdn->parent = parent ? PCI_DN(parent) : NULL; + of_node_put(parent); if (pdn->parent) list_add_tail(&pdn->list, &pdn->parent->child_list); From 61af84b3db8183bfa6faeb42adc7865c597dbcd9 Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Tue, 6 Sep 2022 14:17:03 +0000 Subject: [PATCH 366/610] powerpc/powernv: add missing of_node_put() in opal_export_attrs() [ Upstream commit 71a92e99c47900cc164620948b3863382cec4f1a ] After using 'np' returned by of_find_node_by_path(), of_node_put() need be called to decrease the refcount. Fixes: 11fe909d2362 ("powerpc/powernv: Add OPAL exports attributes to sysfs") Signed-off-by: Zheng Yongjun Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220906141703.118192-1-zhengyongjun3@huawei.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/powernv/opal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index e9d18519e650..5178ec6f3715 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -892,6 +892,7 @@ static void opal_export_attrs(void) kobj = kobject_create_and_add("exports", opal_kobj); if (!kobj) { pr_warn("kobject_create_and_add() of exports failed\n"); + of_node_put(np); return; } From 592b302d8bf66b6f1b9c585dc3864c5da5fb043b Mon Sep 17 00:00:00 2001 From: Rohan McLure Date: Wed, 21 Sep 2022 16:55:48 +1000 Subject: [PATCH 367/610] powerpc: Fix fallocate and fadvise64_64 compat parameter combination [ Upstream commit 016ff72bd2090903715c0f9422a44afbb966f4ee ] As reported[1] by Arnd, the arch-specific fadvise64_64 and fallocate compatibility handlers assume parameters are passed with 32-bit big-endian ABI. This affects the assignment of odd-even parameter pairs to the high or low words of a 64-bit syscall parameter. Fix fadvise64_64 fallocate compat handlers to correctly swap upper/lower 32 bits conditioned on endianness. A future patch will replace the arch-specific compat fallocate with an asm-generic implementation. This patch is intended for ease of back-port. [1]: https://lore.kernel.org/all/be29926f-226e-48dc-871a-e29a54e80583@www.fastmail.com/ Fixes: 57f48b4b74e7 ("powerpc/compat_sys: swap hi/lo parts of 64-bit syscall args in LE mode") Reported-by: Arnd Bergmann Signed-off-by: Rohan McLure Reviewed-by: Arnd Bergmann Reviewed-by: Nicholas Piggin Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220921065605.1051927-9-rmclure@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/syscalls.h | 12 ++++++++++++ arch/powerpc/kernel/sys_ppc32.c | 14 +------------- arch/powerpc/kernel/syscalls.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h index 7ee66ae5444d..0e85d7aa395d 100644 --- a/arch/powerpc/include/asm/syscalls.h +++ b/arch/powerpc/include/asm/syscalls.h @@ -8,6 +8,18 @@ #include #include +/* + * long long munging: + * The 32 bit ABI passes long longs in an odd even register pair. + * High and low parts are swapped depending on endian mode, + * so define a macro (similar to mips linux32) to handle that. + */ +#ifdef __LITTLE_ENDIAN__ +#define merge_64(low, high) (((u64)high << 32) | low) +#else +#define merge_64(high, low) (((u64)high << 32) | low) +#endif + struct rtas_args; asmlinkage long sys_mmap(unsigned long addr, size_t len, diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 16ff0399a257..719bfc6d1e3f 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -56,18 +56,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len, return sys_mmap(addr, len, prot, flags, fd, pgoff << 12); } -/* - * long long munging: - * The 32 bit ABI passes long longs in an odd even register pair. - * High and low parts are swapped depending on endian mode, - * so define a macro (similar to mips linux32) to handle that. - */ -#ifdef __LITTLE_ENDIAN__ -#define merge_64(low, high) ((u64)high << 32) | low -#else -#define merge_64(high, low) ((u64)high << 32) | low -#endif - compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 reg6, u32 pos1, u32 pos2) { @@ -94,7 +82,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4, asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2, u32 len1, u32 len2) { - return ksys_fallocate(fd, mode, ((loff_t)offset1 << 32) | offset2, + return ksys_fallocate(fd, mode, merge_64(offset1, offset2), merge_64(len1, len2)); } diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 825931e400df..e3edcf8f7cae 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -99,8 +99,8 @@ long ppc64_personality(unsigned long personality) long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, u32 len_high, u32 len_low) { - return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low, - (u64)len_high << 32 | len_low, advice); + return ksys_fadvise64_64(fd, merge_64(offset_high, offset_low), + merge_64(len_high, len_low), advice); } SYSCALL_DEFINE0(switch_endian) From 399afe92f6409fd2130e4ffd17a38b426975c02f Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 30 Aug 2022 15:37:05 +0200 Subject: [PATCH 368/610] x86/hyperv: Fix 'struct hv_enlightened_vmcs' definition [ Upstream commit ea9da788a61e47e7ab9cbad397453e51cd82ac0d ] Section 1.9 of TLFS v6.0b says: "All structures are padded in such a way that fields are aligned naturally (that is, an 8-byte field is aligned to an offset of 8 bytes and so on)". 'struct enlightened_vmcs' has a glitch: ... struct { u32 nested_flush_hypercall:1; /* 836: 0 4 */ u32 msr_bitmap:1; /* 836: 1 4 */ u32 reserved:30; /* 836: 2 4 */ } hv_enlightenments_control; /* 836 4 */ u32 hv_vp_id; /* 840 4 */ u64 hv_vm_id; /* 844 8 */ u64 partition_assist_page; /* 852 8 */ ... And the observed values in 'partition_assist_page' make no sense at all. Fix the layout by padding the structure properly. Fixes: 68d1eb72ee99 ("x86/hyper-v: define struct hv_enlightened_vmcs and clean field bits") Reviewed-by: Maxim Levitsky Reviewed-by: Michael Kelley Signed-off-by: Vitaly Kuznetsov Signed-off-by: Sean Christopherson Link: https://lore.kernel.org/r/20220830133737.1539624-2-vkuznets@redhat.com Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- arch/x86/include/asm/hyperv-tlfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index 2322d6bd5883..b54b3e18d94b 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -529,7 +529,7 @@ struct hv_enlightened_vmcs { u64 guest_rip; u32 hv_clean_fields; - u32 hv_padding_32; + u32 padding32_1; u32 hv_synthetic_controls; struct { u32 nested_flush_hypercall:1; @@ -537,7 +537,7 @@ struct hv_enlightened_vmcs { u32 reserved:30; } __packed hv_enlightenments_control; u32 hv_vp_id; - + u32 padding32_2; u64 hv_vm_id; u64 partition_assist_page; u64 padding64_4[4]; From 72c5b7110fba4f1a1a45462ecbd339a967440b30 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 21 Sep 2022 11:41:02 +1000 Subject: [PATCH 369/610] powerpc/64s: Fix GENERIC_CPU build flags for PPC970 / G5 [ Upstream commit 58ec7f06b74e0d6e76c4110afce367c8b5f0837d ] Big-endian GENERIC_CPU supports 970, but builds with -mcpu=power5. POWER5 is ISA v2.02 whereas 970 is v2.01 plus Altivec. 2.02 added the popcntb instruction which a compiler might use. Use -mcpu=power4. Fixes: 471d7ff8b51b ("powerpc/64s: Remove POWER4 support") Signed-off-by: Nicholas Piggin Reviewed-by: Segher Boessenkool Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220921014103.587954-1-npiggin@gmail.com 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 2bb0fe9b2058..7859ae56fcdc 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -154,7 +154,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8 CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8) else CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5)) -CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4) +CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4 endif else ifdef CONFIG_PPC_BOOK3E_64 CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 From 1f98f8f4354159c18d00f2e7946086f13b3f18d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 2 Sep 2022 23:21:02 +0200 Subject: [PATCH 370/610] powerpc: Fix SPE Power ISA properties for e500v1 platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 37b9345ce7f4ab17538ea62def6f6d430f091355 ] Commit 2eb28006431c ("powerpc/e500v2: Add Power ISA properties to comply with ePAPR 1.1") introduced new include file e500v2_power_isa.dtsi and should have used it for all e500v2 platforms. But apparently it was used also for e500v1 platforms mpc8540, mpc8541, mpc8555 and mpc8560. e500v1 cores compared to e500v2 do not support double precision floating point SPE instructions. Hence power-isa-sp.fd should not be set on e500v1 platforms, which is in e500v2_power_isa.dtsi include file. Fix this issue by introducing a new e500v1_power_isa.dtsi include file and use it in all e500v1 device tree files. Fixes: 2eb28006431c ("powerpc/e500v2: Add Power ISA properties to comply with ePAPR 1.1") Signed-off-by: Pali Rohár Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220902212103.22534-1-pali@kernel.org Signed-off-by: Sasha Levin --- .../boot/dts/fsl/e500v1_power_isa.dtsi | 51 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/mpc8540ads.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8541cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8555cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8560ads.dts | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi diff --git a/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi new file mode 100644 index 000000000000..7e2a90cde72e --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi @@ -0,0 +1,51 @@ +/* + * e500v1 Power ISA Device Tree Source (include) + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/ { + cpus { + power-isa-version = "2.03"; + power-isa-b; // Base + power-isa-e; // Embedded + power-isa-atb; // Alternate Time Base + power-isa-cs; // Cache Specification + power-isa-e.le; // Embedded.Little-Endian + power-isa-e.pm; // Embedded.Performance Monitor + power-isa-ecl; // Embedded Cache Locking + power-isa-mmc; // Memory Coherence + power-isa-sp; // Signal Processing Engine + power-isa-sp.fs; // SPE.Embedded Float Scalar Single + power-isa-sp.fv; // SPE.Embedded Float Vector + mmu-type = "power-embedded"; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts index 18a885130538..e03ae130162b 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8540ADS"; diff --git a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts index ac381e7b1c60..a2a6c5cf852e 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8541CDS"; diff --git a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts index 9f58db2a7e66..901b6ff06dfb 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8555CDS"; diff --git a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts index a24722ccaebf..c2f9aea78b29 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8560ADS"; From 7f536a8cb62dd5c084f112373fc34cdb5168a813 Mon Sep 17 00:00:00 2001 From: Li Huafei Date: Fri, 23 Sep 2022 17:32:53 +0800 Subject: [PATCH 371/610] powerpc/kprobes: Fix null pointer reference in arch_prepare_kprobe() [ Upstream commit 97f88a3d723162781d6cbfdc7b9617eefab55b19 ] I found a null pointer reference in arch_prepare_kprobe(): # echo 'p cmdline_proc_show' > kprobe_events # echo 'p cmdline_proc_show+16' >> kprobe_events Kernel attempted to read user page (0) - exploit attempt? (uid: 0) BUG: Kernel NULL pointer dereference on read at 0x00000000 Faulting instruction address: 0xc000000000050bfc Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV Modules linked in: CPU: 0 PID: 122 Comm: sh Not tainted 6.0.0-rc3-00007-gdcf8e5633e2e #10 NIP: c000000000050bfc LR: c000000000050bec CTR: 0000000000005bdc REGS: c0000000348475b0 TRAP: 0300 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e) MSR: 9000000000009033 CR: 88002444 XER: 20040006 CFAR: c00000000022d100 DAR: 0000000000000000 DSISR: 40000000 IRQMASK: 0 ... NIP arch_prepare_kprobe+0x10c/0x2d0 LR arch_prepare_kprobe+0xfc/0x2d0 Call Trace: 0xc0000000012f77a0 (unreliable) register_kprobe+0x3c0/0x7a0 __register_trace_kprobe+0x140/0x1a0 __trace_kprobe_create+0x794/0x1040 trace_probe_create+0xc4/0xe0 create_or_delete_trace_kprobe+0x2c/0x80 trace_parse_run_command+0xf0/0x210 probes_write+0x20/0x40 vfs_write+0xfc/0x450 ksys_write+0x84/0x140 system_call_exception+0x17c/0x3a0 system_call_vectored_common+0xe8/0x278 --- interrupt: 3000 at 0x7fffa5682de0 NIP: 00007fffa5682de0 LR: 0000000000000000 CTR: 0000000000000000 REGS: c000000034847e80 TRAP: 3000 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e) MSR: 900000000280f033 CR: 44002408 XER: 00000000 The address being probed has some special: cmdline_proc_show: Probe based on ftrace cmdline_proc_show+16: Probe for the next instruction at the ftrace location The ftrace-based kprobe does not generate kprobe::ainsn::insn, it gets set to NULL. In arch_prepare_kprobe() it will check for: ... prev = get_kprobe(p->addr - 1); preempt_enable_no_resched(); if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) { ... If prev is based on ftrace, 'ppc_inst_read(prev->ainsn.insn)' will occur with a null pointer reference. At this point prev->addr will not be a prefixed instruction, so the check can be skipped. Check if prev is ftrace-based kprobe before reading 'prev->ainsn.insn' to fix this problem. Fixes: b4657f7650ba ("powerpc/kprobes: Don't allow breakpoints on suffixes") Signed-off-by: Li Huafei [mpe: Trim oops] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220923093253.177298-1-lihuafei1@huawei.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/kprobes.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 7a7cd6bda53e..61552f57db0b 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -140,7 +140,13 @@ int arch_prepare_kprobe(struct kprobe *p) preempt_disable(); prev = get_kprobe(p->addr - 1); preempt_enable_no_resched(); - if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) { + + /* + * When prev is a ftrace-based kprobe, we don't have an insn, and it + * doesn't probe for prefixed instruction. + */ + if (prev && !kprobe_ftrace(prev) && + ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) { printk("Cannot register a kprobe on the second word of prefixed instruction\n"); ret = -EINVAL; } From 8484023b5763e1c981321b415fae8b83a8fe257c Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Wed, 28 Sep 2022 18:57:33 -0700 Subject: [PATCH 372/610] powerpc/pseries/vas: Pass hw_cpu_id to node associativity HCALL [ Upstream commit f3e5d9e53e74d77e711a2c90a91a8b0836a9e0b3 ] Generally the hypervisor decides to allocate a window on different VAS instances. But if user space wishes to allocate on the current VAS instance where the process is executing, the kernel has to pass associativity domain IDs to allocate VAS window HCALL. To determine the associativity domain IDs for the current CPU, smp_processor_id() is passed to node associativity HCALL which may return H_P2 (-55) error during DLPAR CPU event. This is because Linux CPU numbers (smp_processor_id()) are not the same as the hypervisor's view of CPU numbers. Fix the issue by passing hard_smp_processor_id() with VPHN_FLAG_VCPU flag (PAPR 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY). Fixes: b22f2d88e435 ("powerpc/pseries/vas: Integrate API with open/close windows") Reviewed-by: Nathan Lynch Signed-off-by: Haren Myneni [mpe: Update change log to mention Linux vs HV CPU numbers] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/55380253ea0c11341824cd4c0fc6bbcfc5752689.camel@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/pseries/vas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c index b043e3936d21..15046d80f042 100644 --- a/arch/powerpc/platforms/pseries/vas.c +++ b/arch/powerpc/platforms/pseries/vas.c @@ -324,7 +324,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, * So no unpacking needs to be done. */ rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, domain, - VPHN_FLAG_VCPU, smp_processor_id()); + VPHN_FLAG_VCPU, hard_smp_processor_id()); if (rc != H_SUCCESS) { pr_err("H_HOME_NODE_ASSOCIATIVITY error: %d\n", rc); goto out; From e0b4ebf598345beec6b6916b2921bde4b05902ae Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Mon, 25 Jul 2022 12:09:28 +0800 Subject: [PATCH 373/610] crypto: sahara - don't sleep when in softirq [ Upstream commit 108586eba094b318e6a831f977f4ddcc403a15da ] Function of sahara_aes_crypt maybe could be called by function of crypto_skcipher_encrypt during the rx softirq, so it is not allowed to use mutex lock. Fixes: c0c3c89ae347 ("crypto: sahara - replace tasklets with...") Signed-off-by: Zhengchao Shao Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/sahara.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c index 457084b344c1..b07ae4ba165e 100644 --- a/drivers/crypto/sahara.c +++ b/drivers/crypto/sahara.c @@ -26,10 +26,10 @@ #include #include #include -#include #include #include #include +#include #define SHA_BUFFER_LEN PAGE_SIZE #define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE @@ -196,7 +196,7 @@ struct sahara_dev { void __iomem *regs_base; struct clk *clk_ipg; struct clk *clk_ahb; - struct mutex queue_mutex; + spinlock_t queue_spinlock; struct task_struct *kthread; struct completion dma_completion; @@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) rctx->mode = mode; - mutex_lock(&dev->queue_mutex); + spin_lock_bh(&dev->queue_spinlock); err = crypto_enqueue_request(&dev->queue, &req->base); - mutex_unlock(&dev->queue_mutex); + spin_unlock_bh(&dev->queue_spinlock); wake_up_process(dev->kthread); @@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data) do { __set_current_state(TASK_INTERRUPTIBLE); - mutex_lock(&dev->queue_mutex); + spin_lock_bh(&dev->queue_spinlock); backlog = crypto_get_backlog(&dev->queue); async_req = crypto_dequeue_request(&dev->queue); - mutex_unlock(&dev->queue_mutex); + spin_unlock_bh(&dev->queue_spinlock); if (backlog) backlog->complete(backlog, -EINPROGRESS); @@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) rctx->first = 1; } - mutex_lock(&dev->queue_mutex); + spin_lock_bh(&dev->queue_spinlock); ret = crypto_enqueue_request(&dev->queue, &req->base); - mutex_unlock(&dev->queue_mutex); + spin_unlock_bh(&dev->queue_spinlock); wake_up_process(dev->kthread); @@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev) crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH); - mutex_init(&dev->queue_mutex); + spin_lock_init(&dev->queue_spinlock); dev_ptr = dev; From 272093471305261c4e07a2fc97c2d1e53cd56819 Mon Sep 17 00:00:00 2001 From: Ye Weihua Date: Thu, 28 Jul 2022 10:07:58 +0800 Subject: [PATCH 374/610] crypto: hisilicon/zip - fix mismatch in get/set sgl_sge_nr [ Upstream commit d74f9340097a881869c4c22ca376654cc2516ecc ] KASAN reported this Bug: [17619.659757] BUG: KASAN: global-out-of-bounds in param_get_int+0x34/0x60 [17619.673193] Read of size 4 at addr fffff01332d7ed00 by task read_all/1507958 ... [17619.698934] The buggy address belongs to the variable: [17619.708371] sgl_sge_nr+0x0/0xffffffffffffa300 [hisi_zip] There is a mismatch in hisi_zip when get/set the variable sgl_sge_nr. The type of sgl_sge_nr is u16, and get/set sgl_sge_nr by param_get/set_int. Replacing param_get/set_int to param_get/set_ushort can fix this bug. Fixes: f081fda293ffb ("crypto: hisilicon - add sgl_sge_nr module param for zip") Signed-off-by: Ye Weihua Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/hisilicon/zip/zip_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c index 9520a4113c81..a91e6e0e9c69 100644 --- a/drivers/crypto/hisilicon/zip/zip_crypto.c +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c @@ -122,12 +122,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp) if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX) return -EINVAL; - return param_set_int(val, kp); + return param_set_ushort(val, kp); } static const struct kernel_param_ops sgl_sge_nr_ops = { .set = sgl_sge_nr_set, - .get = param_get_int, + .get = param_get_ushort, }; static u16 sgl_sge_nr = HZIP_SGL_SGE_NR; From 8ffe511b7de72712e7210894e9e71d184a43d33c Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Mon, 1 Aug 2022 20:04:18 +0000 Subject: [PATCH 375/610] hwrng: arm-smccc-trng - fix NO_ENTROPY handling [ Upstream commit 042b4b169c6fb9d4df268d66282d7302dd73d37b ] The SMCCC_RET_TRNG_NO_ENTROPY switch arm is never used because the NO_ENTROPY return value is negative and negative values are handled above the switch by immediately returning. Fix by handling errors using a default arm in the switch. Fixes: 0888d04b47a1 ("hwrng: Add Arm SMCCC TRNG based driver") Signed-off-by: James Cowgill Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/char/hw_random/arm_smccc_trng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/hw_random/arm_smccc_trng.c b/drivers/char/hw_random/arm_smccc_trng.c index b24ac39a903b..e34c3ea692b6 100644 --- a/drivers/char/hw_random/arm_smccc_trng.c +++ b/drivers/char/hw_random/arm_smccc_trng.c @@ -71,8 +71,6 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait) MAX_BITS_PER_CALL); arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND, bits, &res); - if ((int)res.a0 < 0) - return (int)res.a0; switch ((int)res.a0) { case SMCCC_RET_SUCCESS: @@ -88,6 +86,8 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait) return copied; cond_resched(); break; + default: + return -EIO; } } From 507128a0e32dbd80f5d277f4f1730e55ea504499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Koutn=C3=BD?= Date: Fri, 26 Aug 2022 18:52:35 +0200 Subject: [PATCH 376/610] cgroup: Honor caller's cgroup NS when resolving path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 74e4b956eb1cac0e4c10c240339b1bbfbc9a4c48 ] cgroup_get_from_path() is not widely used function. Its callers presume the path is resolved under cgroup namespace. (There is one caller currently and resolving in init NS won't make harm (netfilter). However, future users may be subject to different effects when resolving globally.) Since, there's currently no use for the global resolution, modify the existing function to take cgroup NS into account. Fixes: a79a908fd2b0 ("cgroup: introduce cgroup namespaces") Signed-off-by: Michal Koutný Signed-off-by: Tejun Heo Signed-off-by: Sasha Levin --- kernel/cgroup/cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 4b19f7fc4deb..a92990f070d1 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -6598,8 +6598,12 @@ struct cgroup *cgroup_get_from_path(const char *path) { struct kernfs_node *kn; struct cgroup *cgrp = ERR_PTR(-ENOENT); + struct cgroup *root_cgrp; - kn = kernfs_walk_and_get(cgrp_dfl_root.cgrp.kn, path); + spin_lock_irq(&css_set_lock); + root_cgrp = current_cgns_cgroup_from_root(&cgrp_dfl_root); + kn = kernfs_walk_and_get(root_cgrp->kn, path); + spin_unlock_irq(&css_set_lock); if (!kn) goto out; From 3bfc220e5ce3c30e2f25168dd41a7aa8f68fc7aa Mon Sep 17 00:00:00 2001 From: Kshitiz Varshney Date: Mon, 22 Aug 2022 13:19:03 +0200 Subject: [PATCH 377/610] hwrng: imx-rngc - Moving IRQ handler registering after imx_rngc_irq_mask_clear() [ Upstream commit 10a2199caf437e893d9027d97700b3c6010048b7 ] Issue: While servicing interrupt, if the IRQ happens to be because of a SEED_DONE due to a previous boot stage, you end up completing the completion prematurely, hence causing kernel to crash while booting. Fix: Moving IRQ handler registering after imx_rngc_irq_mask_clear() Fixes: 1d5449445bd0 (hwrng: mx-rngc - add a driver for Freescale RNGC) Signed-off-by: Kshitiz Varshney Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/char/hw_random/imx-rngc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index b05d676ca814..2964efeb71c3 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -270,13 +270,6 @@ static int imx_rngc_probe(struct platform_device *pdev) goto err; } - ret = devm_request_irq(&pdev->dev, - irq, imx_rngc_irq, 0, pdev->name, (void *)rngc); - if (ret) { - dev_err(rngc->dev, "Can't get interrupt working.\n"); - goto err; - } - init_completion(&rngc->rng_op_done); rngc->rng.name = pdev->name; @@ -290,6 +283,13 @@ static int imx_rngc_probe(struct platform_device *pdev) imx_rngc_irq_mask_clear(rngc); + ret = devm_request_irq(&pdev->dev, + irq, imx_rngc_irq, 0, pdev->name, (void *)rngc); + if (ret) { + dev_err(rngc->dev, "Can't get interrupt working.\n"); + return ret; + } + if (self_test) { ret = imx_rngc_self_test(rngc); if (ret) { From 9bf3ec61a246037b0bab1e64dcf70945d3bde5b9 Mon Sep 17 00:00:00 2001 From: Lucas Segarra Fernandez Date: Thu, 25 Aug 2022 12:32:16 +0200 Subject: [PATCH 378/610] crypto: qat - fix default value of WDT timer [ Upstream commit cc40b04c08400d86d2d6ea0159e0617e717f729c ] The QAT HW supports an hardware mechanism to detect an accelerator hang. The reporting of a hang occurs after a watchdog timer (WDT) expires. The value of the WDT set previously was too small and was causing false positives. Change the default value of the WDT to 0x7000000ULL to avoid this. Fixes: 1c4d9d5bbb5a ("crypto: qat - enable detection of accelerators hang") Reviewed-by: Giovanni Cabiddu Signed-off-by: Lucas Segarra Fernandez Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h index b8fca1ff7aab..0b7086cae00b 100644 --- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h @@ -99,7 +99,7 @@ do { \ * Timeout is in cycles. Clock speed may vary across products but this * value should be a few milli-seconds. */ -#define ADF_SSM_WDT_DEFAULT_VALUE 0x200000 +#define ADF_SSM_WDT_DEFAULT_VALUE 0x7000000ULL #define ADF_SSM_WDT_PKE_DEFAULT_VALUE 0x8000000 #define ADF_SSMWDTL_OFFSET 0x54 #define ADF_SSMWDTH_OFFSET 0x5C From 771d8aa02dac7dbd268570e15e1100ca1258801a Mon Sep 17 00:00:00 2001 From: Weili Qian Date: Sat, 27 Aug 2022 18:27:37 +0800 Subject: [PATCH 379/610] crypto: hisilicon/qm - fix missing put dfx access [ Upstream commit 5afc904f443de2afd31c4e0686ba178beede86fe ] In function qm_cmd_write(), if function returns from branch 'atomic_read(&qm->status.flags) == QM_STOP', the got dfx access is forgotten to put. Fixes: 607c191b371d ("crypto: hisilicon - support runtime PM for accelerator device") Signed-off-by: Weili Qian Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/hisilicon/qm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index b616d2d8e773..b8900a5dbf6e 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -1888,8 +1888,10 @@ static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer, return ret; /* Judge if the instance is being reset. */ - if (unlikely(atomic_read(&qm->status.flags) == QM_STOP)) - return 0; + if (unlikely(atomic_read(&qm->status.flags) == QM_STOP)) { + ret = 0; + goto put_dfx_access; + } if (count > QM_DBG_WRITE_LEN) { ret = -ENOSPC; From 046803b74d510f6ea61b3890ba8a7a20120c9ef6 Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Thu, 1 Sep 2022 16:57:36 -0400 Subject: [PATCH 380/610] cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset [ Upstream commit ec5fbdfb99d18482619ac42605cb80fbb56068ee ] Previously, update_tasks_cpumask() is not supposed to be called with top cpuset. With cpuset partition that takes CPUs away from the top cpuset, adjusting the cpus_mask of the tasks in the top cpuset is necessary. Percpu kthreads, however, are ignored. Fixes: ee8dde0cd2ce ("cpuset: Add new v2 cpuset.sched.partition flag") Signed-off-by: Waiman Long Signed-off-by: Tejun Heo Signed-off-by: Sasha Levin --- kernel/cgroup/cpuset.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 3213d3c8ea0a..428820bf141d 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1087,10 +1088,18 @@ static void update_tasks_cpumask(struct cpuset *cs) { struct css_task_iter it; struct task_struct *task; + bool top_cs = cs == &top_cpuset; css_task_iter_start(&cs->css, 0, &it); - while ((task = css_task_iter_next(&it))) + while ((task = css_task_iter_next(&it))) { + /* + * Percpu kthreads in top_cpuset are ignored + */ + if (top_cs && (task->flags & PF_KTHREAD) && + kthread_is_per_cpu(task)) + continue; set_cpus_allowed_ptr(task, cs->effective_cpus); + } css_task_iter_end(&it); } @@ -2052,12 +2061,7 @@ static int update_prstate(struct cpuset *cs, int new_prs) update_flag(CS_CPU_EXCLUSIVE, cs, 0); } - /* - * Update cpumask of parent's tasks except when it is the top - * cpuset as some system daemons cannot be mapped to other CPUs. - */ - if (parent != &top_cpuset) - update_tasks_cpumask(parent); + update_tasks_cpumask(parent); if (parent->child_ecpus_count) update_sibling_cpumasks(parent, cs, &tmpmask); From 0c7043a5b5c3b35f5dc8875757f71e7f491d64d4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 4 Aug 2022 17:32:39 +0300 Subject: [PATCH 381/610] iommu/omap: Fix buffer overflow in debugfs [ Upstream commit 184233a5202786b20220acd2d04ddf909ef18f29 ] There are two issues here: 1) The "len" variable needs to be checked before the very first write. Otherwise if omap2_iommu_dump_ctx() with "bytes" less than 32 it is a buffer overflow. 2) The snprintf() function returns the number of bytes that *would* have been copied if there were enough space. But we want to know the number of bytes which were *actually* copied so use scnprintf() instead. Fixes: bd4396f09a4a ("iommu/omap: Consolidate OMAP IOMMU modules") Signed-off-by: Dan Carpenter Reviewed-by: Robin Murphy Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/YuvYh1JbE3v+abd5@kili Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/omap-iommu-debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index a99afb5d9011..259f65291d90 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -32,12 +32,12 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj) ssize_t bytes; \ const char *str = "%20s: %08x\n"; \ const int maxcol = 32; \ - bytes = snprintf(p, maxcol, str, __stringify(name), \ + if (len < maxcol) \ + goto out; \ + bytes = scnprintf(p, maxcol, str, __stringify(name), \ iommu_read_reg(obj, MMU_##name)); \ p += bytes; \ len -= bytes; \ - if (len < maxcol) \ - goto out; \ } while (0) static ssize_t From 779a9930f3e152c82699feb389a0e6d6644e747e Mon Sep 17 00:00:00 2001 From: Ignat Korchagin Date: Wed, 31 Aug 2022 19:37:06 +0100 Subject: [PATCH 382/610] crypto: akcipher - default implementation for setting a private key [ Upstream commit bc155c6c188c2f0c5749993b1405673d25a80389 ] Changes from v1: * removed the default implementation from set_pub_key: it is assumed that an implementation must always have this callback defined as there are no use case for an algorithm, which doesn't need a public key Many akcipher implementations (like ECDSA) support only signature verifications, so they don't have all callbacks defined. Commit 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") introduced default callbacks for sign/verify operations, which just return an error code. However, these are not enough, because before calling sign the caller would likely call set_priv_key first on the instantiated transform (as the in-kernel testmgr does). This function does not have a default stub, so the kernel crashes, when trying to set a private key on an akcipher, which doesn't support signature generation. I've noticed this, when trying to add a KAT vector for ECDSA signature to the testmgr. With this patch the testmgr returns an error in dmesg (as it should) instead of crashing the kernel NULL ptr dereference. Fixes: 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") Signed-off-by: Ignat Korchagin Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/akcipher.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crypto/akcipher.c b/crypto/akcipher.c index f866085c8a4a..ab975a420e1e 100644 --- a/crypto/akcipher.c +++ b/crypto/akcipher.c @@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req) return -ENOSYS; } +static int akcipher_default_set_key(struct crypto_akcipher *tfm, + const void *key, unsigned int keylen) +{ + return -ENOSYS; +} + int crypto_register_akcipher(struct akcipher_alg *alg) { struct crypto_alg *base = &alg->base; @@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg) alg->encrypt = akcipher_default_op; if (!alg->decrypt) alg->decrypt = akcipher_default_op; + if (!alg->set_priv_key) + alg->set_priv_key = akcipher_default_set_key; akcipher_prepare_alg(alg); return crypto_register_alg(base); From 93538944ab0b5860c86c9d1601d3954f82ab8ca5 Mon Sep 17 00:00:00 2001 From: Koba Ko Date: Thu, 1 Sep 2022 22:47:12 +0800 Subject: [PATCH 383/610] crypto: ccp - Release dma channels before dmaengine unrgister [ Upstream commit 68dbe80f5b510c66c800b9e8055235c5b07e37d1 ] A warning is shown during shutdown, __dma_async_device_channel_unregister called while 2 clients hold a reference WARNING: CPU: 15 PID: 1 at drivers/dma/dmaengine.c:1110 __dma_async_device_channel_unregister+0xb7/0xc0 Call dma_release_channel for occupied channles before dma_async_device_unregister. Fixes: 54cce8ecb925 ("crypto: ccp - ccp_dmaengine_unregister release dma channels") Reported-by: kernel test robot Signed-off-by: Koba Ko Acked-by: Tom Lendacky Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/ccp-dmaengine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c index 7d4b4ad1db1f..9f753cb4f5f1 100644 --- a/drivers/crypto/ccp/ccp-dmaengine.c +++ b/drivers/crypto/ccp/ccp-dmaengine.c @@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp) 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); + tasklet_kill(&chan->cleanup_tasklet); list_del_rcu(&dma_chan->device_node); } @@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp) if (!dmaengine) return; - dma_async_device_unregister(dma_dev); ccp_dma_release(ccp); + dma_async_device_unregister(dma_dev); kmem_cache_destroy(ccp->dma_desc_cache); kmem_cache_destroy(ccp->dma_cmd_cache); From 393307b99aac573bffc623311e7fbfe78d4ccc24 Mon Sep 17 00:00:00 2001 From: Peter Harliman Liem Date: Tue, 6 Sep 2022 10:51:28 +0800 Subject: [PATCH 384/610] crypto: inside-secure - Change swab to swab32 [ Upstream commit 664593407e936b6438fbfaaf98876910fd31cf9a ] The use of swab() is causing failures in 64-bit arch, as it translates to __swab64() instead of the intended __swab32(). It eventually causes wrong results in xcbcmac & cmac algo. Fixes: 78cf1c8bfcb8 ("crypto: inside-secure - Move ipad/opad into safexcel_context") Signed-off-by: Peter Harliman Liem Acked-by: Antoine Tenart Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c index bc60b5802256..2124416742f8 100644 --- a/drivers/crypto/inside-secure/safexcel_hash.c +++ b/drivers/crypto/inside-secure/safexcel_hash.c @@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring, u32 x; x = ipad[i] ^ ipad[i + 4]; - cache[i] ^= swab(x); + cache[i] ^= swab32(x); } } cache_len = AES_BLOCK_SIZE; @@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq) u32 *result = (void *)areq->result; /* K3 */ - result[i] = swab(ctx->base.ipad.word[i + 4]); + result[i] = swab32(ctx->base.ipad.word[i + 4]); } areq->result[0] ^= 0x80; // 10- padding crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result); @@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"); for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++) - ctx->base.ipad.word[i] = swab(key_tmp[i]); + ctx->base.ipad.word[i] = swab32(key_tmp[i]); crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) & @@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, return ret; for (i = 0; i < len / sizeof(u32); i++) - ctx->base.ipad.word[i + 8] = swab(aes.key_enc[i]); + ctx->base.ipad.word[i + 8] = swab32(aes.key_enc[i]); /* precompute the CMAC key material */ crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK); From 1f1ab76e251521bd2fa5244473efcf663792745d Mon Sep 17 00:00:00 2001 From: Damian Muszynski Date: Fri, 9 Sep 2022 11:49:12 +0100 Subject: [PATCH 385/610] crypto: qat - fix DMA transfer direction [ Upstream commit cf5bb835b7c8a5fee7f26455099cca7feb57f5e9 ] When CONFIG_DMA_API_DEBUG is selected, while running the crypto self test on the QAT crypto algorithms, the function add_dma_entry() reports a warning similar to the one below, saying that overlapping mappings are not supported. This occurs in tests where the input and the output scatter list point to the same buffers (i.e. two different scatter lists which point to the same chunks of memory). The logic that implements the mapping uses the flag DMA_BIDIRECTIONAL for both the input and the output scatter lists which leads to overlapped write mappings. These are not supported by the DMA layer. Fix by specifying the correct DMA transfer directions when mapping buffers. For in-place operations where the input scatter list matches the output scatter list, buffers are mapped once with DMA_BIDIRECTIONAL, otherwise input buffers are mapped using the flag DMA_TO_DEVICE and output buffers are mapped with DMA_FROM_DEVICE. Overlapping a read mapping with a write mapping is a valid case in dma-coherent devices like QAT. The function that frees and unmaps the buffers, qat_alg_free_bufl() has been changed accordingly to the changes to the mapping function. DMA-API: 4xxx 0000:06:00.0: cacheline tracking EEXIST, overlapping mappings aren't supported WARNING: CPU: 53 PID: 4362 at kernel/dma/debug.c:570 add_dma_entry+0x1e9/0x270 ... Call Trace: dma_map_page_attrs+0x82/0x2d0 ? preempt_count_add+0x6a/0xa0 qat_alg_sgl_to_bufl+0x45b/0x990 [intel_qat] qat_alg_aead_dec+0x71/0x250 [intel_qat] crypto_aead_decrypt+0x3d/0x70 test_aead_vec_cfg+0x649/0x810 ? number+0x310/0x3a0 ? vsnprintf+0x2a3/0x550 ? scnprintf+0x42/0x70 ? valid_sg_divisions.constprop.0+0x86/0xa0 ? test_aead_vec+0xdf/0x120 test_aead_vec+0xdf/0x120 alg_test_aead+0x185/0x400 alg_test+0x3d8/0x500 ? crypto_acomp_scomp_free_ctx+0x30/0x30 ? __schedule+0x32a/0x12a0 ? ttwu_queue_wakelist+0xbf/0x110 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? try_to_wake_up+0x83/0x570 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? __set_cpus_allowed_ptr_locked+0xea/0x1b0 ? crypto_acomp_scomp_free_ctx+0x30/0x30 cryptomgr_test+0x27/0x50 kthread+0xe6/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 Fixes: d370cec ("crypto: qat - Intel(R) QAT crypto interface") Link: https://lore.kernel.org/linux-crypto/20220223080400.139367-1-gilad@benyossef.com/ Signed-off-by: Damian Muszynski Signed-off-by: Giovanni Cabiddu Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/qat_algs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index 873533dc43a7..9abdaf7cd2cf 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst, dma_addr_t blpout = qat_req->buf.bloutp; size_t sz = qat_req->buf.sz; size_t sz_out = qat_req->buf.sz_out; + int bl_dma_dir; int i; + bl_dma_dir = blp != blpout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; + for (i = 0; i < bl->num_bufs; i++) dma_unmap_single(dev, bl->bufers[i].addr, - bl->bufers[i].len, DMA_BIDIRECTIONAL); + bl->bufers[i].len, bl_dma_dir); dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE); @@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst, for (i = bufless; i < blout->num_bufs; i++) { dma_unmap_single(dev, blout->bufers[i].addr, blout->bufers[i].len, - DMA_BIDIRECTIONAL); + DMA_FROM_DEVICE); } dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE); @@ -715,6 +718,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, struct scatterlist *sg; size_t sz_out, sz = struct_size(bufl, bufers, n); int node = dev_to_node(&GET_DEV(inst->accel_dev)); + int bufl_dma_dir; if (unlikely(!n)) return -EINVAL; @@ -732,6 +736,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, qat_req->buf.sgl_src_valid = true; } + bufl_dma_dir = sgl != sglout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL; + for_each_sg(sgl, sg, n, i) bufl->bufers[i].addr = DMA_MAPPING_ERROR; @@ -743,7 +749,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg), sg->length, - DMA_BIDIRECTIONAL); + bufl_dma_dir); bufl->bufers[y].len = sg->length; if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr))) goto err_in; @@ -786,7 +792,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufers[y].addr = dma_map_single(dev, sg_virt(sg), sg->length, - DMA_BIDIRECTIONAL); + DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(dev, bufers[y].addr))) goto err_out; bufers[y].len = sg->length; @@ -816,7 +822,7 @@ err_out: if (!dma_mapping_error(dev, buflout->bufers[i].addr)) dma_unmap_single(dev, buflout->bufers[i].addr, buflout->bufers[i].len, - DMA_BIDIRECTIONAL); + DMA_FROM_DEVICE); if (!qat_req->buf.sgl_dst_valid) kfree(buflout); @@ -830,7 +836,7 @@ err_in: if (!dma_mapping_error(dev, bufl->bufers[i].addr)) dma_unmap_single(dev, bufl->bufers[i].addr, bufl->bufers[i].len, - DMA_BIDIRECTIONAL); + bufl_dma_dir); if (!qat_req->buf.sgl_src_valid) kfree(bufl); From f0cac6cc02a9b965bcee3e980bf8ed5056cdfce0 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Fri, 16 Sep 2022 20:57:05 -0300 Subject: [PATCH 386/610] cifs: return correct error in ->calc_signature() [ Upstream commit 09a1f9a168ae1f69f701689429871793174417d2 ] If an error happens while getting the key or session in the ->calc_signature implementations, 0 (success) is returned. Fix it by returning a proper error code. Since it seems to be highly unlikely to happen wrap the rc check in unlikely() too. Reviewed-by: Ronnie Sahlberg Fixes: 32811d242ff6 ("cifs: Start using per session key for smb2/3 for signature generation") Signed-off-by: Enzo Matsumiya Signed-off-by: Steve French Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2transport.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index f59b956f9d25..390cc5e8c746 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -221,9 +221,9 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, struct smb_rqst drqst; ses = smb2_find_smb_ses(server, shdr->SessionId); - if (!ses) { + if (unlikely(!ses)) { cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); - return 0; + return -ENOENT; } memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); @@ -542,8 +542,10 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, u8 key[SMB3_SIGN_KEY_SIZE]; rc = smb2_get_sign_key(shdr->SessionId, server, key); - if (rc) - return 0; + if (unlikely(rc)) { + cifs_server_dbg(VFS, "%s: Could not get signing key\n", __func__); + return rc; + } if (allocate_crypto) { rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc); From a9990f24adfebdb7983da2904a5497c61cab2e7c Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 13 Sep 2022 12:47:20 +0100 Subject: [PATCH 387/610] iommu/iova: Fix module config properly [ Upstream commit 4f58330fcc8482aa90674e1f40f601e82f18ed4a ] IOMMU_IOVA is intended to be an optional library for users to select as and when they desire. Since it can be a module now, this means that built-in code which has chosen not to select it should not fail to link if it happens to have selected as a module by someone else. Replace IS_ENABLED() with IS_REACHABLE() to do the right thing. CC: Thierry Reding Reported-by: John Garry Fixes: 15bbdec3931e ("iommu: Make the iova library a module") Signed-off-by: Robin Murphy Reviewed-by: Thierry Reding Link: https://lore.kernel.org/r/548c2f683ca379aface59639a8f0cccc3a1ac050.1663069227.git.robin.murphy@arm.com Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- include/linux/iova.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/iova.h b/include/linux/iova.h index 71d8a2de6635..6b6cc104e300 100644 --- a/include/linux/iova.h +++ b/include/linux/iova.h @@ -133,7 +133,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova) return iova >> iova_shift(iovad); } -#if IS_ENABLED(CONFIG_IOMMU_IOVA) +#if IS_REACHABLE(CONFIG_IOMMU_IOVA) int iova_cache_get(void); void iova_cache_put(void); From 867fce09aa203b986ce297740c5a6f719013806a Mon Sep 17 00:00:00 2001 From: Yipeng Zou Date: Mon, 19 Sep 2022 20:56:28 +0800 Subject: [PATCH 388/610] tracing: kprobe: Fix kprobe event gen test module on exit [ Upstream commit ac48e189527fae87253ef2bf58892e782fb36874 ] Correct gen_kretprobe_test clr event para on module exit. This will make it can't to delete. Link: https://lkml.kernel.org/r/20220919125629.238242-2-zouyipeng@huawei.com Cc: Cc: Cc: Cc: Cc: Cc: Cc: Cc: Fixes: 64836248dda2 ("tracing: Add kprobe event command generation test module") Signed-off-by: Yipeng Zou Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/kprobe_event_gen_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c index 18b0f1cbb947..e023154be0f8 100644 --- a/kernel/trace/kprobe_event_gen_test.c +++ b/kernel/trace/kprobe_event_gen_test.c @@ -206,7 +206,7 @@ static void __exit kprobe_event_gen_test_exit(void) WARN_ON(kprobe_event_delete("gen_kprobe_test")); /* Disable the event or you can't remove it */ - WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr, + WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr, "kprobes", "gen_kretprobe_test", false)); From 84795de93e1f25e37323d886267958ae10b3afe3 Mon Sep 17 00:00:00 2001 From: Yipeng Zou Date: Mon, 19 Sep 2022 20:56:29 +0800 Subject: [PATCH 389/610] tracing: kprobe: Make gen test module work in arm and riscv [ Upstream commit d8ef45d66c01425ff748e13ef7dd1da7a91cc93c ] For now, this selftest module can only work in x86 because of the kprobe cmd was fixed use of x86 registers. This patch adapted to register names under arm and riscv, So that this module can be worked on those platform. Link: https://lkml.kernel.org/r/20220919125629.238242-3-zouyipeng@huawei.com Cc: Cc: Cc: Cc: Cc: Cc: Cc: Cc: Fixes: 64836248dda2 ("tracing: Add kprobe event command generation test module") Signed-off-by: Yipeng Zou Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/kprobe_event_gen_test.c | 47 +++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c index e023154be0f8..80e04a1e1977 100644 --- a/kernel/trace/kprobe_event_gen_test.c +++ b/kernel/trace/kprobe_event_gen_test.c @@ -35,6 +35,45 @@ static struct trace_event_file *gen_kprobe_test; static struct trace_event_file *gen_kretprobe_test; +#define KPROBE_GEN_TEST_FUNC "do_sys_open" + +/* X86 */ +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32) +#define KPROBE_GEN_TEST_ARG0 "dfd=%ax" +#define KPROBE_GEN_TEST_ARG1 "filename=%dx" +#define KPROBE_GEN_TEST_ARG2 "flags=%cx" +#define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)" + +/* ARM64 */ +#elif defined(CONFIG_ARM64) +#define KPROBE_GEN_TEST_ARG0 "dfd=%x0" +#define KPROBE_GEN_TEST_ARG1 "filename=%x1" +#define KPROBE_GEN_TEST_ARG2 "flags=%x2" +#define KPROBE_GEN_TEST_ARG3 "mode=%x3" + +/* ARM */ +#elif defined(CONFIG_ARM) +#define KPROBE_GEN_TEST_ARG0 "dfd=%r0" +#define KPROBE_GEN_TEST_ARG1 "filename=%r1" +#define KPROBE_GEN_TEST_ARG2 "flags=%r2" +#define KPROBE_GEN_TEST_ARG3 "mode=%r3" + +/* RISCV */ +#elif defined(CONFIG_RISCV) +#define KPROBE_GEN_TEST_ARG0 "dfd=%a0" +#define KPROBE_GEN_TEST_ARG1 "filename=%a1" +#define KPROBE_GEN_TEST_ARG2 "flags=%a2" +#define KPROBE_GEN_TEST_ARG3 "mode=%a3" + +/* others */ +#else +#define KPROBE_GEN_TEST_ARG0 NULL +#define KPROBE_GEN_TEST_ARG1 NULL +#define KPROBE_GEN_TEST_ARG2 NULL +#define KPROBE_GEN_TEST_ARG3 NULL +#endif + + /* * Test to make sure we can create a kprobe event, then add more * fields. @@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void) * fields. */ ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test", - "do_sys_open", - "dfd=%ax", "filename=%dx"); + KPROBE_GEN_TEST_FUNC, + KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1); if (ret) goto free; /* Use kprobe_event_add_fields to add the rest of the fields */ - ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)"); + ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3); if (ret) goto free; @@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void) * Define the kretprobe event. */ ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test", - "do_sys_open", + KPROBE_GEN_TEST_FUNC, "$retval"); if (ret) goto free; From 1e9c23db31b6a004a04f39f646886d02c944632a Mon Sep 17 00:00:00 2001 From: Nico Pache Date: Mon, 19 Sep 2022 08:49:32 -0600 Subject: [PATCH 390/610] tracing/osnoise: Fix possible recursive locking in stop_per_cpu_kthreads [ Upstream commit 99ee9317a1305cd5626736785c8cb38b0e47686c ] There is a recursive lock on the cpu_hotplug_lock. In kernel/trace/trace_osnoise.c:_per_cpu_kthreads: - start_per_cpu_kthreads calls cpus_read_lock() and if start_kthreads returns a error it will call stop_per_cpu_kthreads. - stop_per_cpu_kthreads then calls cpus_read_lock() again causing deadlock. Fix this by calling cpus_read_unlock() before calling stop_per_cpu_kthreads. This behavior can also be seen in commit f46b16520a08 ("trace/hwlat: Implement the per-cpu mode"). This error was noticed during the LTP ftrace-stress-test: WARNING: possible recursive locking detected -------------------------------------------- sh/275006 is trying to acquire lock: ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: stop_per_cpu_kthreads but task is already holding lock: ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(cpu_hotplug_lock); lock(cpu_hotplug_lock); *** DEADLOCK *** May be due to missing lock nesting notation 3 locks held by sh/275006: #0: ffff8881023f0470 (sb_writers#24){.+.+}-{0:0}, at: ksys_write #1: ffffffffb084f430 (trace_types_lock){+.+.}-{3:3}, at: rb_simple_write #2: ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads Link: https://lkml.kernel.org/r/20220919144932.3064014-1-npache@redhat.com Fixes: c8895e271f79 ("trace/osnoise: Support hotplug operations") Signed-off-by: Nico Pache Acked-by: Daniel Bristot de Oliveira Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/trace_osnoise.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 93de784ee681..6ef1164c0440 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -1598,8 +1598,9 @@ static int start_per_cpu_kthreads(struct trace_array *tr) for_each_cpu(cpu, current_mask) { retval = start_kthread(cpu); if (retval) { + cpus_read_unlock(); stop_per_cpu_kthreads(); - break; + return retval; } } From 059ce6b68b76ca04331608e07adb18ebd16de6f2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 7 Aug 2022 09:48:09 +0900 Subject: [PATCH 391/610] kbuild: remove the target in signal traps when interrupted [ Upstream commit a7f3257da8a86b96fb9bf1bba40ae0bbd7f1885a ] When receiving some signal, GNU Make automatically deletes the target if it has already been changed by the interrupted recipe. If the target is possibly incomplete due to interruption, it must be deleted so that it will be remade from scratch on the next run of make. Otherwise, the target would remain corrupted permanently because its timestamp had already been updated. Thanks to this behavior of Make, you can stop the build any time by pressing Ctrl-C, and just run 'make' to resume it. Kbuild also relies on this feature, but it is equivalently important for any build systems that make decisions based on timestamps (if you want to support Ctrl-C reliably). However, this does not always work as claimed; Make immediately dies with Ctrl-C if its stderr goes into a pipe. [Test Makefile] foo: echo hello > $@ sleep 3 echo world >> $@ [Test Result] $ make # hit Ctrl-C echo hello > foo sleep 3 ^Cmake: *** Deleting file 'foo' make: *** [Makefile:3: foo] Interrupt $ make 2>&1 | cat # hit Ctrl-C echo hello > foo sleep 3 ^C$ # 'foo' is often left-over The reason is because SIGINT is sent to the entire process group. In this example, SIGINT kills 'cat', and 'make' writes the message to the closed pipe, then dies with SIGPIPE before cleaning the target. A typical bad scenario (as reported by [1], [2]) is to save build log by using the 'tee' command: $ make 2>&1 | tee log This can be problematic for any build systems based on Make, so I hope it will be fixed in GNU Make. The maintainer of GNU Make stated this is a long-standing issue and difficult to fix [3]. It has not been fixed yet as of writing. So, we cannot rely on Make cleaning the target. We can do it by ourselves, in signal traps. As far as I understand, Make takes care of SIGHUP, SIGINT, SIGQUIT, and SITERM for the target removal. I added the traps for them, and also for SIGPIPE just in case cmd_* rule prints something to stdout or stderr (but I did not observe an actual case where SIGPIPE was triggered). [Note 1] The trap handler might be worth explaining. rm -f $@; trap - $(sig); kill -s $(sig) $$ This lets the shell kill itself by the signal it caught, so the parent process can tell the child has exited on the signal. Generally, this is a proper manner for handling signals, in case the calling program (like Bash) may monitor WIFSIGNALED() and WTERMSIG() for WCE although this may not be a big deal here because GNU Make handles SIGHUP, SIGINT, SIGQUIT in WUE and SIGTERM in IUE. IUE - Immediate Unconditional Exit WUE - Wait and Unconditional Exit WCE - Wait and Cooperative Exit For details, see "Proper handling of SIGINT/SIGQUIT" [4]. [Note 2] Reverting 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") would directly address [1], but it only saves if_changed_dep. As reported in [2], all commands that use redirection can potentially leave an empty (i.e. broken) target. [Note 3] Another (even safer) approach might be to always write to a temporary file, and rename it to $@ at the end of the recipe. > $(tmp-target) mv $(tmp-target) $@ It would require a lot of Makefile changes, and result in ugly code, so I did not take it. [Note 4] A little more thoughts about a pattern rule with multiple targets (or a grouped target). %.x %.y: %.z When interrupted, GNU Make deletes both %.x and %.y, while this solution only deletes $@. Probably, this is not a big deal. The next run of make will execute the rule again to create $@ along with the other files. [1]: https://lore.kernel.org/all/YLeot94yAaM4xbMY@gmail.com/ [2]: https://lore.kernel.org/all/20220510221333.2770571-1-robh@kernel.org/ [3]: https://lists.gnu.org/archive/html/help-make/2021-06/msg00001.html [4]: https://www.cons.org/cracauer/sigint.html Fixes: 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") Reported-by: Ingo Molnar Reported-by: Rob Herring Signed-off-by: Masahiro Yamada Tested-by: Ingo Molnar Reviewed-by: Nicolas Schier Signed-off-by: Sasha Levin --- scripts/Kbuild.include | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index cdec22088423..914ea5eb16a8 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -96,8 +96,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\ quiet_redirect := silent_redirect := exec >/dev/null; +# Delete the target on interruption +# +# GNU Make automatically deletes the target if it has already been changed by +# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make +# will delete incomplete targets), and resume it later. +# +# However, this does not work when the stderr is piped to another program, like +# $ make >&2 | tee log +# Make dies with SIGPIPE before cleaning the targets. +# +# To address it, we clean the target in signal traps. +# +# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. +# So, we cover them, and also SIGPIPE just in case. +# +# Of course, this is unneeded for phony targets. +delete-on-interrupt = \ + $(if $(filter-out $(PHONY), $@), \ + $(foreach sig, HUP INT QUIT TERM PIPE, \ + trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) + # printing commands -cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1)) +cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1)) ### # if_changed - execute command if any prerequisite is newer than From c963ce2fa05df45cf9b4c0854ed7abb2911132f7 Mon Sep 17 00:00:00 2001 From: Janis Schoetterl-Glausch Date: Fri, 16 Sep 2022 14:41:12 +0200 Subject: [PATCH 392/610] kbuild: rpm-pkg: fix breakage when V=1 is used [ Upstream commit 2e07005f4813a9ff6e895787e0c2d1fea859b033 ] Doing make V=1 binrpm-pkg results in: Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.EgV6qJ + umask 022 + cd . + /bin/rm -rf /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x + /bin/mkdir -p /home/scgl/rpmbuild/BUILDROOT + /bin/mkdir /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x + mkdir -p /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot + make -f ./Makefile image_name + cp test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \ echo >&2; \ echo >&2 " ERROR: Kernel configuration is invalid."; \ echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\ echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo >&2 ; \ /bin/false) arch/s390/boot/bzImage /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot/vmlinuz-6.0.0-rc5+ cp: invalid option -- 'e' Try 'cp --help' for more information. error: Bad exit status from /var/tmp/rpm-tmp.EgV6qJ (%install) Because the make call to get the image name is verbose and prints additional information. Fixes: 993bdde94547 ("kbuild: add image_name to no-sync-config-targets") Signed-off-by: Janis Schoetterl-Glausch Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin --- scripts/package/mkspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 7c477ca7dc98..951cc60e5a90 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -85,10 +85,10 @@ $S mkdir -p %{buildroot}/boot %ifarch ia64 mkdir -p %{buildroot}/boot/efi - cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ %else - cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE %endif $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install From 12acfa1059ad69aa352ddb2bf23ba1b831aff15f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 19 Sep 2022 09:43:19 +0300 Subject: [PATCH 393/610] crypto: marvell/octeontx - prevent integer overflows [ Upstream commit caca37cf6c749ff0303f68418cfe7b757a4e0697 ] The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly. The "code_length * 2" can overflow. The round_up(ucode_size, 16) + sizeof() expression can overflow too. Prevent these overflows. Fixes: d9110b0b01ff ("crypto: marvell - add support for OCTEON TX CPT engine") Signed-off-by: Dan Carpenter Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- .../crypto/marvell/octeontx/otx_cptpf_ucode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c index 40b482198ebc..a765eefb18c2 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c @@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev, struct tar_ucode_info_t *tar_info; struct otx_cpt_ucode_hdr *ucode_hdr; int ucode_type, ucode_size; + unsigned int code_length; /* * If size is less than microcode header size then don't report @@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev, if (get_ucode_type(ucode_hdr, &ucode_type)) return 0; - ucode_size = ntohl(ucode_hdr->code_length) * 2; + code_length = ntohl(ucode_hdr->code_length); + if (code_length >= INT_MAX / 2) { + dev_err(dev, "Invalid code_length %u\n", code_length); + return -EINVAL; + } + + ucode_size = code_length * 2; if (!ucode_size || (size < round_up(ucode_size, 16) + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) { dev_err(dev, "Ucode %s invalid size\n", filename); @@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, { struct otx_cpt_ucode_hdr *ucode_hdr; const struct firmware *fw; + unsigned int code_length; int ret; set_ucode_filename(ucode, ucode_filename); @@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data; memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ); ucode->ver_num = ucode_hdr->ver_num; - ucode->size = ntohl(ucode_hdr->code_length) * 2; + code_length = ntohl(ucode_hdr->code_length); + if (code_length >= INT_MAX / 2) { + dev_err(dev, "Ucode invalid code_length %u\n", code_length); + ret = -EINVAL; + goto release_fw; + } + ucode->size = code_length * 2; if (!ucode->size || (fw->size < round_up(ucode->size, 16) + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) { dev_err(dev, "Ucode %s invalid size\n", ucode_filename); From 172c8a24fc8312cf6b88d3c88469653fdcb1c127 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 19 Sep 2022 09:43:27 +0300 Subject: [PATCH 394/610] crypto: cavium - prevent integer overflow loading firmware [ Upstream commit 2526d6bf27d15054bb0778b2f7bc6625fd934905 ] The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly. The "ntohl(ucode->code_length) * 2" multiplication can have an integer overflow. Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine") Signed-off-by: Dan Carpenter Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/cavium/cpt/cptpf_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c index 8c32d0eb8fcf..6872ac344001 100644 --- a/drivers/crypto/cavium/cpt/cptpf_main.c +++ b/drivers/crypto/cavium/cpt/cptpf_main.c @@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) const struct firmware *fw_entry; struct device *dev = &cpt->pdev->dev; struct ucode_header *ucode; + unsigned int code_length; struct microcode *mcode; int j, ret = 0; @@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) ucode = (struct ucode_header *)fw_entry->data; mcode = &cpt->mcode[cpt->next_mc_idx]; memcpy(mcode->version, (u8 *)fw_entry->data, CPT_UCODE_VERSION_SZ); - mcode->code_size = ntohl(ucode->code_length) * 2; - if (!mcode->code_size) { + code_length = ntohl(ucode->code_length); + if (code_length == 0 || code_length >= INT_MAX / 2) { ret = -EINVAL; goto fw_release; } + mcode->code_size = code_length * 2; mcode->is_ae = is_ae; mcode->core_mask = 0ULL; From 21f1ba52b88c2af062d1a6e52b3ff4ddba2c737d Mon Sep 17 00:00:00 2001 From: Vincent Knecht Date: Thu, 11 Aug 2022 12:50:14 +0200 Subject: [PATCH 395/610] thermal/drivers/qcom/tsens-v0_1: Fix MSM8939 fourth sensor hw_id [ Upstream commit b0c883e900702f408d62cf92b0ef01303ed69be9 ] Reading temperature from this sensor fails with 'Invalid argument'. Looking at old vendor dts [1], its hw_id should be 3 instead of 4. Change this hw_id accordingly. [1] https://github.com/msm8916-mainline/android_kernel_qcom_msm8916/blob/master/arch/arm/boot/dts/qcom/msm8939-common.dtsi#L511 Fixes: 332bc8ebab2c ("thermal: qcom: tsens-v0_1: Add support for MSM8939") Signed-off-by: Vincent Knecht Reviewed-by: Dmitry Baryshkov Reviewed-by: Bjorn Andersson Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20220811105014.7194-1-vincent.knecht@mailoo.org Signed-off-by: Daniel Lezcano Signed-off-by: Sasha Levin --- drivers/thermal/qcom/tsens-v0_1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index f136cb350238..327f37202c69 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -604,7 +604,7 @@ static const struct tsens_ops ops_8939 = { struct tsens_plat_data data_8939 = { .num_sensors = 10, .ops = &ops_8939, - .hw_ids = (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 }, + .hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 }, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields, From 6ddbd411a00a6267e98757ba71def5d3615e9d85 Mon Sep 17 00:00:00 2001 From: Shuai Xue Date: Sat, 24 Sep 2022 15:49:53 +0800 Subject: [PATCH 396/610] ACPI: APEI: do not add task_work to kernel thread to avoid memory leak [ Upstream commit 415fed694fe11395df56e05022d6e7cee1d39dd3 ] If an error is detected as a result of user-space process accessing a corrupt memory location, the CPU may take an abort. Then the platform firmware reports kernel via NMI like notifications, e.g. NOTIFY_SEA, NOTIFY_SOFTWARE_DELEGATED, etc. For NMI like notifications, commit 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors") keep track of whether memory_failure() work was queued, and make task_work pending to flush out the queue so that the work is processed before return to user-space. The code use init_mm to check whether the error occurs in user space: if (current->mm != &init_mm) The condition is always true, becase _nobody_ ever has "init_mm" as a real VM any more. In addition to abort, errors can also be signaled as asynchronous exceptions, such as interrupt and SError. In such case, the interrupted current process could be any kind of thread. When a kernel thread is interrupted, the work ghes_kick_task_work deferred to task_work will never be processed because entry_handler returns to call ret_to_kernel() instead of ret_to_user(). Consequently, the estatus_node alloced from ghes_estatus_pool in ghes_in_nmi_queue_one_entry() will not be freed. After around 200 allocations in our platform, the ghes_estatus_pool will run of memory and ghes_in_nmi_queue_one_entry() returns ENOMEM. As a result, the event failed to be processed. sdei: event 805 on CPU 113 failed with error: -2 Finally, a lot of unhandled events may cause platform firmware to exceed some threshold and reboot. The condition should generally just do if (current->mm) as described in active_mm.rst documentation. Then if an asynchronous error is detected when a kernel thread is running, (e.g. when detected by a background scrubber), do not add task_work to it as the original patch intends to do. Fixes: 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors") Signed-off-by: Shuai Xue Reviewed-by: Tony Luck Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/apei/ghes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 06b0184fa912..d490670f8d55 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) ghes_estatus_cache_add(generic, estatus); } - if (task_work_pending && current->mm != &init_mm) { + if (task_work_pending && current->mm) { estatus_node->task_work.func = ghes_kick_task_work; estatus_node->task_work_cpu = smp_processor_id(); ret = task_work_add(current, &estatus_node->task_work, From fb1dcc2a9e4b189b0c74031cb110c1e3b6de39b8 Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Mon, 5 Sep 2022 12:59:17 +0800 Subject: [PATCH 397/610] f2fs: fix race condition on setting FI_NO_EXTENT flag [ Upstream commit 07725adc55c0a414c10acb5c8c86cea34b95ddef ] The following scenarios exist. process A: process B: ->f2fs_drop_extent_tree ->f2fs_update_extent_cache_range ->f2fs_update_extent_tree_range ->write_lock ->set_inode_flag ->is_inode_flag_set ->__free_extent_tree // Shouldn't // have been // cleaned up // here ->write_lock In this case, the "FI_NO_EXTENT" flag is set between f2fs_update_extent_tree_range and is_inode_flag_set by other process. it leads to clearing the whole exten tree which should not have happened. And we fix it by move the setting it to the range of write_lock. Fixes:5f281fab9b9a3 ("f2fs: disable extent_cache for fcollapse/finsert inodes") Signed-off-by: Zhang Qilong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/extent_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 866e72b29bd5..761fd42c93f2 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode) if (!f2fs_may_extent_tree(inode)) return; - set_inode_flag(inode, FI_NO_EXTENT); - write_lock(&et->lock); + set_inode_flag(inode, FI_NO_EXTENT); __free_extent_tree(sbi, et); if (et->largest.len) { et->largest.len = 0; From 497d736784e58f6a73ded91271fdbc95a224202b Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 14 Sep 2022 21:28:46 +0800 Subject: [PATCH 398/610] f2fs: fix to account FS_CP_DATA_IO correctly [ Upstream commit d80afefb17e01aa0c46a8eebc01882e0ebd8b0f6 ] f2fs_inode_info.cp_task was introduced for FS_CP_DATA_IO accounting since commit b0af6d491a6b ("f2fs: add app/fs io stat"). However, cp_task usage coverage has been increased due to below commits: commit 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") commit 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush") So that, if data_flush mountoption is on, when data flush was triggered from background, the IO from data flush will be accounted as checkpoint IO type incorrectly. In order to fix this issue, this patch splits cp_task into two: a) cp_task: used for IO accounting b) wb_task: used to avoid deadlock Fixes: 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") Fixes: 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/checkpoint.c | 13 +++++++++---- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/segment.c | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 2917299d45c0..02840dadde5d 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1062,7 +1062,8 @@ void f2fs_remove_dirty_inode(struct inode *inode) spin_unlock(&sbi->inode_lock[type]); } -int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type) +int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type, + bool from_cp) { struct list_head *head; struct inode *inode; @@ -1097,11 +1098,15 @@ retry: if (inode) { unsigned long cur_ino = inode->i_ino; - F2FS_I(inode)->cp_task = current; + if (from_cp) + F2FS_I(inode)->cp_task = current; + F2FS_I(inode)->wb_task = current; filemap_fdatawrite(inode->i_mapping); - F2FS_I(inode)->cp_task = NULL; + F2FS_I(inode)->wb_task = NULL; + if (from_cp) + F2FS_I(inode)->cp_task = NULL; iput(inode); /* We need to give cpu to another writers. */ @@ -1230,7 +1235,7 @@ retry_flush_dents: /* write all the dirty dentry pages */ if (get_pages(sbi, F2FS_DIRTY_DENTS)) { f2fs_unlock_all(sbi); - err = f2fs_sync_dirty_inodes(sbi, DIR_INODE); + err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true); if (err) return err; cond_resched(); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 4cf522120cb1..cfa6e1322e46 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2862,7 +2862,7 @@ out: } unlock_page(page); if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) && - !F2FS_I(inode)->cp_task && allow_balance) + !F2FS_I(inode)->wb_task && allow_balance) f2fs_balance_fs(sbi, need_balance_fs); if (unlikely(f2fs_cp_error(sbi))) { @@ -3160,7 +3160,7 @@ static inline bool __should_serialize_io(struct inode *inode, struct writeback_control *wbc) { /* to avoid deadlock in path of data flush */ - if (F2FS_I(inode)->cp_task) + if (F2FS_I(inode)->wb_task) return false; if (!S_ISREG(inode->i_mode)) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4caac78e2034..a144471c5316 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -749,6 +749,7 @@ struct f2fs_inode_info { unsigned int clevel; /* maximum level of given file name */ struct task_struct *task; /* lookup and create consistency */ struct task_struct *cp_task; /* separate cp/wb IO stats*/ + struct task_struct *wb_task; /* indicate inode is in context of writeback */ nid_t i_xattr_nid; /* node id that contains xattrs */ loff_t last_disk_size; /* lastly written file size */ spinlock_t i_size_lock; /* protect last_disk_size */ @@ -3573,7 +3574,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi); int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi); void f2fs_update_dirty_page(struct inode *inode, struct page *page); void f2fs_remove_dirty_inode(struct inode *inode); -int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type); +int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type, + bool from_cp); void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type); u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi); int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index e98c90bd8ef6..af810b2d5d90 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -575,7 +575,7 @@ do_sync: mutex_lock(&sbi->flush_lock); blk_start_plug(&plug); - f2fs_sync_dirty_inodes(sbi, FILE_INODE); + f2fs_sync_dirty_inodes(sbi, FILE_INODE, false); blk_finish_plug(&plug); mutex_unlock(&sbi->flush_lock); From b6b87460f4eb1ace0c15e39f62d597bd5692b80d Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 20 Sep 2022 09:15:18 -0400 Subject: [PATCH 399/610] selftest: tpm2: Add Client.__del__() to close /dev/tpm* handle [ Upstream commit 2d869f0b458547386fbcd8cf3004b271b7347b7f ] The following output can bee seen when the test is executed: test_flush_context (tpm2_tests.SpaceTest) ... \ /usr/lib64/python3.6/unittest/case.py:605: ResourceWarning: \ unclosed file <_io.FileIO name='/dev/tpmrm0' mode='rb+' closefd=True> An instance of Client does not implicitly close /dev/tpm* handle, once it gets destroyed. Close the file handle in the class destructor Client.__del__(). Fixes: 6ea3dfe1e0732 ("selftests: add TPM 2.0 tests") Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Cc: Jarkko Sakkinen Signed-off-by: Stefan Berger Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Sasha Levin --- tools/testing/selftests/tpm2/tpm2.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/testing/selftests/tpm2/tpm2.py b/tools/testing/selftests/tpm2/tpm2.py index f34486cd7342..3e67fdb518ec 100644 --- a/tools/testing/selftests/tpm2/tpm2.py +++ b/tools/testing/selftests/tpm2/tpm2.py @@ -370,6 +370,10 @@ class Client: fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags) self.tpm_poll = select.poll() + def __del__(self): + if self.tpm: + self.tpm.close() + def close(self): self.tpm.close() From 27d3e646dd83bafd7094890462eebfce3ac31e4a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 15 Aug 2022 15:43:13 -0400 Subject: [PATCH 400/610] fs: dlm: fix race in lowcomms [ Upstream commit 30ea3257e8766027c4d8d609dcbd256ff9a76073 ] This patch fixes a race between queue_work() in _dlm_lowcomms_commit_msg() and srcu_read_unlock(). The queue_work() can take the final reference of a dlm_msg and so msg->idx can contain garbage which is signaled by the following warning: [ 676.237050] ------------[ cut here ]------------ [ 676.237052] WARNING: CPU: 0 PID: 1060 at include/linux/srcu.h:189 dlm_lowcomms_commit_msg+0x41/0x50 [ 676.238945] Modules linked in: dlm_locktorture torture rpcsec_gss_krb5 intel_rapl_msr intel_rapl_common iTCO_wdt iTCO_vendor_support qxl kvm_intel drm_ttm_helper vmw_vsock_virtio_transport kvm vmw_vsock_virtio_transport_common ttm irqbypass crc32_pclmul joydev crc32c_intel serio_raw drm_kms_helper vsock virtio_scsi virtio_console virtio_balloon snd_pcm drm syscopyarea sysfillrect sysimgblt snd_timer fb_sys_fops i2c_i801 lpc_ich snd i2c_smbus soundcore pcspkr [ 676.244227] CPU: 0 PID: 1060 Comm: lock_torture_wr Not tainted 5.19.0-rc3+ #1546 [ 676.245216] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-2.module+el8.7.0+15506+033991b0 04/01/2014 [ 676.246460] RIP: 0010:dlm_lowcomms_commit_msg+0x41/0x50 [ 676.247132] Code: fe ff ff ff 75 24 48 c7 c6 bd 0f 49 bb 48 c7 c7 38 7c 01 bd e8 00 e7 ca ff 89 de 48 c7 c7 60 78 01 bd e8 42 3d cd ff 5b 5d c3 <0f> 0b eb d8 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 [ 676.249253] RSP: 0018:ffffa401c18ffc68 EFLAGS: 00010282 [ 676.249855] RAX: 0000000000000001 RBX: 00000000ffff8b76 RCX: 0000000000000006 [ 676.250713] RDX: 0000000000000000 RSI: ffffffffbccf3a10 RDI: ffffffffbcc7b62e [ 676.251610] RBP: ffffa401c18ffc70 R08: 0000000000000001 R09: 0000000000000001 [ 676.252481] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000005 [ 676.253421] R13: ffff8b76786ec370 R14: ffff8b76786ec370 R15: ffff8b76786ec480 [ 676.254257] FS: 0000000000000000(0000) GS:ffff8b7777800000(0000) knlGS:0000000000000000 [ 676.255239] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 676.255897] CR2: 00005590205d88b8 CR3: 000000017656c003 CR4: 0000000000770ee0 [ 676.256734] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 676.257567] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 676.258397] PKRU: 55555554 [ 676.258729] Call Trace: [ 676.259063] [ 676.259354] dlm_midcomms_commit_mhandle+0xcc/0x110 [ 676.259964] queue_bast+0x8b/0xb0 [ 676.260423] grant_pending_locks+0x166/0x1b0 [ 676.261007] _unlock_lock+0x75/0x90 [ 676.261469] unlock_lock.isra.57+0x62/0xa0 [ 676.262009] dlm_unlock+0x21e/0x330 [ 676.262457] ? lock_torture_stats+0x80/0x80 [dlm_locktorture] [ 676.263183] torture_unlock+0x5a/0x90 [dlm_locktorture] [ 676.263815] ? preempt_count_sub+0xba/0x100 [ 676.264361] ? complete+0x1d/0x60 [ 676.264777] lock_torture_writer+0xb8/0x150 [dlm_locktorture] [ 676.265555] kthread+0x10a/0x130 [ 676.266007] ? kthread_complete_and_exit+0x20/0x20 [ 676.266616] ret_from_fork+0x22/0x30 [ 676.267097] [ 676.267381] irq event stamp: 9579855 [ 676.267824] hardirqs last enabled at (9579863): [] __up_console_sem+0x58/0x60 [ 676.268896] hardirqs last disabled at (9579872): [] __up_console_sem+0x3d/0x60 [ 676.270008] softirqs last enabled at (9579798): [] __do_softirq+0x349/0x4c7 [ 676.271438] softirqs last disabled at (9579897): [] irq_exit_rcu+0xb0/0xf0 [ 676.272796] ---[ end trace 0000000000000000 ]--- I reproduced this warning with dlm_locktorture test which is currently not upstream. However this patch fix the issue by make a additional refcount between dlm_lowcomms_new_msg() and dlm_lowcomms_commit_msg(). In case of the race the kref_put() in dlm_lowcomms_commit_msg() will be the final put. Signed-off-by: Alexander Aring Signed-off-by: David Teigland Signed-off-by: Sasha Levin --- fs/dlm/lowcomms.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index b11f695261f5..9d7078a1dc8b 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1319,6 +1319,8 @@ struct dlm_msg *dlm_lowcomms_new_msg(int nodeid, int len, gfp_t allocation, return NULL; } + /* for dlm_lowcomms_commit_msg() */ + kref_get(&msg->ref); /* we assume if successful commit must called */ msg->idx = idx; return msg; @@ -1353,6 +1355,8 @@ void dlm_lowcomms_commit_msg(struct dlm_msg *msg) { _dlm_lowcomms_commit_msg(msg); srcu_read_unlock(&connections_srcu, msg->idx); + /* because dlm_lowcomms_new_msg() */ + kref_put(&msg->ref, dlm_msg_release); } void dlm_lowcomms_put_msg(struct dlm_msg *msg) From 3e2d8b89f03152e07c95ec3075a7b3606380982e Mon Sep 17 00:00:00 2001 From: Zqiang Date: Mon, 8 Aug 2022 10:26:26 +0800 Subject: [PATCH 401/610] rcu: Avoid triggering strict-GP irq-work when RCU is idle [ Upstream commit 621189a1fe93cb2b34d62c5cdb9e258bca044813 ] Kernels built with PREEMPT_RCU=y and RCU_STRICT_GRACE_PERIOD=y trigger irq-work from rcu_read_unlock(), and the resulting irq-work handler invokes rcu_preempt_deferred_qs_handle(). The point of this triggering is to force grace periods to end quickly in order to give tools like KASAN a better chance of detecting RCU usage bugs such as leaking RCU-protected pointers out of an RCU read-side critical section. However, this irq-work triggering is unconditional. This works, but there is no point in doing this irq-work unless the current grace period is waiting on the running CPU or task, which is not the common case. After all, in the common case there are many rcu_read_unlock() calls per CPU per grace period. This commit therefore triggers the irq-work only when the current grace period is waiting on the running CPU or task. This change was tested as follows on a four-CPU system: echo rcu_preempt_deferred_qs_handler > /sys/kernel/debug/tracing/set_ftrace_filter echo 1 > /sys/kernel/debug/tracing/function_profile_enabled insmod rcutorture.ko sleep 20 rmmod rcutorture.ko echo 0 > /sys/kernel/debug/tracing/function_profile_enabled echo > /sys/kernel/debug/tracing/set_ftrace_filter This procedure produces results in this per-CPU set of files: /sys/kernel/debug/tracing/trace_stat/function* Sample output from one of these files is as follows: Function Hit Time Avg s^2 -------- --- ---- --- --- rcu_preempt_deferred_qs_handle 838746 182650.3 us 0.217 us 0.004 us The baseline sum of the "Hit" values (the number of calls to this function) was 3,319,015. With this commit, that sum was 1,140,359, for a 2.9x reduction. The worst-case variance across the CPUs was less than 25%, so this large effect size is statistically significant. The raw data is available in the Link: URL. Link: https://lore.kernel.org/all/20220808022626.12825-1-qiang1.zhang@intel.com/ Signed-off-by: Zqiang Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/tree_plugin.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index ef2dd131e955..f1a73a1f8472 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -638,7 +638,8 @@ static void rcu_read_unlock_special(struct task_struct *t) expboost = (t->rcu_blocked_node && READ_ONCE(t->rcu_blocked_node->exp_tasks)) || (rdp->grpmask & READ_ONCE(rnp->expmask)) || - IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) || + (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) && + ((rdp->grpmask & READ_ONCE(rnp->qsmask)) || t->rcu_blocked_node)) || (IS_ENABLED(CONFIG_RCU_BOOST) && irqs_were_disabled && t->rcu_blocked_node); // Need to defer quiescent state until everything is enabled. From cf38a05eb1d0bbdcdf40fbd5509b255333c394e1 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Wed, 22 Jun 2022 13:47:11 +0200 Subject: [PATCH 402/610] rcu: Back off upon fill_page_cache_func() allocation failure [ Upstream commit 093590c16b447f53e66771c8579ae66c96f6ef61 ] The fill_page_cache_func() function allocates couple of pages to store kvfree_rcu_bulk_data structures. This is a lightweight (GFP_NORETRY) allocation which can fail under memory pressure. The function will, however keep retrying even when the previous attempt has failed. This retrying is in theory correct, but in practice the allocation is invoked from workqueue context, which means that if the memory reclaim gets stuck, these retries can hog the worker for quite some time. Although the workqueues subsystem automatically adjusts concurrency, such adjustment is not guaranteed to happen until the worker context sleeps. And the fill_page_cache_func() function's retry loop is not guaranteed to sleep (see the should_reclaim_retry() function). And we have seen this function cause workqueue lockups: kernel: BUG: workqueue lockup - pool cpus=93 node=1 flags=0x1 nice=0 stuck for 32s! [...] kernel: pool 74: cpus=37 node=0 flags=0x1 nice=0 hung=32s workers=2 manager: 2146 kernel: pwq 498: cpus=249 node=1 flags=0x1 nice=0 active=4/256 refcnt=5 kernel: in-flight: 1917:fill_page_cache_func kernel: pending: dbs_work_handler, free_work, kfree_rcu_monitor Originally, we thought that the root cause of this lockup was several retries with direct reclaim, but this is not yet confirmed. Furthermore, we have seen similar lockups without any heavy memory pressure. This suggests that there are other factors contributing to these lockups. However, it is not really clear that endless retries are desireable. So let's make the fill_page_cache_func() function back off after allocation failure. Cc: Uladzislau Rezki (Sony) Cc: "Paul E. McKenney" Cc: Frederic Weisbecker Cc: Neeraj Upadhyay Cc: Josh Triplett Cc: Steven Rostedt Cc: Mathieu Desnoyers Cc: Lai Jiangshan Cc: Joel Fernandes Signed-off-by: Michal Hocko Reviewed-by: Uladzislau Rezki (Sony) Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/tree.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index a4a9d68b1fdc..63f7ce228cc3 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3419,15 +3419,16 @@ static void fill_page_cache_func(struct work_struct *work) bnode = (struct kvfree_rcu_bulk_data *) __get_free_page(GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); - if (bnode) { - raw_spin_lock_irqsave(&krcp->lock, flags); - pushed = put_cached_bnode(krcp, bnode); - raw_spin_unlock_irqrestore(&krcp->lock, flags); + if (!bnode) + break; - if (!pushed) { - free_page((unsigned long) bnode); - break; - } + raw_spin_lock_irqsave(&krcp->lock, flags); + pushed = put_cached_bnode(krcp, bnode); + raw_spin_unlock_irqrestore(&krcp->lock, flags); + + if (!pushed) { + free_page((unsigned long) bnode); + break; } } From 7ed95b080334e1c9ee13a727fae80cf3f8a2dcb4 Mon Sep 17 00:00:00 2001 From: Zqiang Date: Tue, 12 Jul 2022 16:26:05 +0800 Subject: [PATCH 403/610] rcu-tasks: Convert RCU_LOCKDEP_WARN() to WARN_ONCE() [ Upstream commit fcd53c8a4dfa38bafb89efdd0b0f718f3a03f884 ] Kernels built with CONFIG_PROVE_RCU=y and CONFIG_DEBUG_LOCK_ALLOC=y attempt to emit a warning when the synchronize_rcu_tasks_generic() function is called during early boot while the rcu_scheduler_active variable is RCU_SCHEDULER_INACTIVE. However the warnings is not actually be printed because the debug_lockdep_rcu_enabled() returns false, exactly because the rcu_scheduler_active variable is still equal to RCU_SCHEDULER_INACTIVE. This commit therefore replaces RCU_LOCKDEP_WARN() with WARN_ONCE() to force these warnings to actually be printed. Signed-off-by: Zqiang Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- kernel/rcu/tasks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 60c9eacac25b..ae8396032b5d 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -171,7 +171,7 @@ 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. */ - RCU_LOCKDEP_WARN(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE, + WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE, "synchronize_rcu_tasks called too soon"); /* Wait for the grace period. */ From 5374638222d0b07803ee0f6f5d11c9616bb46b26 Mon Sep 17 00:00:00 2001 From: Arvid Norlander Date: Wed, 24 Aug 2022 20:49:50 +0200 Subject: [PATCH 404/610] ACPI: video: Add Toshiba Satellite/Portege Z830 quirk [ Upstream commit 574160b8548deff8b80b174f03201e94ab8431e2 ] Toshiba Satellite Z830 needs the quirk video_disable_backlight_sysfs_if for proper backlight control after suspend/resume cycles. Toshiba Portege Z830 is simply the same laptop rebranded for certain markets (I looked through the manual to other language sections to confirm this) and thus also needs this quirk. Thanks to Hans de Goede for suggesting this fix. Link: https://www.spinics.net/lists/platform-driver-x86/msg34394.html Suggested-by: Hans de Goede Signed-off-by: Arvid Norlander Reviewed-by: Hans de Goede Tested-by: Arvid Norlander Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpi_video.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 390af28f6faf..2b18b51f6351 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), }, }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Satellite Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"), + }, + }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Portege Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"), + }, + }, /* * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set * but the IDs actually follow the Device ID Scheme. From 30eca146c89d216dda95868ce00a2d35cf73d5a4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 5 Sep 2022 14:34:12 +0200 Subject: [PATCH 405/610] ACPI: tables: FPDT: Don't call acpi_os_map_memory() on invalid phys address [ Upstream commit 211391bf04b3c74e250c566eeff9cf808156c693 ] On a Packard Bell Dot SC (Intel Atom N2600 model) there is a FPDT table which contains invalid physical addresses, with high bits set which fall outside the range of the CPU-s supported physical address range. Calling acpi_os_map_memory() on such an invalid phys address leads to the below WARN_ON in ioremap triggering resulting in an oops/stacktrace. Add code to verify the physical address before calling acpi_os_map_memory() to fix / avoid the oops. [ 1.226900] ioremap: invalid physical address 3001000000000000 [ 1.226949] ------------[ cut here ]------------ [ 1.226962] WARNING: CPU: 1 PID: 1 at arch/x86/mm/ioremap.c:200 __ioremap_caller.cold+0x43/0x5f [ 1.226996] Modules linked in: [ 1.227016] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc3+ #490 [ 1.227029] Hardware name: Packard Bell dot s/SJE01_CT, BIOS V1.10 07/23/2013 [ 1.227038] RIP: 0010:__ioremap_caller.cold+0x43/0x5f [ 1.227054] Code: 96 00 00 e9 f8 af 24 ff 89 c6 48 c7 c7 d8 0c 84 99 e8 6a 96 00 00 e9 76 af 24 ff 48 89 fe 48 c7 c7 a8 0c 84 99 e8 56 96 00 00 <0f> 0b e9 60 af 24 ff 48 8b 34 24 48 c7 c7 40 0d 84 99 e8 3f 96 00 [ 1.227067] RSP: 0000:ffffb18c40033d60 EFLAGS: 00010286 [ 1.227084] RAX: 0000000000000032 RBX: 3001000000000000 RCX: 0000000000000000 [ 1.227095] RDX: 0000000000000001 RSI: 00000000ffffdfff RDI: 00000000ffffffff [ 1.227105] RBP: 3001000000000000 R08: 0000000000000000 R09: ffffb18c40033c18 [ 1.227115] R10: 0000000000000003 R11: ffffffff99d62fe8 R12: 0000000000000008 [ 1.227124] R13: 0003001000000000 R14: 0000000000001000 R15: 3001000000000000 [ 1.227135] FS: 0000000000000000(0000) GS:ffff913a3c080000(0000) knlGS:0000000000000000 [ 1.227146] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1.227156] CR2: 0000000000000000 CR3: 0000000018c26000 CR4: 00000000000006e0 [ 1.227167] Call Trace: [ 1.227176] [ 1.227185] ? acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227215] ? kmem_cache_alloc_trace+0x187/0x370 [ 1.227254] acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227288] acpi_init_fpdt+0xa8/0x253 [ 1.227308] ? acpi_debugfs_init+0x1f/0x1f [ 1.227339] do_one_initcall+0x5a/0x300 [ 1.227406] ? rcu_read_lock_sched_held+0x3f/0x80 [ 1.227442] kernel_init_freeable+0x28b/0x2cc [ 1.227512] ? rest_init+0x170/0x170 [ 1.227538] kernel_init+0x16/0x140 [ 1.227552] ret_from_fork+0x1f/0x30 [ 1.227639] [ 1.227647] irq event stamp: 186819 [ 1.227656] hardirqs last enabled at (186825): [] __up_console_sem+0x5e/0x70 [ 1.227672] hardirqs last disabled at (186830): [] __up_console_sem+0x43/0x70 [ 1.227686] softirqs last enabled at (186576): [] __irq_exit_rcu+0xed/0x160 [ 1.227701] softirqs last disabled at (186569): [] __irq_exit_rcu+0xed/0x160 [ 1.227715] ---[ end trace 0000000000000000 ]--- Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpi_fpdt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c index 6922a44b3ce7..a2056c4c8cb7 100644 --- a/drivers/acpi/acpi_fpdt.c +++ b/drivers/acpi/acpi_fpdt.c @@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = { static struct kobject *fpdt_kobj; +#if defined CONFIG_X86 && defined CONFIG_PHYS_ADDR_T_64BIT +#include +static bool fpdt_address_valid(u64 address) +{ + /* + * On some systems the table contains invalid addresses + * with unsuppored high address bits set, check for this. + */ + return !(address >> boot_cpu_data.x86_phys_bits); +} +#else +static bool fpdt_address_valid(u64 address) +{ + return true; +} +#endif + static int fpdt_process_subtable(u64 address, u32 subtable_type) { struct fpdt_subtable_header *subtable_header; @@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type) u32 length, offset; int result; + if (!fpdt_address_valid(address)) { + pr_info(FW_BUG "invalid physical address: 0x%llx!\n", address); + return -EINVAL; + } + subtable_header = acpi_os_map_memory(address, sizeof(*subtable_header)); if (!subtable_header) return -ENOMEM; From c2790fede9209c1baf6a3aa91a3c025327485862 Mon Sep 17 00:00:00 2001 From: Doug Smythies Date: Tue, 6 Sep 2022 13:28:57 -0700 Subject: [PATCH 406/610] cpufreq: intel_pstate: Add Tigerlake support in no-HWP mode [ Upstream commit 71bb5c82aaaea007167f3ba68d3a669c74d7d55d ] Users may disable HWP in firmware, in which case intel_pstate wouldn't load unless the CPU model is explicitly supported. Add TIGERLAKE to the list of CPUs that can register intel_pstate while not advertising the HWP capability. Without this change, an TIGERLAKE in no-HWP mode could only use the acpi_cpufreq frequency scaling driver. See also commits: d8de7a44e11f: cpufreq: intel_pstate: Add Skylake servers support fbdc21e9b038: cpufreq: intel_pstate: Add Icelake servers support in no-HWP mode 706c5328851d: cpufreq: intel_pstate: Add Cometlake support in no-HWP mode Reported by: M. Cargi Ari Signed-off-by: Doug Smythies Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/cpufreq/intel_pstate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 8a2c6b58b652..c57229c108a7 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -2257,6 +2257,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { X86_MATCH(SKYLAKE_X, core_funcs), X86_MATCH(COMETLAKE, core_funcs), X86_MATCH(ICELAKE_X, core_funcs), + X86_MATCH(TIGERLAKE, core_funcs), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); From a1387ae83e974b6905ef0441c64fff34c9cd30a4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 7 Sep 2022 16:05:56 -0700 Subject: [PATCH 407/610] MIPS: BCM47XX: Cast memcmp() of function to (void *) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 0dedcf6e3301836eb70cfa649052e7ce4fcd13ba ] Clang is especially sensitive about argument type matching when using __overloaded functions (like memcmp(), etc). Help it see that function pointers are just "void *". Avoids this error: arch/mips/bcm47xx/prom.c:89:8: error: no matching function for call to 'memcmp' if (!memcmp(prom_init, prom_init + mem, 32)) ^~~~~~ include/linux/string.h:156:12: note: candidate function not viable: no known conversion from 'void (void)' to 'const void *' for 1st argument extern int memcmp(const void *,const void *,__kernel_size_t); Cc: Hauke Mehrtens Cc: "Rafał Miłecki" Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: llvm@lists.linux.dev Reported-by: kernel test robot Link: https://lore.kernel.org/lkml/202209080652.sz2d68e5-lkp@intel.com Signed-off-by: Kees Cook Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/bcm47xx/prom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index 0a63721d0fbf..5a33d6b48d77 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -86,7 +86,7 @@ static __init void prom_init_mem(void) pr_debug("Assume 128MB RAM\n"); break; } - if (!memcmp(prom_init, prom_init + mem, 32)) + if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32)) break; } lowmem = mem; @@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void) off = EXTVBASE + __pa(off); for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { - if (!memcmp(prom_init, (void *)(off + extmem), 16)) + if (!memcmp((void *)prom_init, (void *)(off + extmem), 16)) break; } extmem -= lowmem; From 139bbbd01114433b80fe59f5e1330615aadf9752 Mon Sep 17 00:00:00 2001 From: Chao Qin Date: Tue, 20 Sep 2022 14:08:26 +0800 Subject: [PATCH 408/610] powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue [ Upstream commit 2d93540014387d1c73b9ccc4d7895320df66d01b ] When value < time_unit, the parameter of ilog2() will be zero and the return value is -1. u64(-1) is too large for shift exponent and then will trigger shift-out-of-bounds: shift exponent 18446744073709551615 is too large for 32-bit type 'int' Call Trace: rapl_compute_time_window_core rapl_write_data_raw set_time_window store_constraint_time_window_us Signed-off-by: Chao Qin Acked-by: Zhang Rui Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/powercap/intel_rapl_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index c87d4687aa67..9dfc053878fd 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -938,6 +938,9 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value, y = value & 0x1f; value = (1 << y) * (4 + f) * rp->time_unit / 4; } else { + if (value < rp->time_unit) + return 0; + do_div(value, rp->time_unit); y = ilog2(value); f = div64_u64(4 * (value - (1 << y)), 1 << y); From 5614908434451aafbf9b24cb5247cf1d21269f76 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 20 Sep 2022 04:06:57 -0700 Subject: [PATCH 409/610] thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash [ Upstream commit 68b99e94a4a2db6ba9b31fe0485e057b9354a640 ] When CPU 0 is offline and intel_powerclamp is used to inject idle, it generates kernel BUG: BUG: using smp_processor_id() in preemptible [00000000] code: bash/15687 caller is debug_smp_processor_id+0x17/0x20 CPU: 4 PID: 15687 Comm: bash Not tainted 5.19.0-rc7+ #57 Call Trace: dump_stack_lvl+0x49/0x63 dump_stack+0x10/0x16 check_preemption_disabled+0xdd/0xe0 debug_smp_processor_id+0x17/0x20 powerclamp_set_cur_state+0x7f/0xf9 [intel_powerclamp] ... ... Here CPU 0 is the control CPU by default and changed to the current CPU, if CPU 0 offlined. This check has to be performed under cpus_read_lock(), hence the above warning. Use get_cpu() instead of smp_processor_id() to avoid this BUG. Suggested-by: Chen Yu Signed-off-by: Srinivas Pandruvada [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/intel/intel_powerclamp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index a5b58ea89cc6..9121ae4f5068 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -532,8 +532,10 @@ static int start_power_clamp(void) /* prefer BSP */ control_cpu = 0; - if (!cpu_online(control_cpu)) - control_cpu = smp_processor_id(); + if (!cpu_online(control_cpu)) { + control_cpu = get_cpu(); + put_cpu(); + } clamping = true; schedule_delayed_work(&poll_pkg_cstate_work, 0); From 6733222f2cc9dddcb83e0154ef50069dcb21fa18 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 7 Sep 2022 15:41:03 -0700 Subject: [PATCH 410/610] ARM: decompressor: Include .data.rel.ro.local [ Upstream commit 1b64daf413acd86c2c13f5443f6b4ef3690c8061 ] The .data.rel.ro.local section has the same semantics as .data.rel.ro here, so include it in the .rodata section of the decompressor. Additionally since the .printk_index section isn't usable outside of the core kernel, discard it in the decompressor. Avoids these warnings: arm-linux-gnueabi-ld: warning: orphan section `.data.rel.ro.local' from `arch/arm/boot/compressed/fdt_rw.o' being placed in section `.data.rel.ro.local' arm-linux-gnueabi-ld: warning: orphan section `.printk_index' from `arch/arm/boot/compressed/fdt_rw.o' being placed in section `.printk_index' Reported-by: kernel test robot Link: https://lore.kernel.org/linux-mm/202209080545.qMIVj7YM-lkp@intel.com Cc: Russell King Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- arch/arm/boot/compressed/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S index 1bcb68ac4b01..3fcb3e62dc56 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.S +++ b/arch/arm/boot/compressed/vmlinux.lds.S @@ -23,6 +23,7 @@ SECTIONS *(.ARM.extab*) *(.note.*) *(.rel.*) + *(.printk_index) /* * Discard any r/w data - this produces a link error if we have any, * which is required for PIC decompression. Local data generates @@ -57,6 +58,7 @@ SECTIONS *(.rodata) *(.rodata.*) *(.data.rel.ro) + *(.data.rel.ro.*) } .piggydata : { *(.piggydata) From 06c56c9d5da82459bfad12edf812b6e584346849 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 15 Sep 2022 13:23:14 -0500 Subject: [PATCH 411/610] ACPI: x86: Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable [ Upstream commit 018d6711c26e4bd26e20a819fcc7f8ab902608f3 ] Dell Inspiron 14 2-in-1 has two ACPI nodes under GPP1 both with _ADR of 0, both without _HID. It's ambiguous which the kernel should take, but it seems to take "DEV0". Unfortunately "DEV0" is missing the device property `StorageD3Enable` which is present on "NVME". To avoid this causing problems for suspend, add a quirk for this system to behave like `StorageD3Enable` property was found. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216440 Reported-and-tested-by: Luya Tshimbalanga Signed-off-by: Mario Limonciello Reviewed-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/x86/utils.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index b3fb428461c6..3a3f09b6cbfc 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -198,7 +198,24 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = { {} }; +static const struct dmi_system_id force_storage_d3_dmi[] = { + { + /* + * _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME + * but .NVME is needed to get StorageD3Enable node + * https://bugzilla.kernel.org/show_bug.cgi?id=216440 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"), + } + }, + {} +}; + bool force_storage_d3(void) { - return x86_match_cpu(storage_d3_cpu_ids); + const struct dmi_system_id *dmi_id = dmi_first_match(force_storage_d3_dmi); + + return dmi_id || x86_match_cpu(storage_d3_cpu_ids); } From 066b1302f2a9f07d268da73ef5557b886d4dee25 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 19 Sep 2022 19:45:14 -0700 Subject: [PATCH 412/610] x86/entry: Work around Clang __bdos() bug [ Upstream commit 3e1730842f142add55dc658929221521a9ea62b6 ] Clang produces a false positive when building with CONFIG_FORTIFY_SOURCE=y and CONFIG_UBSAN_BOUNDS=y when operating on an array with a dynamic offset. Work around this by using a direct assignment of an empty instance. Avoids this warning: ../include/linux/fortify-string.h:309:4: warning: call to __write_overflow_field declared with 'warn ing' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wat tribute-warning] __write_overflow_field(p_size_field, size); ^ which was isolated to the memset() call in xen_load_idt(). Note that this looks very much like another bug that was worked around: https://github.com/ClangBuiltLinux/linux/issues/1592 Cc: Juergen Gross Cc: Boris Ostrovsky Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86@kernel.org Cc: "H. Peter Anvin" Cc: xen-devel@lists.xenproject.org Reviewed-by: Boris Ostrovsky Link: https://lore.kernel.org/lkml/41527d69-e8ab-3f86-ff37-6b298c01d5bc@oracle.com Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- arch/x86/xen/enlighten_pv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 133ef31639df..561aad13412f 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -759,6 +759,7 @@ static void xen_load_idt(const struct desc_ptr *desc) { static DEFINE_SPINLOCK(lock); static struct trap_info traps[257]; + static const struct trap_info zero = { }; unsigned out; trace_xen_cpu_load_idt(desc); @@ -768,7 +769,7 @@ static void xen_load_idt(const struct desc_ptr *desc) memcpy(this_cpu_ptr(&idt_desc), desc, sizeof(idt_desc)); out = xen_convert_trap_info(desc, traps, false); - memset(&traps[out], 0, sizeof(traps[0])); + traps[out] = zero; xen_mc_flush(); if (HYPERVISOR_set_trap_table(traps)) From 118dc74b2bc08dec271e0eb0c77fa637333e0fff Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 13 Sep 2022 14:01:50 -0400 Subject: [PATCH 413/610] NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data [ Upstream commit 06981d560606ac48d61e5f4fff6738b925c93173 ] This was discussed with Chuck as part of this patch set. Returning nfserr_resource was decided to not be the best error message here, and he suggested changing to nfserr_serverfault instead. Signed-off-by: Anna Schumaker Link: https://lore.kernel.org/linux-nfs/20220907195259.926736-1-anna@kernel.org/T/#t Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index bda8478eb1ae..e0409f6cdfd5 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3988,7 +3988,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, if (resp->xdr->buf->page_len && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) { WARN_ON_ONCE(1); - return nfserr_resource; + return nfserr_serverfault; } xdr_commit_encode(xdr); From 83b94969751a691347606dbe6b1865efcfa5a643 Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Mon, 26 Sep 2022 10:59:16 -0700 Subject: [PATCH 414/610] NFSD: fix use-after-free on source server when doing inter-server copy [ Upstream commit 019805fea91599b22dfa62ffb29c022f35abeb06 ] Use-after-free occurred when the laundromat tried to free expired cpntf_state entry on the s2s_cp_stateids list after inter-server copy completed. The sc_cp_list that the expired copy state was inserted on was already freed. When COPY completes, the Linux client normally sends LOCKU(lock_state x), FREE_STATEID(lock_state x) and CLOSE(open_state y) to the source server. The nfs4_put_stid call from nfsd4_free_stateid cleans up the copy state from the s2s_cp_stateids list before freeing the lock state's stid. However, sometimes the CLOSE was sent before the FREE_STATEID request. When this happens, the nfsd4_close_open_stateid call from nfsd4_close frees all lock states on its st_locks list without cleaning up the copy state on the sc_cp_list list. When the time the FREE_STATEID arrives the server returns BAD_STATEID since the lock state was freed. This causes the use-after-free error to occur when the laundromat tries to free the expired cpntf_state. This patch adds a call to nfs4_free_cpntf_statelist in nfsd4_close_open_stateid to clean up the copy state before calling free_ol_stateid_reaplist to free the lock state's stid on the reaplist. Signed-off-by: Dai Ngo Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin --- fs/nfsd/nfs4state.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f9e2fa9cfbec..7b763f146b62 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -961,6 +961,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp) static void nfs4_free_deleg(struct nfs4_stid *stid) { + WARN_ON(!list_empty(&stid->sc_cp_list)); kmem_cache_free(deleg_slab, stid); atomic_long_dec(&num_delegations); } @@ -1374,6 +1375,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid) release_all_access(stp); if (stp->st_stateowner) nfs4_put_stateowner(stp->st_stateowner); + WARN_ON(!list_empty(&stid->sc_cp_list)); kmem_cache_free(stateid_slab, stid); } @@ -6389,6 +6391,7 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) struct nfs4_client *clp = s->st_stid.sc_client; bool unhashed; LIST_HEAD(reaplist); + struct nfs4_ol_stateid *stp; spin_lock(&clp->cl_lock); unhashed = unhash_open_stateid(s, &reaplist); @@ -6397,6 +6400,8 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) if (unhashed) put_ol_stateid_locked(s, &reaplist); spin_unlock(&clp->cl_lock); + list_for_each_entry(stp, &reaplist, st_locks) + nfs4_free_cpntf_statelist(clp->net, &stp->st_stid); free_ol_stateid_reaplist(&reaplist); } else { spin_unlock(&clp->cl_lock); From 75995ce1c926ee87bf93d58977c766b4e7744715 Mon Sep 17 00:00:00 2001 From: Wright Feng Date: Fri, 22 Jul 2022 13:56:28 +0200 Subject: [PATCH 415/610] wifi: brcmfmac: fix invalid address access when enabling SCAN log level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit aa666b68e73fc06d83c070d96180b9010cf5a960 ] The variable i is changed when setting random MAC address and causes invalid address access when printing the value of pi->reqs[i]->reqid. We replace reqs index with ri to fix the issue. [ 136.726473] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000 [ 136.737365] Mem abort info: [ 136.740172] ESR = 0x96000004 [ 136.743359] Exception class = DABT (current EL), IL = 32 bits [ 136.749294] SET = 0, FnV = 0 [ 136.752481] EA = 0, S1PTW = 0 [ 136.755635] Data abort info: [ 136.758514] ISV = 0, ISS = 0x00000004 [ 136.762487] CM = 0, WnR = 0 [ 136.765522] user pgtable: 4k pages, 48-bit VAs, pgdp = 000000005c4e2577 [ 136.772265] [0000000000000000] pgd=0000000000000000 [ 136.777160] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 136.782732] Modules linked in: brcmfmac(O) brcmutil(O) cfg80211(O) compat(O) [ 136.789788] Process wificond (pid: 3175, stack limit = 0x00000000053048fb) [ 136.796664] CPU: 3 PID: 3175 Comm: wificond Tainted: G O 4.19.42-00001-g531a5f5 #1 [ 136.805532] Hardware name: Freescale i.MX8MQ EVK (DT) [ 136.810584] pstate: 60400005 (nZCv daif +PAN -UAO) [ 136.815429] pc : brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.821811] lr : brcmf_pno_config_sched_scans+0x67c/0xa80 [brcmfmac] [ 136.828162] sp : ffff00000e9a3880 [ 136.831475] x29: ffff00000e9a3890 x28: ffff800020543400 [ 136.836786] x27: ffff8000b1008880 x26: ffff0000012bf6a0 [ 136.842098] x25: ffff80002054345c x24: ffff800088d22400 [ 136.847409] x23: ffff0000012bf638 x22: ffff0000012bf6d8 [ 136.852721] x21: ffff8000aced8fc0 x20: ffff8000ac164400 [ 136.858032] x19: ffff00000e9a3946 x18: 0000000000000000 [ 136.863343] x17: 0000000000000000 x16: 0000000000000000 [ 136.868655] x15: ffff0000093f3b37 x14: 0000000000000050 [ 136.873966] x13: 0000000000003135 x12: 0000000000000000 [ 136.879277] x11: 0000000000000000 x10: ffff000009a61888 [ 136.884589] x9 : 000000000000000f x8 : 0000000000000008 [ 136.889900] x7 : 303a32303d726464 x6 : ffff00000a1f957d [ 136.895211] x5 : 0000000000000000 x4 : ffff00000e9a3942 [ 136.900523] x3 : 0000000000000000 x2 : ffff0000012cead8 [ 136.905834] x1 : ffff0000012bf6d8 x0 : 0000000000000000 [ 136.911146] Call trace: [ 136.913623] brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.919658] brcmf_pno_start_sched_scan+0xa4/0x118 [brcmfmac] [ 136.925430] brcmf_cfg80211_sched_scan_start+0x80/0xe0 [brcmfmac] [ 136.931636] nl80211_start_sched_scan+0x140/0x308 [cfg80211] [ 136.937298] genl_rcv_msg+0x358/0x3f4 [ 136.940960] netlink_rcv_skb+0xb4/0x118 [ 136.944795] genl_rcv+0x34/0x48 [ 136.947935] netlink_unicast+0x264/0x300 [ 136.951856] netlink_sendmsg+0x2e4/0x33c [ 136.955781] __sys_sendto+0x120/0x19c Signed-off-by: Wright Feng Signed-off-by: Chi-hsien Lin Signed-off-by: Ahmad Fatoum Signed-off-by: Alvin Šipraga Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220722115632.620681-4-alvin@pqrs.dk Signed-off-by: Sasha Levin --- .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c index fabfbb0b40b0..d0a7465be586 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c @@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) struct brcmf_pno_macaddr_le pfn_mac; u8 *mac_addr = NULL; u8 *mac_mask = NULL; - int err, i; + int err, i, ri; - for (i = 0; i < pi->n_reqs; i++) - if (pi->reqs[i]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { - mac_addr = pi->reqs[i]->mac_addr; - mac_mask = pi->reqs[i]->mac_addr_mask; + for (ri = 0; ri < pi->n_reqs; ri++) + if (pi->reqs[ri]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + mac_addr = pi->reqs[ri]->mac_addr; + mac_mask = pi->reqs[ri]->mac_addr_mask; break; } @@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) pfn_mac.mac[0] |= 0x02; brcmf_dbg(SCAN, "enabling random mac: reqid=%llu mac=%pM\n", - pi->reqs[i]->reqid, pfn_mac.mac); + pi->reqs[ri]->reqid, pfn_mac.mac); err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, sizeof(pfn_mac)); if (err) From 2e52d858de3a77f447c1636c2a9c3e64ab4eff91 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Mon, 15 Aug 2022 17:22:05 +0100 Subject: [PATCH 416/610] bpftool: Clear errno after libcap's checks [ Upstream commit cea558855c39b7f1f02ff50dcf701ca6596bc964 ] When bpftool is linked against libcap, the library runs a "constructor" function to compute the number of capabilities of the running kernel [0], at the beginning of the execution of the program. As part of this, it performs multiple calls to prctl(). Some of these may fail, and set errno to a non-zero value: # strace -e prctl ./bpftool version prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1 prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument) prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1 prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument) prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument) prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument) ** fprintf added at the top of main(): we have errno == 1 ./bpftool v7.0.0 using libbpf v1.0 features: libbfd, libbpf_strict, skeletons +++ exited with 0 +++ This has been addressed in libcap 2.63 [1], but until this version is available everywhere, we can fix it on bpftool side. Let's clean errno at the beginning of the main() function, to make sure that these checks do not interfere with the batch mode, where we error out if errno is set after a bpftool command. [0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/tree/libcap/cap_alloc.c?h=libcap-2.65#n20 [1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=f25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0 Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20220815162205.45043-1-quentin@isovalent.com Signed-off-by: Sasha Levin --- tools/bpf/bpftool/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index d27ec4f852bb..b70c023f3a57 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -404,6 +404,16 @@ int main(int argc, char **argv) setlinebuf(stdout); +#ifdef USE_LIBCAP + /* Libcap < 2.63 hooks before main() to compute the number of + * capabilities of the running kernel, and doing so it calls prctl() + * which may fail and set errno to non-zero. + * Let's reset errno to make sure this does not interfere with the + * batch mode. + */ + errno = 0; +#endif + last_do_help = do_help; pretty_output = false; json_output = false; From 624f03a027f2b18647cc4f1a7a81920a1e4e0201 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Wed, 27 Jul 2022 16:15:57 -0700 Subject: [PATCH 417/610] ice: set tx_tstamps when creating new Tx rings via ethtool [ Upstream commit b3b173745c8cab1e24d6821488b60abed3acb24d ] When the user changes the number of queues via ethtool, the driver allocates new rings. This allocation did not initialize tx_tstamps. This results in the tx_tstamps field being zero (due to kcalloc allocation), and would result in a NULL pointer dereference when attempting a transmit timestamp on the new ring. Signed-off-by: Jacob Keller Tested-by: Gurucharan (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ice/ice_ethtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 9b9c2b885486..f10d9c377c74 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -2788,6 +2788,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) tx_rings[i].count = new_tx_cnt; tx_rings[i].desc = NULL; tx_rings[i].tx_buf = NULL; + tx_rings[i].tx_tstamps = &pf->ptp.port.tx; err = ice_setup_tx_ring(&tx_rings[i]); if (err) { while (i--) From d449d00a8dceffe378a3079946b1556290208906 Mon Sep 17 00:00:00 2001 From: Ravi Gunasekaran Date: Wed, 17 Aug 2022 15:14:06 +0530 Subject: [PATCH 418/610] net: ethernet: ti: davinci_mdio: Add workaround for errata i2329 [ Upstream commit d04807b80691c6041ca8e3dcf1870d1bf1082c22 ] On the CPSW and ICSS peripherals, there is a possibility that the MDIO interface returns corrupt data on MDIO reads or writes incorrect data on MDIO writes. There is also a possibility for the MDIO interface to become unavailable until the next peripheral reset. The workaround is to configure the MDIO in manual mode and disable the MDIO state machine and emulate the MDIO protocol by reading and writing appropriate fields in MDIO_MANUAL_IF_REG register of the MDIO controller to manipulate the MDIO clock and data pins. More details about the errata i2329 and the workaround is available in: https://www.ti.com/lit/er/sprz487a/sprz487a.pdf Add implementation to disable MDIO state machine, configure MDIO in manual mode and achieve MDIO read and writes via MDIO Bitbanging Signed-off-by: Ravi Gunasekaran Reported-by: kernel test robot Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/ti/davinci_mdio.c | 242 +++++++++++++++++++++++-- 1 file changed, 231 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index a4efd5e35158..995633e1ec5e 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include /* * This timeout definition is a worst-case ultra defensive measure against @@ -41,6 +43,7 @@ struct davinci_mdio_of_param { int autosuspend_delay_ms; + bool manual_mode; }; struct davinci_mdio_regs { @@ -49,6 +52,15 @@ struct davinci_mdio_regs { #define CONTROL_IDLE BIT(31) #define CONTROL_ENABLE BIT(30) #define CONTROL_MAX_DIV (0xffff) +#define CONTROL_CLKDIV GENMASK(15, 0) + +#define MDIO_MAN_MDCLK_O BIT(2) +#define MDIO_MAN_OE BIT(1) +#define MDIO_MAN_PIN BIT(0) +#define MDIO_MANUALMODE BIT(31) + +#define MDIO_PIN 0 + u32 alive; u32 link; @@ -59,7 +71,9 @@ struct davinci_mdio_regs { u32 userintmasked; u32 userintmaskset; u32 userintmaskclr; - u32 __reserved_1[20]; + u32 manualif; + u32 poll; + u32 __reserved_1[18]; struct { u32 access; @@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = { struct davinci_mdio_data { struct mdio_platform_data pdata; + struct mdiobb_ctrl bb_ctrl; struct davinci_mdio_regs __iomem *regs; struct clk *clk; struct device *dev; @@ -90,6 +105,7 @@ struct davinci_mdio_data { */ bool skip_scan; u32 clk_div; + bool manual_mode; }; static void davinci_mdio_init_clk(struct davinci_mdio_data *data) @@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data) writel(data->clk_div | CONTROL_ENABLE, &data->regs->control); } -static int davinci_mdio_reset(struct mii_bus *bus) +static void davinci_mdio_disable(struct davinci_mdio_data *data) +{ + u32 reg; + + /* Disable MDIO state machine */ + reg = readl(&data->regs->control); + + reg &= ~CONTROL_CLKDIV; + reg |= data->clk_div; + + reg &= ~CONTROL_ENABLE; + writel(reg, &data->regs->control); +} + +static void davinci_mdio_enable_manual_mode(struct davinci_mdio_data *data) +{ + u32 reg; + /* set manual mode */ + reg = readl(&data->regs->poll); + reg |= MDIO_MANUALMODE; + writel(reg, &data->regs->poll); +} + +static void davinci_set_mdc(struct mdiobb_ctrl *ctrl, int level) +{ + struct davinci_mdio_data *data; + u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg = readl(&data->regs->manualif); + + if (level) + reg |= MDIO_MAN_MDCLK_O; + else + reg &= ~MDIO_MAN_MDCLK_O; + + writel(reg, &data->regs->manualif); +} + +static void davinci_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output) +{ + struct davinci_mdio_data *data; + u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg = readl(&data->regs->manualif); + + if (output) + reg |= MDIO_MAN_OE; + else + reg &= ~MDIO_MAN_OE; + + writel(reg, &data->regs->manualif); +} + +static void davinci_set_mdio_data(struct mdiobb_ctrl *ctrl, int value) +{ + struct davinci_mdio_data *data; + u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg = readl(&data->regs->manualif); + + if (value) + reg |= MDIO_MAN_PIN; + else + reg &= ~MDIO_MAN_PIN; + + writel(reg, &data->regs->manualif); +} + +static int davinci_get_mdio_data(struct mdiobb_ctrl *ctrl) +{ + struct davinci_mdio_data *data; + unsigned long reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg = readl(&data->regs->manualif); + return test_bit(MDIO_PIN, ®); +} + +static int davinci_mdiobb_read(struct mii_bus *bus, int phy, int reg) +{ + int ret; + + ret = pm_runtime_resume_and_get(bus->parent); + if (ret < 0) + return ret; + + ret = mdiobb_read(bus, phy, reg); + + pm_runtime_mark_last_busy(bus->parent); + pm_runtime_put_autosuspend(bus->parent); + + return ret; +} + +static int davinci_mdiobb_write(struct mii_bus *bus, int phy, int reg, + u16 val) +{ + int ret; + + ret = pm_runtime_resume_and_get(bus->parent); + if (ret < 0) + return ret; + + ret = mdiobb_write(bus, phy, reg, val); + + pm_runtime_mark_last_busy(bus->parent); + pm_runtime_put_autosuspend(bus->parent); + + return ret; +} + +static int davinci_mdio_common_reset(struct davinci_mdio_data *data) { - struct davinci_mdio_data *data = bus->priv; u32 phy_mask, ver; int ret; @@ -140,6 +269,11 @@ static int davinci_mdio_reset(struct mii_bus *bus) return ret; } + if (data->manual_mode) { + davinci_mdio_disable(data); + davinci_mdio_enable_manual_mode(data); + } + /* wait for scan logic to settle */ msleep(PHY_MAX_ADDR * data->access_time); @@ -173,6 +307,23 @@ done: return 0; } +static int davinci_mdio_reset(struct mii_bus *bus) +{ + struct davinci_mdio_data *data = bus->priv; + + return davinci_mdio_common_reset(data); +} + +static int davinci_mdiobb_reset(struct mii_bus *bus) +{ + struct mdiobb_ctrl *ctrl = bus->priv; + struct davinci_mdio_data *data; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + + return davinci_mdio_common_reset(data); +} + /* wait until hardware is ready for another user access */ static inline int wait_for_user_access(struct davinci_mdio_data *data) { @@ -324,6 +475,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data, return 0; } +struct k3_mdio_soc_data { + bool manual_mode; +}; + +static const struct k3_mdio_soc_data am65_mdio_soc_data = { + .manual_mode = true, +}; + +static const struct soc_device_attribute k3_mdio_socinfo[] = { + { .family = "AM62X", .revision = "SR1.0", .data = &am65_mdio_soc_data }, + { .family = "AM64X", .revision = "SR1.0", .data = &am65_mdio_soc_data }, + { .family = "AM64X", .revision = "SR2.0", .data = &am65_mdio_soc_data }, + { .family = "AM65X", .revision = "SR1.0", .data = &am65_mdio_soc_data }, + { .family = "AM65X", .revision = "SR2.0", .data = &am65_mdio_soc_data }, + { .family = "J7200", .revision = "SR1.0", .data = &am65_mdio_soc_data }, + { .family = "J7200", .revision = "SR2.0", .data = &am65_mdio_soc_data }, + { .family = "J721E", .revision = "SR1.0", .data = &am65_mdio_soc_data }, + { .family = "J721E", .revision = "SR2.0", .data = &am65_mdio_soc_data }, + { .family = "J721S2", .revision = "SR1.0", .data = &am65_mdio_soc_data}, + { /* sentinel */ }, +}; + #if IS_ENABLED(CONFIG_OF) static const struct davinci_mdio_of_param of_cpsw_mdio_data = { .autosuspend_delay_ms = 100, @@ -337,6 +510,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = { MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable); #endif +static const struct mdiobb_ops davinci_mdiobb_ops = { + .owner = THIS_MODULE, + .set_mdc = davinci_set_mdc, + .set_mdio_dir = davinci_set_mdio_dir, + .set_mdio_data = davinci_set_mdio_data, + .get_mdio_data = davinci_get_mdio_data, +}; + static int davinci_mdio_probe(struct platform_device *pdev) { struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -351,7 +532,26 @@ static int davinci_mdio_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - data->bus = devm_mdiobus_alloc(dev); + data->manual_mode = false; + data->bb_ctrl.ops = &davinci_mdiobb_ops; + + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { + const struct soc_device_attribute *soc_match_data; + + soc_match_data = soc_device_match(k3_mdio_socinfo); + if (soc_match_data && soc_match_data->data) { + const struct k3_mdio_soc_data *socdata = + soc_match_data->data; + + data->manual_mode = socdata->manual_mode; + } + } + + if (data->manual_mode) + data->bus = alloc_mdio_bitbang(&data->bb_ctrl); + else + data->bus = devm_mdiobus_alloc(dev); + if (!data->bus) { dev_err(dev, "failed to alloc mii bus\n"); return -ENOMEM; @@ -377,11 +577,20 @@ static int davinci_mdio_probe(struct platform_device *pdev) } data->bus->name = dev_name(dev); - data->bus->read = davinci_mdio_read; - data->bus->write = davinci_mdio_write; - data->bus->reset = davinci_mdio_reset; + + if (data->manual_mode) { + data->bus->read = davinci_mdiobb_read; + data->bus->write = davinci_mdiobb_write; + data->bus->reset = davinci_mdiobb_reset; + + dev_info(dev, "Configuring MDIO in manual mode\n"); + } else { + data->bus->read = davinci_mdio_read; + data->bus->write = davinci_mdio_write; + data->bus->reset = davinci_mdio_reset; + data->bus->priv = data; + } data->bus->parent = dev; - data->bus->priv = data; data->clk = devm_clk_get(dev, "fck"); if (IS_ERR(data->clk)) { @@ -439,9 +648,13 @@ static int davinci_mdio_remove(struct platform_device *pdev) { struct davinci_mdio_data *data = platform_get_drvdata(pdev); - if (data->bus) + if (data->bus) { mdiobus_unregister(data->bus); + if (data->manual_mode) + free_mdio_bitbang(data->bus); + } + pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -458,7 +671,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev) ctrl = readl(&data->regs->control); ctrl &= ~CONTROL_ENABLE; writel(ctrl, &data->regs->control); - wait_for_idle(data); + + if (!data->manual_mode) + wait_for_idle(data); return 0; } @@ -467,7 +682,12 @@ static int davinci_mdio_runtime_resume(struct device *dev) { struct davinci_mdio_data *data = dev_get_drvdata(dev); - davinci_mdio_enable(data); + if (data->manual_mode) { + davinci_mdio_disable(data); + davinci_mdio_enable_manual_mode(data); + } else { + davinci_mdio_enable(data); + } return 0; } #endif From ffd7a1dcae9a12b46716ca4bebfc4d866405d06d Mon Sep 17 00:00:00 2001 From: Mike Pattrick Date: Wed, 17 Aug 2022 11:06:34 -0400 Subject: [PATCH 419/610] openvswitch: Fix double reporting of drops in dropwatch [ Upstream commit 1100248a5c5ccd57059eb8d02ec077e839a23826 ] Frames sent to userspace can be reported as dropped in ovs_dp_process_packet, however, if they are dropped in the netlink code then netlink_attachskb will report the same frame as dropped. This patch checks for error codes which indicate that the frame has already been freed. Signed-off-by: Mike Pattrick Link: https://bugzilla.redhat.com/show_bug.cgi?id=2109946 Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/openvswitch/datapath.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 5e2c83cb7b12..f4b088d418fb 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -251,10 +251,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.mru = OVS_CB(skb)->mru; error = ovs_dp_upcall(dp, skb, key, &upcall, 0); - if (unlikely(error)) - kfree_skb(skb); - else + switch (error) { + case 0: + case -EAGAIN: + case -ERESTARTSYS: + case -EINTR: consume_skb(skb); + break; + default: + kfree_skb(skb); + break; + } stats_counter = &stats->n_missed; goto out; } From 7b03296b4f7a4429b372cd869c6ca0ff7e6b3d15 Mon Sep 17 00:00:00 2001 From: Mike Pattrick Date: Wed, 17 Aug 2022 11:06:35 -0400 Subject: [PATCH 420/610] openvswitch: Fix overreporting of drops in dropwatch [ Upstream commit c21ab2afa2c64896a7f0e3cbc6845ec63dcfad2e ] Currently queue_userspace_packet will call kfree_skb for all frames, whether or not an error occurred. This can result in a single dropped frame being reported as multiple drops in dropwatch. This functions caller may also call kfree_skb in case of an error. This patch will consume the skbs instead and allow caller's to use kfree_skb. Signed-off-by: Mike Pattrick Link: https://bugzilla.redhat.com/show_bug.cgi?id=2109957 Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/openvswitch/datapath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index f4b088d418fb..46ef1525b2e5 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -557,8 +557,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, out: if (err) skb_tx_error(skb); - kfree_skb(user_skb); - kfree_skb(nskb); + consume_skb(user_skb); + consume_skb(nskb); + return err; } From 1663629bc3ffcb2e441457f86dafbc63a1a61c3f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 22 Aug 2022 21:15:28 +0000 Subject: [PATCH 421/610] tcp: annotate data-race around tcp_md5sig_pool_populated [ Upstream commit aacd467c0a576e5e44d2de4205855dc0fe43f6fb ] tcp_md5sig_pool_populated can be read while another thread changes its value. The race has no consequence because allocations are protected with tcp_md5sig_mutex. This patch adds READ_ONCE() and WRITE_ONCE() to document the race and silence KCSAN. Reported-by: Abhishek Shah Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/tcp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b604c7664350..5b4e170b6a34 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -4331,12 +4331,16 @@ static void __tcp_alloc_md5sig_pool(void) * to memory. See smp_rmb() in tcp_get_md5sig_pool() */ smp_wmb(); - tcp_md5sig_pool_populated = true; + /* Paired with READ_ONCE() from tcp_alloc_md5sig_pool() + * and tcp_get_md5sig_pool(). + */ + WRITE_ONCE(tcp_md5sig_pool_populated, true); } bool tcp_alloc_md5sig_pool(void) { - if (unlikely(!tcp_md5sig_pool_populated)) { + /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ + if (unlikely(!READ_ONCE(tcp_md5sig_pool_populated))) { mutex_lock(&tcp_md5sig_mutex); if (!tcp_md5sig_pool_populated) { @@ -4347,7 +4351,8 @@ bool tcp_alloc_md5sig_pool(void) mutex_unlock(&tcp_md5sig_mutex); } - return tcp_md5sig_pool_populated; + /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ + return READ_ONCE(tcp_md5sig_pool_populated); } EXPORT_SYMBOL(tcp_alloc_md5sig_pool); @@ -4363,7 +4368,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) { local_bh_disable(); - if (tcp_md5sig_pool_populated) { + /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ + if (READ_ONCE(tcp_md5sig_pool_populated)) { /* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */ smp_rmb(); return this_cpu_ptr(&tcp_md5sig_pool); From 839f563c5dc53fe4d92a2542cc9f7e23e94f2241 Mon Sep 17 00:00:00 2001 From: Jane Chu Date: Fri, 26 Aug 2022 17:38:51 -0600 Subject: [PATCH 422/610] x86/mce: Retrieve poison range from hardware [ Upstream commit f9781bb18ed828e7b83b7bac4a4ad7cd497ee7d7 ] When memory poison consumption machine checks fire, MCE notifier handlers like nfit_handle_mce() record the impacted physical address range which is reported by the hardware in the MCi_MISC MSR. The error information includes data about blast radius, i.e. how many cachelines did the hardware determine are impacted. A recent change 7917f9cdb503 ("acpi/nfit: rely on mce->misc to determine poison granularity") updated nfit_handle_mce() to stop hard coding the blast radius value of 1 cacheline, and instead rely on the blast radius reported in 'struct mce' which can be up to 4K (64 cachelines). It turns out that apei_mce_report_mem_error() had a similar problem in that it hard coded a blast radius of 4K rather than reading the blast radius from the error information. Fix apei_mce_report_mem_error() to convey the proper poison granularity. Signed-off-by: Jane Chu Signed-off-by: Borislav Petkov Reviewed-by: Dan Williams Reviewed-by: Ingo Molnar Link: https://lore.kernel.org/r/7ed50fd8-521e-cade-77b1-738b8bfb8502@oracle.com Link: https://lore.kernel.org/r/20220826233851.1319100-1-jane.chu@oracle.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/mce/apei.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mce/apei.c b/arch/x86/kernel/cpu/mce/apei.c index 0e3ae64d3b76..b08b90cdc2a3 100644 --- a/arch/x86/kernel/cpu/mce/apei.c +++ b/arch/x86/kernel/cpu/mce/apei.c @@ -29,15 +29,26 @@ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err) { struct mce m; + int lsb; if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) return; + /* + * Even if the ->validation_bits are set for address mask, + * to be extra safe, check and reject an error radius '0', + * and fall back to the default page size. + */ + if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK) + lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT); + else + lsb = PAGE_SHIFT; + mce_setup(&m); m.bank = -1; /* Fake a memory read error with unknown channel */ m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f; - m.misc = (MCI_MISC_ADDR_PHYS << 6) | PAGE_SHIFT; + m.misc = (MCI_MISC_ADDR_PHYS << 6) | lsb; if (severity >= GHES_SEV_RECOVERABLE) m.status |= MCI_STATUS_UC; From b1b4144508adfc585e43856b31baaf9008a3beb4 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 16 Aug 2022 23:46:13 +0900 Subject: [PATCH 423/610] wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b383e8abed41cc6ff1a3b34de75df9397fa4878c ] syzbot is reporting uninit value at ath9k_htc_rx_msg() [1], for ioctl(USB_RAW_IOCTL_EP_WRITE) can call ath9k_hif_usb_rx_stream() with pkt_len = 0 but ath9k_hif_usb_rx_stream() uses __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC) based on an assumption that pkt_len is valid. As a result, ath9k_hif_usb_rx_stream() allocates skb with uninitialized memory and ath9k_htc_rx_msg() is reading from uninitialized memory. Since bytes accessed by ath9k_htc_rx_msg() is not known until ath9k_htc_rx_msg() is called, it would be difficult to check minimal valid pkt_len at "if (pkt_len > 2 * MAX_RX_BUF_SIZE) {" line in ath9k_hif_usb_rx_stream(). We have two choices. One is to workaround by adding __GFP_ZERO so that ath9k_htc_rx_msg() sees 0 if pkt_len is invalid. The other is to let ath9k_htc_rx_msg() validate pkt_len before accessing. This patch chose the latter. Note that I'm not sure threshold condition is correct, for I can't find details on possible packet length used by this protocol. Link: https://syzkaller.appspot.com/bug?extid=2ca247c2d60c7023de7f [1] Reported-by: syzbot Signed-off-by: Tetsuo Handa Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/7acfa1be-4b5c-b2ce-de43-95b0593fb3e5@I-love.SAKURA.ne.jp Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/htc_hst.c | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 994ec48b2f66..ca05b07a45e6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -364,33 +364,27 @@ ret: } static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle, - struct sk_buff *skb) + struct sk_buff *skb, u32 len) { uint32_t *pattern = (uint32_t *)skb->data; - switch (*pattern) { - case 0x33221199: - { + if (*pattern == 0x33221199 && len >= sizeof(struct htc_panic_bad_vaddr)) { struct htc_panic_bad_vaddr *htc_panic; htc_panic = (struct htc_panic_bad_vaddr *) skb->data; dev_err(htc_handle->dev, "ath: firmware panic! " "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n", htc_panic->exccause, htc_panic->pc, htc_panic->badvaddr); - break; - } - case 0x33221299: - { + return; + } + if (*pattern == 0x33221299) { struct htc_panic_bad_epid *htc_panic; htc_panic = (struct htc_panic_bad_epid *) skb->data; dev_err(htc_handle->dev, "ath: firmware panic! " "bad epid: 0x%08x\n", htc_panic->epid); - break; - } - default: - dev_err(htc_handle->dev, "ath: unknown panic pattern!\n"); - break; + return; } + dev_err(htc_handle->dev, "ath: unknown panic pattern!\n"); } /* @@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle, if (!htc_handle || !skb) return; + /* A valid message requires len >= 8. + * + * sizeof(struct htc_frame_hdr) == 8 + * sizeof(struct htc_ready_msg) == 8 + * sizeof(struct htc_panic_bad_vaddr) == 16 + * sizeof(struct htc_panic_bad_epid) == 8 + */ + if (unlikely(len < sizeof(struct htc_frame_hdr))) + goto invalid; htc_hdr = (struct htc_frame_hdr *) skb->data; epid = htc_hdr->endpoint_id; if (epid == 0x99) { - ath9k_htc_fw_panic_report(htc_handle, skb); + ath9k_htc_fw_panic_report(htc_handle, skb, len); kfree_skb(skb); return; } if (epid < 0 || epid >= ENDPOINT_MAX) { +invalid: if (pipe_id != USB_REG_IN_PIPE) dev_kfree_skb_any(skb); else @@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle, /* Handle trailer */ if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) { - if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) + if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) { /* Move past the Watchdog pattern */ htc_hdr = (struct htc_frame_hdr *)(skb->data + 4); + len -= 4; + } } /* Get the message ID */ + if (unlikely(len < sizeof(struct htc_frame_hdr) + sizeof(__be16))) + goto invalid; msg_id = (__be16 *) ((void *) htc_hdr + sizeof(struct htc_frame_hdr)); /* Now process HTC messages */ switch (be16_to_cpu(*msg_id)) { case HTC_MSG_READY_ID: + if (unlikely(len < sizeof(struct htc_ready_msg))) + goto invalid; htc_process_target_rdy(htc_handle, htc_hdr); break; case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID: + if (unlikely(len < sizeof(struct htc_frame_hdr) + + sizeof(struct htc_conn_svc_rspmsg))) + goto invalid; htc_process_conn_rsp(htc_handle, htc_hdr); break; default: From 716c526d666d0d07fc63d98497e534860f654809 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 30 Aug 2022 18:32:48 +0300 Subject: [PATCH 424/610] thunderbolt: Add back Intel Falcon Ridge end-to-end flow control workaround [ Upstream commit 54669e2f17cb5a4c41ade89427f074dc22cecb17 ] As we are now enabling full end-to-end flow control to the Thunderbolt networking driver, in order for it to work properly on second generation Thunderbolt hardware (Falcon Ridge), we need to add back the workaround that was removed with commit 53f13319d131 ("thunderbolt: Get rid of E2E workaround"). However, this time we only apply it for Falcon Ridge controllers as a form of an additional quirk. For non-Falcon Ridge this does nothing. While there fix a typo 'reqister' -> 'register' in the comment. Signed-off-by: Mika Westerberg Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/thunderbolt/nhi.c | 49 +++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index c73da0532be4..aa6cf7f2f438 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -25,7 +25,11 @@ #define RING_TYPE(ring) ((ring)->is_tx ? "TX ring" : "RX ring") #define RING_FIRST_USABLE_HOPID 1 - +/* + * Used with QUIRK_E2E to specify an unused HopID the Rx credits are + * transferred. + */ +#define RING_E2E_RESERVED_HOPID RING_FIRST_USABLE_HOPID /* * Minimal number of vectors when we use MSI-X. Two for control channel * Rx/Tx and the rest four are for cross domain DMA paths. @@ -35,7 +39,9 @@ #define NHI_MAILBOX_TIMEOUT 500 /* ms */ +/* Host interface quirks */ #define QUIRK_AUTO_CLEAR_INT BIT(0) +#define QUIRK_E2E BIT(1) static int ring_interrupt_index(struct tb_ring *ring) { @@ -455,8 +461,18 @@ static void ring_release_msix(struct tb_ring *ring) static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring) { + unsigned int start_hop = RING_FIRST_USABLE_HOPID; int ret = 0; + if (nhi->quirks & QUIRK_E2E) { + start_hop = RING_FIRST_USABLE_HOPID + 1; + if (ring->flags & RING_FLAG_E2E && !ring->is_tx) { + dev_dbg(&nhi->pdev->dev, "quirking E2E TX HopID %u -> %u\n", + ring->e2e_tx_hop, RING_E2E_RESERVED_HOPID); + ring->e2e_tx_hop = RING_E2E_RESERVED_HOPID; + } + } + spin_lock_irq(&nhi->lock); if (ring->hop < 0) { @@ -466,7 +482,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring) * Automatically allocate HopID from the non-reserved * range 1 .. hop_count - 1. */ - for (i = RING_FIRST_USABLE_HOPID; i < nhi->hop_count; i++) { + for (i = start_hop; i < nhi->hop_count; i++) { if (ring->is_tx) { if (!nhi->tx_rings[i]) { ring->hop = i; @@ -481,6 +497,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring) } } + if (ring->hop > 0 && ring->hop < start_hop) { + dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop); + ret = -EINVAL; + goto err_unlock; + } if (ring->hop < 0 || ring->hop >= nhi->hop_count) { dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop); ret = -EINVAL; @@ -1094,12 +1115,26 @@ static void nhi_shutdown(struct tb_nhi *nhi) static void nhi_check_quirks(struct tb_nhi *nhi) { - /* - * Intel hardware supports auto clear of the interrupt status - * reqister right after interrupt is being issued. - */ - if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) + if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) { + /* + * Intel hardware supports auto clear of the interrupt + * status register right after interrupt is being + * issued. + */ nhi->quirks |= QUIRK_AUTO_CLEAR_INT; + + switch (nhi->pdev->device) { + case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI: + case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI: + /* + * Falcon Ridge controller needs the end-to-end + * flow control workaround to avoid losing Rx + * packets when RING_FLAG_E2E is set. + */ + nhi->quirks |= QUIRK_E2E; + break; + } + } } static int nhi_init_msi(struct tb_nhi *nhi) From 03155680191ef0f004b1d6a5714c5b8cd271ab61 Mon Sep 17 00:00:00 2001 From: Khalid Masum Date: Thu, 1 Sep 2022 13:12:10 +0600 Subject: [PATCH 425/610] xfrm: Update ipcomp_scratches with NULL when freed [ Upstream commit 8a04d2fc700f717104bfb95b0f6694e448a4537f ] Currently if ipcomp_alloc_scratches() fails to allocate memory ipcomp_scratches holds obsolete address. So when we try to free the percpu scratches using ipcomp_free_scratches() it tries to vfree non existent vm area. Described below: static void * __percpu *ipcomp_alloc_scratches(void) { ... scratches = alloc_percpu(void *); if (!scratches) return NULL; ipcomp_scratches does not know about this allocation failure. Therefore holding the old obsolete address. ... } So when we free, static void ipcomp_free_scratches(void) { ... scratches = ipcomp_scratches; Assigning obsolete address from ipcomp_scratches if (!scratches) return; for_each_possible_cpu(i) vfree(*per_cpu_ptr(scratches, i)); Trying to free non existent page, causing warning: trying to vfree existent vm area. ... } Fix this breakage by updating ipcomp_scrtches with NULL when scratches is freed Suggested-by: Herbert Xu Reported-by: syzbot+5ec9bb042ddfe9644773@syzkaller.appspotmail.com Tested-by: syzbot+5ec9bb042ddfe9644773@syzkaller.appspotmail.com Signed-off-by: Khalid Masum Acked-by: Herbert Xu Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/xfrm/xfrm_ipcomp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c index cb40ff0ff28d..92ad336a83ab 100644 --- a/net/xfrm/xfrm_ipcomp.c +++ b/net/xfrm/xfrm_ipcomp.c @@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void) vfree(*per_cpu_ptr(scratches, i)); free_percpu(scratches); + ipcomp_scratches = NULL; } static void * __percpu *ipcomp_alloc_scratches(void) From 37f15edba22ddc1ee20f5d5dc82e68c08dd44208 Mon Sep 17 00:00:00 2001 From: Michal Jaron Date: Thu, 18 Aug 2022 13:32:33 +0200 Subject: [PATCH 426/610] iavf: Fix race between iavf_close and iavf_reset_task [ Upstream commit 11c12adcbc1598d91e73ab6ddfa41d25a01478ed ] During stress tests with adding VF to namespace and changing vf's trust there was a race between iavf_reset_task and iavf_close. Sometimes when IAVF_FLAG_AQ_DISABLE_QUEUES from iavf_close was sent to PF after reset and before IAVF_AQ_GET_CONFIG was sent then PF returns error IAVF_NOT_SUPPORTED to disable queues request and following requests. There is need to get_config before other aq_required will be send but iavf_close clears all flags, if get_config was not sent before iavf_close, then it will not be send at all. In case when IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS was sent before IAVF_FLAG_AQ_DISABLE_QUEUES then there was rtnl_lock deadlock between iavf_close and iavf_adminq_task until iavf_close timeouts and disable queues was sent after iavf_close ends. There was also a problem with sending delete/add filters. Sometimes when filters was not yet added to PF and in iavf_close all filters was set to remove there might be a try to remove nonexistent filters on PF. Add aq_required_tmp to save aq_required flags and send them after disable_queues will be handled. Clear flags given to iavf_down different than IAVF_FLAG_AQ_GET_CONFIG as this flag is necessary to sent other aq_required. Remove some flags that we don't want to send as we are in iavf_close and we want to disable interface. Remove filters which was not yet sent and send del filters flags only when there are filters to remove. Signed-off-by: Michal Jaron Signed-off-by: Mateusz Palczewski Tested-by: Konrad Jankowski Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/iavf/iavf_main.c | 199 +++++++++++++++----- 1 file changed, 152 insertions(+), 47 deletions(-) diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 00b2ef01f4ea..629ebdfa48b8 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1011,6 +1011,116 @@ static void iavf_up_complete(struct iavf_adapter *adapter) mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0); } +/** + * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF + * yet and mark other to be removed. + * @adapter: board private structure + **/ +static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter) +{ + struct iavf_vlan_filter *vlf, *vlftmp; + struct iavf_mac_filter *f, *ftmp; + + spin_lock_bh(&adapter->mac_vlan_list_lock); + /* clear the sync flag on all filters */ + __dev_uc_unsync(adapter->netdev, NULL); + __dev_mc_unsync(adapter->netdev, NULL); + + /* remove all MAC filters */ + list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, + list) { + if (f->add) { + list_del(&f->list); + kfree(f); + } else { + f->remove = true; + } + } + + /* remove all VLAN filters */ + list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list, + list) { + if (vlf->add) { + list_del(&vlf->list); + kfree(vlf); + } else { + vlf->remove = true; + } + } + spin_unlock_bh(&adapter->mac_vlan_list_lock); +} + +/** + * iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and + * mark other to be removed. + * @adapter: board private structure + **/ +static void iavf_clear_cloud_filters(struct iavf_adapter *adapter) +{ + struct iavf_cloud_filter *cf, *cftmp; + + /* remove all cloud filters */ + spin_lock_bh(&adapter->cloud_filter_list_lock); + list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list, + list) { + if (cf->add) { + list_del(&cf->list); + kfree(cf); + adapter->num_cloud_filters--; + } else { + cf->del = true; + } + } + spin_unlock_bh(&adapter->cloud_filter_list_lock); +} + +/** + * iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark + * other to be removed. + * @adapter: board private structure + **/ +static void iavf_clear_fdir_filters(struct iavf_adapter *adapter) +{ + struct iavf_fdir_fltr *fdir, *fdirtmp; + + /* remove all Flow Director filters */ + spin_lock_bh(&adapter->fdir_fltr_lock); + list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head, + list) { + if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) { + list_del(&fdir->list); + kfree(fdir); + adapter->fdir_active_fltr--; + } else { + fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST; + } + } + spin_unlock_bh(&adapter->fdir_fltr_lock); +} + +/** + * iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark + * other to be removed. + * @adapter: board private structure + **/ +static void iavf_clear_adv_rss_conf(struct iavf_adapter *adapter) +{ + struct iavf_adv_rss *rss, *rsstmp; + + /* remove all advance RSS configuration */ + spin_lock_bh(&adapter->adv_rss_lock); + list_for_each_entry_safe(rss, rsstmp, &adapter->adv_rss_list_head, + list) { + if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) { + list_del(&rss->list); + kfree(rss); + } else { + rss->state = IAVF_ADV_RSS_DEL_REQUEST; + } + } + spin_unlock_bh(&adapter->adv_rss_lock); +} + /** * iavf_down - Shutdown the connection processing * @adapter: board private structure @@ -1020,11 +1130,6 @@ static void iavf_up_complete(struct iavf_adapter *adapter) void iavf_down(struct iavf_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct iavf_vlan_filter *vlf; - struct iavf_cloud_filter *cf; - struct iavf_fdir_fltr *fdir; - struct iavf_mac_filter *f; - struct iavf_adv_rss *rss; if (adapter->state <= __IAVF_DOWN_PENDING) return; @@ -1035,43 +1140,10 @@ void iavf_down(struct iavf_adapter *adapter) iavf_napi_disable_all(adapter); iavf_irq_disable(adapter); - spin_lock_bh(&adapter->mac_vlan_list_lock); - - /* clear the sync flag on all filters */ - __dev_uc_unsync(adapter->netdev, NULL); - __dev_mc_unsync(adapter->netdev, NULL); - - /* remove all MAC filters */ - list_for_each_entry(f, &adapter->mac_filter_list, list) { - f->remove = true; - } - - /* remove all VLAN filters */ - list_for_each_entry(vlf, &adapter->vlan_filter_list, list) { - vlf->remove = true; - } - - spin_unlock_bh(&adapter->mac_vlan_list_lock); - - /* remove all cloud filters */ - spin_lock_bh(&adapter->cloud_filter_list_lock); - list_for_each_entry(cf, &adapter->cloud_filter_list, list) { - cf->del = true; - } - spin_unlock_bh(&adapter->cloud_filter_list_lock); - - /* remove all Flow Director filters */ - spin_lock_bh(&adapter->fdir_fltr_lock); - list_for_each_entry(fdir, &adapter->fdir_list_head, list) { - fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST; - } - spin_unlock_bh(&adapter->fdir_fltr_lock); - - /* remove all advance RSS configuration */ - spin_lock_bh(&adapter->adv_rss_lock); - list_for_each_entry(rss, &adapter->adv_rss_list_head, list) - rss->state = IAVF_ADV_RSS_DEL_REQUEST; - spin_unlock_bh(&adapter->adv_rss_lock); + iavf_clear_mac_vlan_filters(adapter); + iavf_clear_cloud_filters(adapter); + iavf_clear_fdir_filters(adapter); + iavf_clear_adv_rss_conf(adapter); if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) { /* cancel any current operation */ @@ -1080,11 +1152,16 @@ void iavf_down(struct iavf_adapter *adapter) * here for this to complete. The watchdog is still running * and it will take care of this. */ - adapter->aq_required = IAVF_FLAG_AQ_DEL_MAC_FILTER; - adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER; - adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER; - adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; - adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG; + if (!list_empty(&adapter->mac_filter_list)) + adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER; + if (!list_empty(&adapter->vlan_filter_list)) + adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER; + if (!list_empty(&adapter->cloud_filter_list)) + adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER; + if (!list_empty(&adapter->fdir_list_head)) + adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER; + if (!list_empty(&adapter->adv_rss_list_head)) + adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG; adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES; } @@ -3483,6 +3560,7 @@ err_unlock: static int iavf_close(struct net_device *netdev) { struct iavf_adapter *adapter = netdev_priv(netdev); + u64 aq_to_restore; int status; mutex_lock(&adapter->crit_lock); @@ -3495,6 +3573,29 @@ static int iavf_close(struct net_device *netdev) set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); if (CLIENT_ENABLED(adapter)) adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_CLOSE; + /* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before + * IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl + * deadlock with adminq_task() until iavf_close timeouts. We must send + * IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make + * disable queues possible for vf. Give only necessary flags to + * iavf_down and save other to set them right before iavf_close() + * returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and + * iavf will be in DOWN state. + */ + aq_to_restore = adapter->aq_required; + adapter->aq_required &= IAVF_FLAG_AQ_GET_CONFIG; + + /* Remove flags which we do not want to send after close or we want to + * send before disable queues. + */ + aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG | + IAVF_FLAG_AQ_ENABLE_QUEUES | + IAVF_FLAG_AQ_CONFIGURE_QUEUES | + IAVF_FLAG_AQ_ADD_VLAN_FILTER | + IAVF_FLAG_AQ_ADD_MAC_FILTER | + IAVF_FLAG_AQ_ADD_CLOUD_FILTER | + IAVF_FLAG_AQ_ADD_FDIR_FILTER | + IAVF_FLAG_AQ_ADD_ADV_RSS_CFG); iavf_down(adapter); iavf_change_state(adapter, __IAVF_DOWN_PENDING); @@ -3518,6 +3619,10 @@ static int iavf_close(struct net_device *netdev) msecs_to_jiffies(500)); if (!status) netdev_warn(netdev, "Device resources not yet released\n"); + + mutex_lock(&adapter->crit_lock); + adapter->aq_required |= aq_to_restore; + mutex_unlock(&adapter->crit_lock); return 0; } From 232d59eca07f6ea27307022a33d226aff373bd02 Mon Sep 17 00:00:00 2001 From: Alexander Coffin Date: Mon, 8 Aug 2022 10:49:26 -0700 Subject: [PATCH 427/610] wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit() [ Upstream commit 3f42faf6db431e04bf942d2ebe3ae88975723478 ] > ret = brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb); may be schedule, and then complete before the line > ndev->stats.tx_bytes += skb->len; [ 46.912801] ================================================================== [ 46.920552] BUG: KASAN: use-after-free in brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.928673] Read of size 4 at addr ffffff803f5882e8 by task systemd-resolve/328 [ 46.935991] [ 46.937514] CPU: 1 PID: 328 Comm: systemd-resolve Tainted: G O 5.4.199-[REDACTED] #1 [ 46.947255] Hardware name: [REDACTED] [ 46.954568] Call trace: [ 46.957037] dump_backtrace+0x0/0x2b8 [ 46.960719] show_stack+0x24/0x30 [ 46.964052] dump_stack+0x128/0x194 [ 46.967557] print_address_description.isra.0+0x64/0x380 [ 46.972877] __kasan_report+0x1d4/0x240 [ 46.976723] kasan_report+0xc/0x18 [ 46.980138] __asan_report_load4_noabort+0x18/0x20 [ 46.985027] brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.990613] dev_hard_start_xmit+0x1bc/0xda0 [ 46.994894] sch_direct_xmit+0x198/0xd08 [ 46.998827] __qdisc_run+0x37c/0x1dc0 [ 47.002500] __dev_queue_xmit+0x1528/0x21f8 [ 47.006692] dev_queue_xmit+0x24/0x30 [ 47.010366] neigh_resolve_output+0x37c/0x678 [ 47.014734] ip_finish_output2+0x598/0x2458 [ 47.018927] __ip_finish_output+0x300/0x730 [ 47.023118] ip_output+0x2e0/0x430 [ 47.026530] ip_local_out+0x90/0x140 [ 47.030117] igmpv3_sendpack+0x14c/0x228 [ 47.034049] igmpv3_send_cr+0x384/0x6b8 [ 47.037895] igmp_ifc_timer_expire+0x4c/0x118 [ 47.042262] call_timer_fn+0x1cc/0xbe8 [ 47.046021] __run_timers+0x4d8/0xb28 [ 47.049693] run_timer_softirq+0x24/0x40 [ 47.053626] __do_softirq+0x2c0/0x117c [ 47.057387] irq_exit+0x2dc/0x388 [ 47.060715] __handle_domain_irq+0xb4/0x158 [ 47.064908] gic_handle_irq+0x58/0xb0 [ 47.068581] el0_irq_naked+0x50/0x5c [ 47.072162] [ 47.073665] Allocated by task 328: [ 47.077083] save_stack+0x24/0xb0 [ 47.080410] __kasan_kmalloc.isra.0+0xc0/0xe0 [ 47.084776] kasan_slab_alloc+0x14/0x20 [ 47.088622] kmem_cache_alloc+0x15c/0x468 [ 47.092643] __alloc_skb+0xa4/0x498 [ 47.096142] igmpv3_newpack+0x158/0xd78 [ 47.099987] add_grhead+0x210/0x288 [ 47.103485] add_grec+0x6b0/0xb70 [ 47.106811] igmpv3_send_cr+0x2e0/0x6b8 [ 47.110657] igmp_ifc_timer_expire+0x4c/0x118 [ 47.115027] call_timer_fn+0x1cc/0xbe8 [ 47.118785] __run_timers+0x4d8/0xb28 [ 47.122457] run_timer_softirq+0x24/0x40 [ 47.126389] __do_softirq+0x2c0/0x117c [ 47.130142] [ 47.131643] Freed by task 180: [ 47.134712] save_stack+0x24/0xb0 [ 47.138041] __kasan_slab_free+0x108/0x180 [ 47.142146] kasan_slab_free+0x10/0x18 [ 47.145904] slab_free_freelist_hook+0xa4/0x1b0 [ 47.150444] kmem_cache_free+0x8c/0x528 [ 47.154292] kfree_skbmem+0x94/0x108 [ 47.157880] consume_skb+0x10c/0x5a8 [ 47.161466] __dev_kfree_skb_any+0x88/0xa0 [ 47.165598] brcmu_pkt_buf_free_skb+0x44/0x68 [brcmutil] [ 47.171023] brcmf_txfinalize+0xec/0x190 [brcmfmac] [ 47.176016] brcmf_proto_bcdc_txcomplete+0x1c0/0x210 [brcmfmac] [ 47.182056] brcmf_sdio_sendfromq+0x8dc/0x1e80 [brcmfmac] [ 47.187568] brcmf_sdio_dpc+0xb48/0x2108 [brcmfmac] [ 47.192529] brcmf_sdio_dataworker+0xc8/0x238 [brcmfmac] [ 47.197859] process_one_work+0x7fc/0x1a80 [ 47.201965] worker_thread+0x31c/0xc40 [ 47.205726] kthread+0x2d8/0x370 [ 47.208967] ret_from_fork+0x10/0x18 [ 47.212546] [ 47.214051] The buggy address belongs to the object at ffffff803f588280 [ 47.214051] which belongs to the cache skbuff_head_cache of size 208 [ 47.227086] The buggy address is located 104 bytes inside of [ 47.227086] 208-byte region [ffffff803f588280, ffffff803f588350) [ 47.238814] The buggy address belongs to the page: [ 47.243618] page:ffffffff00dd6200 refcount:1 mapcount:0 mapping:ffffff804b6bf800 index:0xffffff803f589900 compound_mapcount: 0 [ 47.255007] flags: 0x10200(slab|head) [ 47.258689] raw: 0000000000010200 ffffffff00dfa980 0000000200000002 ffffff804b6bf800 [ 47.266439] raw: ffffff803f589900 0000000080190018 00000001ffffffff 0000000000000000 [ 47.274180] page dumped because: kasan: bad access detected [ 47.279752] [ 47.281251] Memory state around the buggy address: [ 47.286051] ffffff803f588180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.293277] ffffff803f588200: fb fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 47.300502] >ffffff803f588280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.307723] ^ [ 47.314343] ffffff803f588300: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc [ 47.321569] ffffff803f588380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb [ 47.328789] ================================================================== Signed-off-by: Alexander Coffin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220808174925.3922558-1-alex.coffin@matician.com Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index db5f8535fdb5..e5bae6224521 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -295,6 +295,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, struct brcmf_pub *drvr = ifp->drvr; struct ethhdr *eh; int head_delta; + unsigned int tx_bytes = skb->len; brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); @@ -369,7 +370,7 @@ done: ndev->stats.tx_dropped++; } else { ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += tx_bytes; } /* Return ok: we always eat the packet */ From d58c8781c0d718682c458d2b5772cf46c5b7a582 Mon Sep 17 00:00:00 2001 From: Kiran K Date: Wed, 7 Sep 2022 12:49:45 +0530 Subject: [PATCH 428/610] Bluetooth: btintel: Mark Intel controller to support LE_STATES quirk [ Upstream commit dd0a1794f4334ddbf9b7c5e7d642aaffff38c69b ] HarrrisonPeak, CyclonePeak, SnowFieldPeak and SandyPeak controllers are marked to support HCI_QUIRK_LE_STATES. Signed-off-by: Kiran K Signed-off-by: Chethan T N Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/btintel.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index d122cc973917..de3d851d85e7 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -2274,15 +2274,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) INTEL_ROM_LEGACY_NO_WBS_SUPPORT)) set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); + if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22) + set_bit(HCI_QUIRK_VALID_LE_STATES, + &hdev->quirks); err = btintel_legacy_rom_setup(hdev, &ver); break; case 0x0b: /* SfP */ - case 0x0c: /* WsP */ case 0x11: /* JfP */ case 0x12: /* ThP */ case 0x13: /* HrP */ case 0x14: /* CcP */ + set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); + fallthrough; + case 0x0c: /* WsP */ /* Apply the device specific HCI quirks * * All Legacy bootloader devices support WBS @@ -2290,11 +2295,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); - /* Valid LE States quirk for JfP/ThP familiy */ - if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12) - set_bit(HCI_QUIRK_VALID_LE_STATES, - &hdev->quirks); - /* Setup MSFT Extension support */ btintel_set_msft_opcode(hdev, ver.hw_variant); @@ -2361,9 +2361,8 @@ static int btintel_setup_combined(struct hci_dev *hdev) */ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); - /* Valid LE States quirk for JfP/ThP familiy */ - if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12) - set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); + /* Set Valid LE States quirk */ + set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); /* Setup MSFT Extension support */ btintel_set_msft_opcode(hdev, ver.hw_variant); From e33da263e9658bfe870ea7836fbbd72f246d7dbd Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 9 Sep 2022 14:59:53 +0200 Subject: [PATCH 429/610] regulator: core: Prevent integer underflow [ Upstream commit 8d8e16592022c9650df8aedfe6552ed478d7135b ] By using a ratio of delay to poll_enabled_time that is not integer time_remaining underflows and does not exit the loop as expected. As delay could be derived from DT and poll_enabled_time is defined in the driver this can easily happen. Use a signed iterator to make sure that the loop exits once the remaining time is negative. Signed-off-by: Patrick Rudolph Link: https://lore.kernel.org/r/20220909125954.577669-1-patrick.rudolph@9elements.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 43613db7af75..aa4d78b02483 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2636,7 +2636,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) * expired, return -ETIMEDOUT. */ if (rdev->desc->poll_enabled_time) { - unsigned int time_remaining = delay; + int time_remaining = delay; while (time_remaining > 0) { _regulator_enable_delay(rdev->desc->poll_enabled_time); From af46b2b9b096c9d51a5bf76383c02dfd3a37f13e Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Tue, 30 Aug 2022 06:57:44 +0800 Subject: [PATCH 430/610] wifi: mt76: mt7921: reset msta->airtime_ac while clearing up hw value [ Upstream commit 1bf66dc31032ff5292f4d5b76436653f269fcfbd ] We should reset mstat->airtime_ac along with clear up the entries in the hardware WLAN table for the Rx and Rx accumulative airtime. Otherwsie, the value msta->airtime_ac - [tx, rx]_last may be a negative and that is not the actual airtime the device took in the last run. Reported-by: YN Chen Signed-off-by: Sean Wang Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin --- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 6cb65391427f..7b48df301079 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -627,6 +627,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif, mt7921_mac_wtbl_update(dev, msta->wcid.idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); + memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac)); mt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC); From 3ac837cef1fb77c047674c3633a6bd18dd615fc5 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 4 Sep 2022 00:32:56 +0900 Subject: [PATCH 431/610] Bluetooth: L2CAP: initialize delayed works at l2cap_chan_create() [ Upstream commit 2d2cb3066f2c90cd8ca540b36ba7a55e7f2406e0 ] syzbot is reporting cancel_delayed_work() without INIT_DELAYED_WORK() at l2cap_chan_del() [1], for CONF_NOT_COMPLETE flag (which meant to prevent l2cap_chan_del() from calling cancel_delayed_work()) is cleared by timer which fires before l2cap_chan_del() is called by closing file descriptor created by socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP). l2cap_bredr_sig_cmd(L2CAP_CONF_REQ) and l2cap_bredr_sig_cmd(L2CAP_CONF_RSP) are calling l2cap_ertm_init(chan), and they call l2cap_chan_ready() (which clears CONF_NOT_COMPLETE flag) only when l2cap_ertm_init(chan) succeeded. l2cap_sock_init() does not call l2cap_ertm_init(chan), and it instead sets CONF_NOT_COMPLETE flag by calling l2cap_chan_set_defaults(). However, when connect() is requested, "command 0x0409 tx timeout" happens after 2 seconds from connect() request, and CONF_NOT_COMPLETE flag is cleared after 4 seconds from connect() request, for l2cap_conn_start() from l2cap_info_timeout() callback scheduled by schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); in l2cap_connect() is calling l2cap_chan_ready(). Fix this problem by initializing delayed works used by L2CAP_MODE_ERTM mode as soon as l2cap_chan_create() allocates a channel, like I did in commit be8597239379f0f5 ("Bluetooth: initialize skb_queue_head at l2cap_chan_create()"). Link: https://syzkaller.appspot.com/bug?extid=83672956c7aa6af698b3 [1] Reported-by: syzbot Signed-off-by: Tetsuo Handa Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e8de1e7d6ff4..4e7dd41a8314 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -61,6 +61,9 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event); +static void l2cap_retrans_timeout(struct work_struct *work); +static void l2cap_monitor_timeout(struct work_struct *work); +static void l2cap_ack_timeout(struct work_struct *work); static inline u8 bdaddr_type(u8 link_type, u8 bdaddr_type) { @@ -476,6 +479,9 @@ struct l2cap_chan *l2cap_chan_create(void) write_unlock(&chan_list_lock); INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout); + INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout); + INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout); + INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout); chan->state = BT_OPEN; @@ -3320,10 +3326,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan) chan->rx_state = L2CAP_RX_STATE_RECV; chan->tx_state = L2CAP_TX_STATE_XMIT; - INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout); - INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout); - INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout); - skb_queue_head_init(&chan->srej_q); err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win); From 3423a50fa018e88aed4c900d59c3c8334d8ad583 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 19 Sep 2022 10:56:59 -0700 Subject: [PATCH 432/610] Bluetooth: hci_sysfs: Fix attempting to call device_add multiple times [ Upstream commit 448a496f760664d3e2e79466aa1787e6abc922b5 ] device_add shall not be called multiple times as stated in its documentation: 'Do not call this routine or device_register() more than once for any device structure' Syzkaller reports a bug as follows [1]: ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:33! invalid opcode: 0000 [#1] PREEMPT SMP KASAN [...] Call Trace: __list_add include/linux/list.h:69 [inline] list_add_tail include/linux/list.h:102 [inline] kobj_kset_join lib/kobject.c:164 [inline] kobject_add_internal+0x18f/0x8f0 lib/kobject.c:214 kobject_add_varg lib/kobject.c:358 [inline] kobject_add+0x150/0x1c0 lib/kobject.c:410 device_add+0x368/0x1e90 drivers/base/core.c:3452 hci_conn_add_sysfs+0x9b/0x1b0 net/bluetooth/hci_sysfs.c:53 hci_le_cis_estabilished_evt+0x57c/0xae0 net/bluetooth/hci_event.c:6799 hci_le_meta_evt+0x2b8/0x510 net/bluetooth/hci_event.c:7110 hci_event_func net/bluetooth/hci_event.c:7440 [inline] hci_event_packet+0x63d/0xfd0 net/bluetooth/hci_event.c:7495 hci_rx_work+0xae7/0x1230 net/bluetooth/hci_core.c:4007 process_one_work+0x991/0x1610 kernel/workqueue.c:2289 worker_thread+0x665/0x1080 kernel/workqueue.c:2436 kthread+0x2e4/0x3a0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 Link: https://syzkaller.appspot.com/bug?id=da3246e2d33afdb92d66bc166a0934c5b146404a Signed-off-by: Luiz Augusto von Dentz Tested-by: Hawkins Jiawei Signed-off-by: Sasha Levin --- net/bluetooth/hci_sysfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 4e3e0451b08c..08542dfc2dc5 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -48,6 +48,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn) BT_DBG("conn %p", conn); + if (device_is_registered(&conn->dev)) + return; + dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); if (device_add(&conn->dev) < 0) { From 4a5eab200e434f78b2d89eee27d1802bc1cf680f Mon Sep 17 00:00:00 2001 From: Ziyang Xuan Date: Thu, 15 Sep 2022 09:55:56 +0800 Subject: [PATCH 433/610] can: bcm: check the result of can_send() in bcm_can_tx() [ Upstream commit 3fd7bfd28cfd68ae80a2fe92ea1615722cc2ee6e ] If can_send() fail, it should not update frames_abs counter in bcm_can_tx(). Add the result check for can_send() in bcm_can_tx(). Suggested-by: Marc Kleine-Budde Suggested-by: Oliver Hartkopp Signed-off-by: Ziyang Xuan Link: https://lore.kernel.org/all/9851878e74d6d37aee2f1ee76d68361a46f89458.1663206163.git.william.xuanziyang@huawei.com Acked-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- net/can/bcm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/can/bcm.c b/net/can/bcm.c index e5ffd2bd62ab..aab3a18f4a90 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -274,6 +274,7 @@ static void bcm_can_tx(struct bcm_op *op) struct sk_buff *skb; struct net_device *dev; struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe; + int err; /* no target device? => exit */ if (!op->ifindex) @@ -298,11 +299,11 @@ static void bcm_can_tx(struct bcm_op *op) /* send with loopback */ skb->dev = dev; can_skb_set_owner(skb, op->sk); - can_send(skb, 1); + err = can_send(skb, 1); + if (!err) + op->frames_abs++; - /* update statistics */ op->currframe++; - op->frames_abs++; /* reached last frame? */ if (op->currframe >= op->nframes) From 4304b8e07579b78903f84e3aea2654af6089ce78 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 17 Sep 2022 21:28:29 +0100 Subject: [PATCH 434/610] wifi: rt2x00: don't run Rt5592 IQ calibration on MT7620 [ Upstream commit d3aad83d05aec0cfd7670cf0028f2ad4b81de92e ] The function rt2800_iq_calibrate is intended for Rt5592 only. Don't call it for MT7620 which has it's own calibration functions. Reported-by: Serge Vasilugin Signed-off-by: Daniel Golle Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/31a1c34ddbd296b82f38c18c9ae7339059215fdc.1663445157.git.daniel@makrotopia.org Signed-off-by: Sasha Levin --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index deddb0afd312..0a47180f321a 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -4365,7 +4365,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); - rt2800_iq_calibrate(rt2x00dev, rf->channel); + if (rt2x00_rt(rt2x00dev, RT5592)) + rt2800_iq_calibrate(rt2x00dev, rf->channel); } bbp = rt2800_bbp_read(rt2x00dev, 4); From 92e2e04da567642da31e753e0c89db6846ecc985 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 17 Sep 2022 21:29:26 +0100 Subject: [PATCH 435/610] wifi: rt2x00: set correct TX_SW_CFG1 MAC register for MT7620 [ Upstream commit eeb50acf15762b61921f9df18663f839f387c054 ] Set correct TX_SW_CFG1 MAC register as it is done also in v3 of the vendor driver[1]. [1]: https://gitlab.com/dm38/padavan-ng/-/blob/master/trunk/proprietary/rt_wifi/rtpci/3.0.X.X/mt76x2/chips/rt6352.c#L531 Reported-by: Serge Vasilugin Signed-off-by: Daniel Golle Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/4be38975ce600a34249e12d09a3cb758c6e71071.1663445157.git.daniel@makrotopia.org Signed-off-by: Sasha Levin --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 0a47180f321a..cc879035acae 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -5868,7 +5868,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); } else if (rt2x00_rt(rt2x00dev, RT6352)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); From 357c89074ae69b489698c953a9501ff2c8b47567 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 17 Sep 2022 21:29:40 +0100 Subject: [PATCH 436/610] wifi: rt2x00: set VGC gain for both chains of MT7620 [ Upstream commit 0e09768c085709e10ece3b68f6ac921d3f6a9caa ] Set bbp66 for all chains of the MT7620. Reported-by: Serge Vasilugin Signed-off-by: Daniel Golle Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/29e161397e5c9d9399da0fe87d44458aa2b90a78.1663445157.git.daniel@makrotopia.org Signed-off-by: Sasha Levin --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index cc879035acae..92a5231cdd95 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -5645,7 +5645,8 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev, if (qual->vgc_level != vgc_level) { if (rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT3883)) { + rt2x00_rt(rt2x00dev, RT3883) || + rt2x00_rt(rt2x00dev, RT6352)) { rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); } else if (rt2x00_rt(rt2x00dev, RT5592)) { From b5e6ada5a5d690bfcb60ee59fffb5441e6c000c2 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 17 Sep 2022 21:29:55 +0100 Subject: [PATCH 437/610] wifi: rt2x00: set SoC wmac clock register [ Upstream commit cbde6ed406a51092d9e8a2df058f5f8490f27443 ] Instead of using the default value 33 (pci), set US_CYC_CNT init based on Programming guide: If available, set chipset bus clock with fallback to cpu clock/3. Reported-by: Serge Vasilugin Signed-off-by: Daniel Golle Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/3e275d259f476f597dab91a9c395015ef3fe3284.1663445157.git.daniel@makrotopia.org Signed-off-by: Sasha Levin --- .../net/wireless/ralink/rt2x00/rt2800lib.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 92a5231cdd95..d7b862b7bf67 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -6131,6 +6131,27 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125); rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); + } else if (rt2x00_is_soc(rt2x00dev)) { + struct clk *clk = clk_get_sys("bus", NULL); + int rate; + + if (IS_ERR(clk)) { + clk = clk_get_sys("cpu", NULL); + + if (IS_ERR(clk)) { + rate = 125; + } else { + rate = clk_get_rate(clk) / 3000000; + clk_put(clk); + } + } else { + rate = clk_get_rate(clk) / 1000000; + clk_put(clk); + } + + reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); + rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, rate); + rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); } reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0); From a269c3e3908741f7512d701eb29be15e6cdb937e Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 17 Sep 2022 21:30:09 +0100 Subject: [PATCH 438/610] wifi: rt2x00: correctly set BBP register 86 for MT7620 [ Upstream commit c9aada64fe6493461127f1522d7e2f01792d2424 ] Instead of 0 set the correct value for BBP register 86 for MT7620. Reported-by: Serge Vasilugin Signed-off-by: Daniel Golle Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/257267247ee4fa7ebc6a5d0c4948b3f8119c0d77.1663445157.git.daniel@makrotopia.org Signed-off-by: Sasha Levin --- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index d7b862b7bf67..34788bfb34b7 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -4164,7 +4164,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 86, 0); + if (rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 86, 0x38); + else + rt2800_bbp_write(rt2x00dev, 86, 0); } if (rf->channel <= 14) { From 5b94d48898d9dddd579a495d67d02f1f27fe3161 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 24 Sep 2022 12:11:51 +0200 Subject: [PATCH 439/610] hwmon: (sht4x) do not overflow clamping operation on 32-bit platforms [ Upstream commit f9c0cf8f26de367c58e48b02b1cdb9c377626e6f ] On 32-bit platforms, long is 32 bits, so (long)UINT_MAX is less than (long)SHT4X_MIN_POLL_INTERVAL, which means the clamping operation is bogus. Fix this by clamping at INT_MAX, so that the upperbound is the same on all platforms. Signed-off-by: Jason A. Donenfeld Link: https://lore.kernel.org/r/20220924101151.4168414-1-Jason@zx2c4.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin --- drivers/hwmon/sht4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c index 09c2a0b06444..9aeb3dbf6c20 100644 --- a/drivers/hwmon/sht4x.c +++ b/drivers/hwmon/sht4x.c @@ -129,7 +129,7 @@ unlock: static ssize_t sht4x_interval_write(struct sht4x_data *data, long val) { - data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, UINT_MAX); + data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, INT_MAX); return 0; } From 124b7c773271f06af5a2cea694b283cdb5275cf5 Mon Sep 17 00:00:00 2001 From: Liu Jian Date: Tue, 23 Aug 2022 21:37:54 +0800 Subject: [PATCH 440/610] net: If sock is dead don't access sock's sk_wq in sk_stream_wait_memory [ Upstream commit 3f8ef65af927db247418d4e1db49164d7a158fc5 ] Fixes the below NULL pointer dereference: [...] [ 14.471200] Call Trace: [ 14.471562] [ 14.471882] lock_acquire+0x245/0x2e0 [ 14.472416] ? remove_wait_queue+0x12/0x50 [ 14.473014] ? _raw_spin_lock_irqsave+0x17/0x50 [ 14.473681] _raw_spin_lock_irqsave+0x3d/0x50 [ 14.474318] ? remove_wait_queue+0x12/0x50 [ 14.474907] remove_wait_queue+0x12/0x50 [ 14.475480] sk_stream_wait_memory+0x20d/0x340 [ 14.476127] ? do_wait_intr_irq+0x80/0x80 [ 14.476704] do_tcp_sendpages+0x287/0x600 [ 14.477283] tcp_bpf_push+0xab/0x260 [ 14.477817] tcp_bpf_sendmsg_redir+0x297/0x500 [ 14.478461] ? __local_bh_enable_ip+0x77/0xe0 [ 14.479096] tcp_bpf_send_verdict+0x105/0x470 [ 14.479729] tcp_bpf_sendmsg+0x318/0x4f0 [ 14.480311] sock_sendmsg+0x2d/0x40 [ 14.480822] ____sys_sendmsg+0x1b4/0x1c0 [ 14.481390] ? copy_msghdr_from_user+0x62/0x80 [ 14.482048] ___sys_sendmsg+0x78/0xb0 [ 14.482580] ? vmf_insert_pfn_prot+0x91/0x150 [ 14.483215] ? __do_fault+0x2a/0x1a0 [ 14.483738] ? do_fault+0x15e/0x5d0 [ 14.484246] ? __handle_mm_fault+0x56b/0x1040 [ 14.484874] ? lock_is_held_type+0xdf/0x130 [ 14.485474] ? find_held_lock+0x2d/0x90 [ 14.486046] ? __sys_sendmsg+0x41/0x70 [ 14.486587] __sys_sendmsg+0x41/0x70 [ 14.487105] ? intel_pmu_drain_pebs_core+0x350/0x350 [ 14.487822] do_syscall_64+0x34/0x80 [ 14.488345] entry_SYSCALL_64_after_hwframe+0x63/0xcd [...] The test scenario has the following flow: thread1 thread2 ----------- --------------- tcp_bpf_sendmsg tcp_bpf_send_verdict tcp_bpf_sendmsg_redir sock_close tcp_bpf_push_locked __sock_release tcp_bpf_push //inet_release do_tcp_sendpages sock->ops->release sk_stream_wait_memory // tcp_close sk_wait_event sk->sk_prot->close release_sock(__sk); *** lock_sock(sk); __tcp_close sock_orphan(sk) sk->sk_wq = NULL release_sock **** lock_sock(__sk); remove_wait_queue(sk_sleep(sk), &wait); sk_sleep(sk) //NULL pointer dereference &rcu_dereference_raw(sk->sk_wq)->wait While waiting for memory in thread1, the socket is released with its wait queue because thread2 has closed it. This caused by tcp_bpf_send_verdict didn't increase the f_count of psock->sk_redir->sk_socket->file in thread1. We should check if SOCK_DEAD flag is set on wakeup in sk_stream_wait_memory before accessing the wait queue. Suggested-by: Jakub Sitnicki Signed-off-by: Liu Jian Signed-off-by: Daniel Borkmann Acked-by: John Fastabend Cc: Eric Dumazet Link: https://lore.kernel.org/bpf/20220823133755.314697-2-liujian56@huawei.com Signed-off-by: Sasha Levin --- net/core/stream.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/stream.c b/net/core/stream.c index a166a32b411f..a61130504827 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -159,7 +159,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) *timeo_p = current_timeo; } out: - remove_wait_queue(sk_sleep(sk), &wait); + if (!sock_flag(sk, SOCK_DEAD)) + remove_wait_queue(sk_sleep(sk), &wait); return err; do_error: From d1e894f950ad48897d1a7cb05909ea29d8c3810e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Sep 2022 13:27:13 -0700 Subject: [PATCH 441/610] Bluetooth: L2CAP: Fix user-after-free [ Upstream commit 35fcbc4243aad7e7d020b7c1dfb14bb888b20a4f ] This uses l2cap_chan_hold_unless_zero() after calling __l2cap_get_chan_blah() to prevent the following trace: Bluetooth: l2cap_core.c:static void l2cap_chan_destroy(struct kref *kref) Bluetooth: chan 0000000023c4974d Bluetooth: parent 00000000ae861c08 ================================================================== BUG: KASAN: use-after-free in __mutex_waiter_is_first kernel/locking/mutex.c:191 [inline] BUG: KASAN: use-after-free in __mutex_lock_common kernel/locking/mutex.c:671 [inline] BUG: KASAN: use-after-free in __mutex_lock+0x278/0x400 kernel/locking/mutex.c:729 Read of size 8 at addr ffff888006a49b08 by task kworker/u3:2/389 Link: https://lore.kernel.org/lkml/20220622082716.478486-1-lee.jones@linaro.org Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sungwoo Kim Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4e7dd41a8314..8f1a95b9d320 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -4309,6 +4309,12 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, } } + chan = l2cap_chan_hold_unless_zero(chan); + if (!chan) { + err = -EBADSLT; + goto unlock; + } + err = 0; l2cap_chan_lock(chan); @@ -4338,6 +4344,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, } l2cap_chan_unlock(chan); + l2cap_chan_put(chan); unlock: mutex_unlock(&conn->chan_lock); From b3179865cf7e892b26eedab3d6c54b4747c774a2 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Sun, 2 Oct 2022 12:41:28 +0900 Subject: [PATCH 442/610] r8152: Rate limit overflow messages [ Upstream commit 93e2be344a7db169b7119de21ac1bf253b8c6907 ] My system shows almost 10 million of these messages over a 24-hour period which pollutes my logs. Signed-off-by: Andrew Gaul Link: https://lore.kernel.org/r/20221002034128.2026653-1-gaul@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/usb/r8152.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 7e821bed91ce..c7169243aa6e 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1871,7 +1871,9 @@ static void intr_callback(struct urb *urb) "Stop submitting intr, status %d\n", status); return; case -EOVERFLOW: - netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); + if (net_ratelimit()) + netif_info(tp, intr, tp->netdev, + "intr status -EOVERFLOW\n"); goto resubmit; /* -EPIPE: should clear the halt */ default: From 5ab84b1596b26a6c789e3075252df720b15fd126 Mon Sep 17 00:00:00 2001 From: Jianglei Nie Date: Tue, 5 Jul 2022 17:43:06 +0800 Subject: [PATCH 443/610] drm/nouveau/nouveau_bo: fix potential memory leak in nouveau_bo_alloc() [ Upstream commit 6dc548745d5b5102e3c53dc5097296ac270b6c69 ] nouveau_bo_alloc() allocates a memory chunk for "nvbo" with kzalloc(). When some error occurs, "nvbo" should be released. But when WARN_ON(pi < 0)) equals true, the function return ERR_PTR without releasing the "nvbo", which will lead to a memory leak. We should release the "nvbo" with kfree() if WARN_ON(pi < 0)) equals true. Signed-off-by: Jianglei Nie Signed-off-by: Lyude Paul Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20220705094306.2244103-1-niejianglei2021@163.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/nouveau/nouveau_bo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 511fb8dfb4c4..da58230bcb1f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -281,8 +281,10 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain, break; } - if (WARN_ON(pi < 0)) + if (WARN_ON(pi < 0)) { + kfree(nvbo); return ERR_PTR(-EINVAL); + } /* Disable compression if suitable settings couldn't be found. */ if (nvbo->comp && !vmm->page[pi].comp) { From df5ac9392648394db23a98442d58f283b5479329 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 5 Jul 2022 12:02:13 +0200 Subject: [PATCH 444/610] drm: Use size_t type for len variable in drm_copy_field() [ Upstream commit 94dc3471d1b2b58b3728558d0e3f264e9ce6ff59 ] The strlen() function returns a size_t which is an unsigned int on 32-bit arches and an unsigned long on 64-bit arches. But in the drm_copy_field() function, the strlen() return value is assigned to an 'int len' variable. Later, the len variable is passed as copy_from_user() third argument that is an unsigned long parameter as well. In theory, this can lead to an integer overflow via type conversion. Since the assignment happens to a signed int lvalue instead of a size_t lvalue. In practice though, that's unlikely since the values copied are set by DRM drivers and not controlled by userspace. But using a size_t for len is the correct thing to do anyways. Signed-off-by: Javier Martinez Canillas Tested-by: Peter Robinson Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20220705100215.572498-2-javierm@redhat.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index be4a52dc4d6f..5669c6cf7135 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -472,7 +472,7 @@ EXPORT_SYMBOL(drm_invalid_op); */ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) { - int len; + size_t len; /* don't overflow userbuf */ len = strlen(value); From ca163e389f0ae096a4e1e19f0a95e60ed80b4e31 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 5 Jul 2022 12:02:14 +0200 Subject: [PATCH 445/610] drm: Prevent drm_copy_field() to attempt copying a NULL pointer [ Upstream commit f6ee30407e883042482ad4ad30da5eaba47872ee ] There are some struct drm_driver fields that are required by drivers since drm_copy_field() attempts to copy them to user-space via DRM_IOCTL_VERSION. But it can be possible that a driver has a bug and did not set some of the fields, which leads to drm_copy_field() attempting to copy a NULL pointer: [ +10.395966] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000 [ +0.010955] Mem abort info: [ +0.002835] ESR = 0x0000000096000004 [ +0.003872] EC = 0x25: DABT (current EL), IL = 32 bits [ +0.005395] SET = 0, FnV = 0 [ +0.003113] EA = 0, S1PTW = 0 [ +0.003182] FSC = 0x04: level 0 translation fault [ +0.004964] Data abort info: [ +0.002919] ISV = 0, ISS = 0x00000004 [ +0.003886] CM = 0, WnR = 0 [ +0.003040] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000115dad000 [ +0.006536] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 [ +0.006925] Internal error: Oops: 96000004 [#1] SMP ... [ +0.011113] pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ +0.007061] pc : __pi_strlen+0x14/0x150 [ +0.003895] lr : drm_copy_field+0x30/0x1a4 [ +0.004156] sp : ffff8000094b3a50 [ +0.003355] x29: ffff8000094b3a50 x28: ffff8000094b3b70 x27: 0000000000000040 [ +0.007242] x26: ffff443743c2ba00 x25: 0000000000000000 x24: 0000000000000040 [ +0.007243] x23: ffff443743c2ba00 x22: ffff8000094b3b70 x21: 0000000000000000 [ +0.007241] x20: 0000000000000000 x19: ffff8000094b3b90 x18: 0000000000000000 [ +0.007241] x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaab14b9af40 [ +0.007241] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 [ +0.007239] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa524ad67d4d8 [ +0.007242] x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : 6c6e6263606e7141 [ +0.007239] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 [ +0.007241] x2 : 0000000000000000 x1 : ffff8000094b3b90 x0 : 0000000000000000 [ +0.007240] Call trace: [ +0.002475] __pi_strlen+0x14/0x150 [ +0.003537] drm_version+0x84/0xac [ +0.003448] drm_ioctl_kernel+0xa8/0x16c [ +0.003975] drm_ioctl+0x270/0x580 [ +0.003448] __arm64_sys_ioctl+0xb8/0xfc [ +0.003978] invoke_syscall+0x78/0x100 [ +0.003799] el0_svc_common.constprop.0+0x4c/0xf4 [ +0.004767] do_el0_svc+0x38/0x4c [ +0.003357] el0_svc+0x34/0x100 [ +0.003185] el0t_64_sync_handler+0x11c/0x150 [ +0.004418] el0t_64_sync+0x190/0x194 [ +0.003716] Code: 92402c04 b200c3e8 f13fc09f 5400088c (a9400c02) [ +0.006180] ---[ end trace 0000000000000000 ]--- Reported-by: Peter Robinson Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20220705100215.572498-3-javierm@redhat.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_ioctl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 5669c6cf7135..fb5e6f86dea2 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -474,6 +474,12 @@ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) { size_t len; + /* don't attempt to copy a NULL pointer */ + if (WARN_ONCE(!value, "BUG: the value to copy was not set!")) { + *buf_len = 0; + return 0; + } + /* don't overflow userbuf */ len = strlen(value); if (len > *buf_len) From 5ff7bec678ca89ce7e3114c1b75adddaeb32ef57 Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Fri, 8 Jul 2022 16:39:21 +0100 Subject: [PATCH 446/610] drm/komeda: Fix handling of atomic commits in the atomic_commit_tail hook [ Upstream commit eaa225b6b52233d45457fd33730e1528c604d92d ] Komeda driver relies on the generic DRM atomic helper functions to handle commits. It only implements an atomic_commit_tail hook for the mode_config_helper_funcs and even that one is pretty close to the generic implementation with the exception of additional dma_fence signalling. What the generic helper framework doesn't do is waiting for the actual hardware to signal that the commit parameters have been written into the appropriate registers. As we signal CRTC events only on the irq handlers, we need to flush the configuration and wait for the hardware to respond. Add the Komeda specific implementation for atomic_commit_hw_done() that flushes and waits for flip done before calling drm_atomic_helper_commit_hw_done(). The fix was prompted by a patch from Carsten Haitzler where he was trying to solve the same issue but in a different way that I think can lead to wrong event signaling to userspace. Reported-by: Carsten Haitzler Tested-by: Carsten Haitzler Reviewed-by: Carsten Haitzler Signed-off-by: Liviu Dudau Link: https://patchwork.freedesktop.org/patch/msgid/20220722122139.288486-1-liviu.dudau@arm.com Signed-off-by: Sasha Levin --- .../gpu/drm/arm/display/komeda/komeda_crtc.c | 4 ++-- .../gpu/drm/arm/display/komeda/komeda_kms.c | 21 ++++++++++++++++++- .../gpu/drm/arm/display/komeda/komeda_kms.h | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 59172acb9738..292f533d8cf0 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -235,7 +235,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, crtc->state->event = NULL; drm_crtc_send_vblank_event(crtc, event); } else { - DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n", + DRM_WARN("CRTC[%d]: FLIP happened but no pending commit.\n", drm_crtc_index(&kcrtc->base)); } spin_unlock_irqrestore(&crtc->dev->event_lock, flags); @@ -286,7 +286,7 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc, komeda_crtc_do_flush(crtc, old); } -static void +void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc, struct completion *input_flip_done) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 93b7f09b96ca..327051bba5b6 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -69,6 +69,25 @@ static const struct drm_driver komeda_kms_driver = { .minor = 1, }; +static void komeda_kms_atomic_commit_hw_done(struct drm_atomic_state *state) +{ + struct drm_device *dev = state->dev; + struct komeda_kms_dev *kms = to_kdev(dev); + int i; + + for (i = 0; i < kms->n_crtcs; i++) { + struct komeda_crtc *kcrtc = &kms->crtcs[i]; + + if (kcrtc->base.state->active) { + struct completion *flip_done = NULL; + if (kcrtc->base.state->event) + flip_done = kcrtc->base.state->event->base.completion; + komeda_crtc_flush_and_wait_for_flip_done(kcrtc, flip_done); + } + } + drm_atomic_helper_commit_hw_done(state); +} + static void komeda_kms_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *dev = old_state->dev; @@ -81,7 +100,7 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_commit_modeset_enables(dev, old_state); - drm_atomic_helper_commit_hw_done(old_state); + komeda_kms_atomic_commit_hw_done(old_state); drm_atomic_helper_wait_for_flip_done(dev, old_state); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index 456f3c435719..bf6e8fba5061 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -182,6 +182,8 @@ void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms); void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, struct komeda_events *evts); +void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc, + struct completion *input_flip_done); struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev); void komeda_kms_detach(struct komeda_kms_dev *kms); From a29f7427041a943484f916157c43c46d3bbf25d4 Mon Sep 17 00:00:00 2001 From: Zeng Jingxiang Date: Wed, 27 Jul 2022 15:31:19 +0800 Subject: [PATCH 447/610] gpu: lontium-lt9611: Fix NULL pointer dereference in lt9611_connector_init() [ Upstream commit ef8886f321c5dab8124b9153d25afa2a71d05323 ] A NULL check for bridge->encoder shows that it may be NULL, but it already been dereferenced on all paths leading to the check. 812 if (!bridge->encoder) { Dereference the pointer bridge->encoder. 810 drm_connector_attach_encoder(<9611->connector, bridge->encoder); Signed-off-by: Zeng Jingxiang Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20220727073119.1578972-1-zengjx95@gmail.com 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 29b1ce2140ab..1dcc28a4d853 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -816,13 +816,14 @@ static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt961 drm_connector_helper_add(<9611->connector, <9611_bridge_connector_helper_funcs); - drm_connector_attach_encoder(<9611->connector, bridge->encoder); if (!bridge->encoder) { DRM_ERROR("Parent encoder object not found"); return -ENODEV; } + drm_connector_attach_encoder(<9611->connector, bridge->encoder); + return 0; } From a47d92c74b1e884336abd7fcd6a0daefafcf6ea5 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 11 Aug 2022 17:43:26 -0300 Subject: [PATCH 448/610] drm/amd/display: fix overflow on MIN_I64 definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 6ae0632d17759852c07e2d1e0a31c728eb6ba246 ] The definition of MIN_I64 in bw_fixed.c can cause gcc to whinge about integer overflow, because it is treated as a positive value, which is then negated. The temporary positive value is not necessarily representable. This causes the following warning: ../drivers/gpu/drm/amd/amdgpu/../display/dc/dml/calcs/bw_fixed.c:30:19: warning: integer overflow in expression ‘-9223372036854775808’ of type ‘long long int’ results in ‘-9223372036854775808’ [-Woverflow] 30 | (int64_t)(-(1LL << 63)) | ^ Writing out (-MAX_I64 - 1) works instead. Signed-off-by: David Gow Signed-off-by: Tales Aparecida Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c index 6ca288fb5fb9..2d46bc527b21 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c @@ -26,12 +26,12 @@ #include "bw_fixed.h" -#define MIN_I64 \ - (int64_t)(-(1LL << 63)) - #define MAX_I64 \ (int64_t)((1ULL << 63) - 1) +#define MIN_I64 \ + (-MAX_I64 - 1) + #define FRACTIONAL_PART_MASK \ ((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1) From dfbed8c92eb853929f4fa676ba493391dab47be4 Mon Sep 17 00:00:00 2001 From: Vivek Kasireddy Date: Wed, 24 Aug 2022 23:35:22 -0700 Subject: [PATCH 449/610] udmabuf: Set ubuf->sg = NULL if the creation of sg table fails [ Upstream commit d9c04a1b7a15b5e74b2977461d9511e497f05d8f ] When userspace tries to map the dmabuf and if for some reason (e.g. OOM) the creation of the sg table fails, ubuf->sg needs to be set to NULL. Otherwise, when the userspace subsequently closes the dmabuf fd, we'd try to erroneously free the invalid sg table from release_udmabuf resulting in the following crash reported by syzbot: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 PID: 3609 Comm: syz-executor487 Not tainted 5.19.0-syzkaller-13930-g7ebfc85e2cd7 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022 RIP: 0010:dma_unmap_sgtable include/linux/dma-mapping.h:378 [inline] RIP: 0010:put_sg_table drivers/dma-buf/udmabuf.c:89 [inline] RIP: 0010:release_udmabuf+0xcb/0x4f0 drivers/dma-buf/udmabuf.c:114 Code: 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 2b 04 00 00 48 8d 7d 0c 4c 8b 63 30 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 e2 RSP: 0018:ffffc900037efd30 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: ffffffff8cb67800 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff84ad27e0 RDI: 0000000000000000 RBP: fffffffffffffff4 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 000000000008c07c R12: ffff88801fa05000 R13: ffff888073db07e8 R14: ffff888025c25440 R15: 0000000000000000 FS: 0000555555fc4300(0000) GS:ffff8880b9a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fc1c0ce06e4 CR3: 00000000715e6000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: dma_buf_release+0x157/0x2d0 drivers/dma-buf/dma-buf.c:78 __dentry_kill+0x42b/0x640 fs/dcache.c:612 dentry_kill fs/dcache.c:733 [inline] dput+0x806/0xdb0 fs/dcache.c:913 __fput+0x39c/0x9d0 fs/file_table.c:333 task_work_run+0xdd/0x1a0 kernel/task_work.c:177 ptrace_notify+0x114/0x140 kernel/signal.c:2353 ptrace_report_syscall include/linux/ptrace.h:420 [inline] ptrace_report_syscall_exit include/linux/ptrace.h:482 [inline] syscall_exit_work kernel/entry/common.c:249 [inline] syscall_exit_to_user_mode_prepare+0x129/0x280 kernel/entry/common.c:276 __syscall_exit_to_user_mode_work kernel/entry/common.c:281 [inline] syscall_exit_to_user_mode+0x9/0x50 kernel/entry/common.c:294 do_syscall_64+0x42/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fc1c0c35b6b Code: 0f 05 48 3d 00 f0 ff ff 77 45 c3 0f 1f 40 00 48 83 ec 18 89 7c 24 0c e8 63 fc ff ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 a1 fc ff ff 8b 44 RSP: 002b:00007ffd78a06090 EFLAGS: 00000293 ORIG_RAX: 0000000000000003 RAX: 0000000000000000 RBX: 0000000000000007 RCX: 00007fc1c0c35b6b RDX: 0000000020000280 RSI: 0000000040086200 RDI: 0000000000000006 RBP: 0000000000000007 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000293 R12: 000000000000000c R13: 0000000000000003 R14: 00007fc1c0cfe4a0 R15: 00007ffd78a06140 Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:dma_unmap_sgtable include/linux/dma-mapping.h:378 [inline] RIP: 0010:put_sg_table drivers/dma-buf/udmabuf.c:89 [inline] RIP: 0010:release_udmabuf+0xcb/0x4f0 drivers/dma-buf/udmabuf.c:114 Reported-by: syzbot+c80e9ef5d8bb45894db0@syzkaller.appspotmail.com Cc: Gerd Hoffmann Signed-off-by: Vivek Kasireddy Link: http://patchwork.freedesktop.org/patch/msgid/20220825063522.801264-1-vivek.kasireddy@intel.com Signed-off-by: Gerd Hoffmann Signed-off-by: Sasha Levin --- drivers/dma-buf/udmabuf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 38e8767ec371..bf11d32205f3 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -124,17 +124,20 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, { struct udmabuf *ubuf = buf->priv; struct device *dev = ubuf->device->this_device; + int ret = 0; if (!ubuf->sg) { ubuf->sg = get_sg_table(dev, buf, direction); - if (IS_ERR(ubuf->sg)) - return PTR_ERR(ubuf->sg); + if (IS_ERR(ubuf->sg)) { + ret = PTR_ERR(ubuf->sg); + ubuf->sg = NULL; + } } else { dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, direction); } - return 0; + return ret; } static int end_cpu_udmabuf(struct dma_buf *buf, From 39d7a81bbb7aafb2114fbeca9363b3dfa501b1ac Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 26 Aug 2022 20:57:33 +0200 Subject: [PATCH 450/610] drm: bridge: dw_hdmi: only trigger hotplug event on link change [ Upstream commit da09daf881082266e4075657fac53c7966de8e4d ] There are two events that signal a real change of the link state: HPD going high means the sink is newly connected or wants the source to re-read the EDID, RX sense going low is a indication that the link has been disconnected. Ignore the other two events that also trigger interrupts, but don't need immediate attention: HPD going low does not necessarily mean the link has been lost and should not trigger a immediate read of the status. RX sense going high also does not require a detect cycle, as HPD going high is the right point in time to read the EDID. Signed-off-by: Lucas Stach Reviewed-by: Neil Armstrong (v1) Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20220826185733.3213248-1-l.stach@pengutronix.de Signed-off-by: Sasha Levin --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 25d58dcfc87e..d3129a3e6ab7 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2970,6 +2970,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) { struct dw_hdmi *hdmi = dev_id; u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat; + enum drm_connector_status status = connector_status_unknown; intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); @@ -3008,13 +3009,15 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) cec_notifier_phys_addr_invalidate(hdmi->cec_notifier); mutex_unlock(&hdmi->cec_notifier_mutex); } + + if (phy_stat & HDMI_PHY_HPD) + status = connector_status_connected; + + if (!(phy_stat & (HDMI_PHY_HPD | HDMI_PHY_RX_SENSE))) + status = connector_status_disconnected; } - if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { - enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD - ? connector_status_connected - : connector_status_disconnected; - + if (status != connector_status_unknown) { dev_dbg(hdmi->dev, "EVENT=%s\n", status == connector_status_connected ? "plugin" : "plugout"); From 0506c4eae9a924c9181954348f016af738f7327c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 4 Sep 2022 18:12:47 +0200 Subject: [PATCH 451/610] ALSA: usb-audio: Register card at the last interface [ Upstream commit 6392dcd1d0c7034ccf630ec55fc9e5810ecadf3b ] The USB-audio driver matches per interface, and as default, it registers the card instance at the very first instance. This can be a problem for the devices that have multiple interfaces to be probed, as the udev rule isn't applied properly for the later appearing interfaces. Although we introduced the delayed_register option and the quirks for covering those shortcomings, it's nothing but a workaround for specific devices. This patch is an another attempt to fix the problem in a more generic way. Now the driver checks the whole USB device descriptor at the very first time when an interface is attached to a sound card. It looks at each matching interface in the descriptor and remembers the last matching one. The snd_card_register() is invoked only when this last interface is probed. After this change, the quirks for the delayed registration become superfluous, hence they are removed along with the patch. OTOH, the delayed_register option is still kept, as it might be useful for some corner cases (e.g. a special driver overtakes the interface probe from the standard driver, and the last interface probe may miss). Link: https://lore.kernel.org/r/20220904161247.16461-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/card.c | 32 +++++++++++++++++++++++++------- sound/usb/quirks.c | 42 ------------------------------------------ sound/usb/quirks.h | 2 -- sound/usb/usbaudio.h | 1 + 4 files changed, 26 insertions(+), 51 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 713b84d8d42f..207c212eabde 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -689,7 +689,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id) return false; } -static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface) +static int check_delayed_register_option(struct snd_usb_audio *chip) { int i; unsigned int id, inum; @@ -698,14 +698,31 @@ static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface) if (delayed_register[i] && sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 && id == chip->usb_id) - return iface < inum; + return inum; } - return false; + return -1; } static const struct usb_device_id usb_audio_ids[]; /* defined below */ +/* look for the last interface that matches with our ids and remember it */ +static void find_last_interface(struct snd_usb_audio *chip) +{ + struct usb_host_config *config = chip->dev->actconfig; + struct usb_interface *intf; + int i; + + if (!config) + return; + for (i = 0; i < config->desc.bNumInterfaces; i++) { + intf = config->interface[i]; + if (usb_match_id(intf, usb_audio_ids)) + chip->last_iface = intf->altsetting[0].desc.bInterfaceNumber; + } + usb_audio_dbg(chip, "Found last interface = %d\n", chip->last_iface); +} + /* look for the corresponding quirk */ static const struct snd_usb_audio_quirk * get_alias_quirk(struct usb_device *dev, unsigned int id) @@ -812,6 +829,7 @@ static int usb_audio_probe(struct usb_interface *intf, err = -ENODEV; goto __error; } + find_last_interface(chip); } if (chip->num_interfaces >= MAX_CARD_INTERFACES) { @@ -861,11 +879,11 @@ static int usb_audio_probe(struct usb_interface *intf, chip->need_delayed_register = false; /* clear again */ } - /* we are allowed to call snd_card_register() many times, but first - * check to see if a device needs to skip it or do anything special + /* register card if we reach to the last interface or to the specified + * one given via option */ - if (!snd_usb_registration_quirk(chip, ifnum) && - !check_delayed_register_option(chip, ifnum)) { + if (check_delayed_register_option(chip) == ifnum || + chip->last_iface == ifnum) { err = snd_card_register(chip->card); if (err < 0) goto __error; diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 5b4d8f5eade2..8c3b0be909eb 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1728,48 +1728,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, } } -/* - * registration quirk: - * the registration is skipped if a device matches with the given ID, - * unless the interface reaches to the defined one. This is for delaying - * the registration until the last known interface, so that the card and - * devices appear at the same time. - */ - -struct registration_quirk { - unsigned int usb_id; /* composed via USB_ID() */ - unsigned int interface; /* the interface to trigger register */ -}; - -#define REG_QUIRK_ENTRY(vendor, product, iface) \ - { .usb_id = USB_ID(vendor, product), .interface = (iface) } - -static const struct registration_quirk registration_quirks[] = { - REG_QUIRK_ENTRY(0x0951, 0x16d8, 2), /* Kingston HyperX AMP */ - REG_QUIRK_ENTRY(0x0951, 0x16ed, 2), /* Kingston HyperX Cloud Alpha S */ - REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */ - REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */ - REG_QUIRK_ENTRY(0x0ecb, 0x1f47, 2), /* JBL Quantum 800 */ - REG_QUIRK_ENTRY(0x0ecb, 0x1f4c, 2), /* JBL Quantum 400 */ - REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */ - REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */ - REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */ - { 0 } /* terminator */ -}; - -/* return true if skipping registration */ -bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface) -{ - const struct registration_quirk *q; - - for (q = registration_quirks; q->usb_id; q++) - if (chip->usb_id == q->usb_id) - return iface < q->interface; - - /* Register as normal */ - return false; -} - /* * driver behavior quirk flags */ diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 31abb7cb01a5..f9bfd5ac7bab 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h @@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, struct audioformat *fp, int stream); -bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface); - void snd_usb_init_quirk_flags(struct snd_usb_audio *chip); #endif /* __USBAUDIO_QUIRKS_H */ diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 044cd7ab27cb..39c3c61a7e49 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -37,6 +37,7 @@ struct snd_usb_audio { unsigned int quirk_flags; unsigned int need_delayed_register:1; /* warn for delayed registration */ int num_interfaces; + int last_iface; int num_suspended_intf; int sample_rate_read_error; From 2810061452f9b748b096ad023d318690ca519aa3 Mon Sep 17 00:00:00 2001 From: Mateusz Kwiatkowski Date: Mon, 29 Aug 2022 15:11:42 +0200 Subject: [PATCH 452/610] drm/vc4: vec: Fix timings for VEC modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 30d7565be96b3946c18a1ce3fd538f7946839092 ] This commit fixes vertical timings of the VEC (composite output) modes to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R standards. Previous timings were actually defined as 502 and 601 lines, resulting in non-standard 62.69 Hz and 52 Hz signals being generated, respectively. Signed-off-by: Mateusz Kwiatkowski Acked-by: Noralf Trønnes Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20220728-rpi-analog-tv-properties-v2-28-459522d653a7@cerno.tech Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_vec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 11fc3d6f66b1..4e2250b8fa23 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -256,7 +256,7 @@ static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec) static const struct drm_display_mode ntsc_mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500, 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0, - 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0, + 480, 480 + 7, 480 + 7 + 6, 525, 0, DRM_MODE_FLAG_INTERLACE) }; @@ -278,7 +278,7 @@ static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec) static const struct drm_display_mode pal_mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500, 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0, - 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0, + 576, 576 + 4, 576 + 4 + 6, 625, 0, DRM_MODE_FLAG_INTERLACE) }; From 74636047845cd2c91ad3baec60e506315a760bb0 Mon Sep 17 00:00:00 2001 From: Maya Matuszczyk Date: Wed, 3 Aug 2022 20:24:03 +0200 Subject: [PATCH 453/610] drm: panel-orientation-quirks: Add quirk for Anbernic Win600 [ Upstream commit 770e19076065e079a32f33eb11be2057c87f1cde ] This device is another x86 gaming handheld, and as (hopefully) there is only one set of DMI IDs it's using DMI_EXACT_MATCH Signed-off-by: Maya Matuszczyk Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20220803182402.1217293-1-maccraft123mc@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 f5ab891731d0..083273736c83 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -128,6 +128,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Anbernic Win600 */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"), + }, + .driver_data = (void *)&lcd720x1280_rightside_up, }, { /* Asus T100HA */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), From 39da49ffa2f3d0b077ce3c056f9998d62a086d63 Mon Sep 17 00:00:00 2001 From: Jameson Thies Date: Tue, 13 Sep 2022 20:49:54 +0000 Subject: [PATCH 454/610] platform/chrome: cros_ec: Notify the PM of wake events during resume [ Upstream commit 8edd2752b0aa498b3a61f3caee8f79f7e0567fad ] cros_ec_handle_event in the cros_ec driver can notify the PM of wake events. When a device is suspended, cros_ec_handle_event will not check MKBP events. Instead, received MKBP events are checked during resume by cros_ec_report_events_during_suspend. But cros_ec_report_events_during_suspend cannot notify the PM if received events are wake events, causing wake events to not be reported if received while the device is suspended. Update cros_ec_report_events_during_suspend to notify the PM of wake events during resume by calling pm_wakeup_event. Signed-off-by: Jameson Thies Reviewed-by: Prashant Malani Reviewed-by: Benson Leung Signed-off-by: Tzung-Bi Shih Link: https://lore.kernel.org/r/20220913204954.2931042-1-jthies@google.com Signed-off-by: Sasha Levin --- drivers/platform/chrome/cros_ec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index 4f0390b10cd3..9664e13ded59 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -353,10 +353,16 @@ EXPORT_SYMBOL(cros_ec_suspend); static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev) { + bool wake_event; + while (ec_dev->mkbp_event_supported && - cros_ec_get_next_event(ec_dev, NULL, NULL) > 0) + cros_ec_get_next_event(ec_dev, &wake_event, NULL) > 0) { blocking_notifier_call_chain(&ec_dev->event_notifier, 1, ec_dev); + + if (wake_event && device_may_wakeup(ec_dev->dev)) + pm_wakeup_event(ec_dev->dev, 0); + } } /** From f16e1b7b3968996fca9fa71794e3c63eb1c6a9e4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 17 Sep 2022 23:04:07 +0200 Subject: [PATCH 455/610] platform/x86: msi-laptop: Change DMI match / alias strings to fix module autoloading [ Upstream commit 2a2565272a3628e45d61625e36ef17af7af4e3de ] On a MSI S270 with Fedora 37 x86_64 / systemd-251.4 the module does not properly autoload. This is likely caused by issues with how systemd-udevd handles the single quote char (') which is part of the sys_vendor / chassis_vendor strings on this laptop. As a workaround remove the single quote char + everything behind it from the sys_vendor + chassis_vendor matches. This fixes the module not autoloading. Link: https://github.com/systemd/systemd/issues/24715 Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20220917210407.647432-1-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/msi-laptop.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 3e935303b143..0e804b6c2d24 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -596,11 +596,10 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = { { .ident = "MSI S270", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"), DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), - DMI_MATCH(DMI_CHASSIS_VENDOR, - "MICRO-STAR INT'L CO.,LTD") + DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT") }, .driver_data = &quirk_old_ec_model, .callback = dmi_check_cb @@ -633,8 +632,7 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = { DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), - DMI_MATCH(DMI_CHASSIS_VENDOR, - "MICRO-STAR INT'L CO.,LTD") + DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT") }, .driver_data = &quirk_old_ec_model, .callback = dmi_check_cb From e3675f688d3b2100f76b18d7bda19842061fcbc3 Mon Sep 17 00:00:00 2001 From: Jairaj Arava Date: Mon, 19 Sep 2022 13:44:29 +0200 Subject: [PATCH 456/610] ASoC: SOF: pci: Change DMI match info to support all Chrome platforms [ Upstream commit c1c1fc8103f794a10c5c15e3c17879caf4f42c8f ] In some Chrome platforms if OEM's use their own string as SYS_VENDOR than "Google", it leads to firmware load failure from intel/sof/community path. Hence, changing SYS_VENDOR to PRODUCT_FAMILY in which "Google" is used as common prefix and is supported in all Chrome platforms. Reviewed-by: Ranjani Sridharan Reviewed-by: Chao Song Reviewed-by: Curtis Malainey Signed-off-by: Jairaj Arava Signed-off-by: Curtis Malainey Signed-off-by: Sathyanarayana Nujella Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220919114429.42700-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/sof/sof-pci-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index b773289c928d..3b4c011e0283 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -80,7 +80,7 @@ static const struct dmi_system_id community_key_platforms[] = { { .ident = "Google Chromebooks", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"), } }, {}, From d894db35617f12adf67102228c602e44dafde046 Mon Sep 17 00:00:00 2001 From: hongao Date: Tue, 20 Sep 2022 17:24:53 +0800 Subject: [PATCH 457/610] drm/amdgpu: fix initial connector audio value [ Upstream commit 4bb71fce58f30df3f251118291d6b0187ce531e6 ] This got lost somewhere along the way, This fixes audio not working until set_property was called. Signed-off-by: hongao Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index a09876bb7ec8..4b1d62ebf8dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -1671,10 +1671,12 @@ amdgpu_connector_add(struct amdgpu_device *adev, adev->mode_info.dither_property, AMDGPU_FMT_DITHER_DISABLE); - if (amdgpu_audio != 0) + if (amdgpu_audio != 0) { drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; + } subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true; @@ -1796,6 +1798,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property, @@ -1849,6 +1852,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property, @@ -1899,6 +1903,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property, From d76ff04a72f90767455059c8239b06042cd0ed23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= Date: Mon, 19 Sep 2022 02:09:38 +0100 Subject: [PATCH 458/610] drm/meson: reorder driver deinit sequence to fix use-after-free bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 31c519981eb141c7ec39bfd5be25d35f02edb868 ] Unloading the driver triggers the following KASAN warning: [ +0.006275] ============================================================= [ +0.000029] BUG: KASAN: use-after-free in __list_del_entry_valid+0xe0/0x1a0 [ +0.000026] Read of size 8 at addr ffff000020c395e0 by task rmmod/2695 [ +0.000019] CPU: 5 PID: 2695 Comm: rmmod Tainted: G C O 5.19.0-rc6-lrmbkasan+ #1 [ +0.000013] Hardware name: Hardkernel ODROID-N2Plus (DT) [ +0.000008] Call trace: [ +0.000007] dump_backtrace+0x1ec/0x280 [ +0.000013] show_stack+0x24/0x80 [ +0.000008] dump_stack_lvl+0x98/0xd4 [ +0.000011] print_address_description.constprop.0+0x80/0x520 [ +0.000011] print_report+0x128/0x260 [ +0.000007] kasan_report+0xb8/0xfc [ +0.000008] __asan_report_load8_noabort+0x3c/0x50 [ +0.000010] __list_del_entry_valid+0xe0/0x1a0 [ +0.000009] drm_atomic_private_obj_fini+0x30/0x200 [drm] [ +0.000172] drm_bridge_detach+0x94/0x260 [drm] [ +0.000145] drm_encoder_cleanup+0xa4/0x290 [drm] [ +0.000144] drm_mode_config_cleanup+0x118/0x740 [drm] [ +0.000143] drm_mode_config_init_release+0x1c/0x2c [drm] [ +0.000144] drm_managed_release+0x170/0x414 [drm] [ +0.000142] drm_dev_put.part.0+0xc0/0x124 [drm] [ +0.000143] drm_dev_put+0x20/0x30 [drm] [ +0.000142] meson_drv_unbind+0x1d8/0x2ac [meson_drm] [ +0.000028] take_down_aggregate_device+0xb0/0x160 [ +0.000016] component_del+0x18c/0x360 [ +0.000009] meson_dw_hdmi_remove+0x28/0x40 [meson_dw_hdmi] [ +0.000015] platform_remove+0x64/0xb0 [ +0.000009] device_remove+0xb8/0x154 [ +0.000009] device_release_driver_internal+0x398/0x5b0 [ +0.000009] driver_detach+0xac/0x1b0 [ +0.000009] bus_remove_driver+0x158/0x29c [ +0.000009] driver_unregister+0x70/0xb0 [ +0.000008] platform_driver_unregister+0x20/0x2c [ +0.000008] meson_dw_hdmi_platform_driver_exit+0x1c/0x30 [meson_dw_hdmi] [ +0.000012] __do_sys_delete_module+0x288/0x400 [ +0.000011] __arm64_sys_delete_module+0x5c/0x80 [ +0.000009] invoke_syscall+0x74/0x260 [ +0.000009] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000009] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000012] el0t_64_sync_handler+0x11c/0x150 [ +0.000008] el0t_64_sync+0x18c/0x190 [ +0.000018] Allocated by task 0: [ +0.000007] (stack is not available) [ +0.000011] Freed by task 2695: [ +0.000008] kasan_save_stack+0x2c/0x5c [ +0.000011] kasan_set_track+0x2c/0x40 [ +0.000008] kasan_set_free_info+0x28/0x50 [ +0.000009] ____kasan_slab_free+0x128/0x1d4 [ +0.000008] __kasan_slab_free+0x18/0x24 [ +0.000007] slab_free_freelist_hook+0x108/0x230 [ +0.000011] kfree+0x110/0x35c [ +0.000008] release_nodes+0xf0/0x16c [ +0.000009] devres_release_group+0x180/0x270 [ +0.000008] component_unbind+0x128/0x1e0 [ +0.000010] component_unbind_all+0x1b8/0x264 [ +0.000009] meson_drv_unbind+0x1a0/0x2ac [meson_drm] [ +0.000025] take_down_aggregate_device+0xb0/0x160 [ +0.000009] component_del+0x18c/0x360 [ +0.000009] meson_dw_hdmi_remove+0x28/0x40 [meson_dw_hdmi] [ +0.000012] platform_remove+0x64/0xb0 [ +0.000008] device_remove+0xb8/0x154 [ +0.000009] device_release_driver_internal+0x398/0x5b0 [ +0.000009] driver_detach+0xac/0x1b0 [ +0.000009] bus_remove_driver+0x158/0x29c [ +0.000008] driver_unregister+0x70/0xb0 [ +0.000008] platform_driver_unregister+0x20/0x2c [ +0.000008] meson_dw_hdmi_platform_driver_exit+0x1c/0x30 [meson_dw_hdmi] [ +0.000011] __do_sys_delete_module+0x288/0x400 [ +0.000010] __arm64_sys_delete_module+0x5c/0x80 [ +0.000008] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000008] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000009] el0t_64_sync_handler+0x11c/0x150 [ +0.000009] el0t_64_sync+0x18c/0x190 [ +0.000014] The buggy address belongs to the object at ffff000020c39000 which belongs to the cache kmalloc-4k of size 4096 [ +0.000008] The buggy address is located 1504 bytes inside of 4096-byte region [ffff000020c39000, ffff000020c3a000) [ +0.000016] The buggy address belongs to the physical page: [ +0.000009] page:fffffc0000830e00 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x20c38 [ +0.000013] head:fffffc0000830e00 order:3 compound_mapcount:0 compound_pincount:0 [ +0.000008] flags: 0xffff00000010200(slab|head|node=0|zone=0|lastcpupid=0xffff) [ +0.000019] raw: 0ffff00000010200 fffffc0000fd4808 fffffc0000126208 ffff000000002e80 [ +0.000009] raw: 0000000000000000 0000000000020002 00000001ffffffff 0000000000000000 [ +0.000008] page dumped because: kasan: bad access detected [ +0.000011] Memory state around the buggy address: [ +0.000008] ffff000020c39480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ffff000020c39500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] >ffff000020c39580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ^ [ +0.000007] ffff000020c39600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ffff000020c39680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000006] ================================================================== The reason this is happening is unloading meson-dw-hdmi will cause the component API to take down the aggregate device, which in turn will cause all devres-managed memory to be freed, including the struct dw_hdmi allocated in dw_hdmi_probe. This struct embeds a struct drm_bridge that is added at the end of the function, and which is later on picked up in meson_encoder_hdmi_init. However, when attaching the bridge to the encoder created in meson_encoder_hdmi_init, it's linked to the encoder's bridge chain, from where it never leaves, even after devres_release_group is called when the driver's components are unbound and the embedding structure freed. Then, when calling drm_dev_put in the aggregate driver's unbind function, drm_bridge_detach is called for every single bridge linked to the encoder, including the one whose memory had already been deallocated. Fix by calling component_unbind_all after drm_dev_put. Signed-off-by: Adrián Larumbe Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20220919010940.419893-2-adrian.larumbe@collabora.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index a56607501d36..56c7daeb116a 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -387,9 +387,9 @@ static void meson_drv_unbind(struct device *dev) drm_dev_unregister(drm); drm_kms_helper_poll_fini(drm); drm_atomic_helper_shutdown(drm); - component_unbind_all(dev, drm); free_irq(priv->vsync_irq, drm); drm_dev_put(drm); + component_unbind_all(dev, drm); if (priv->afbcd.ops) priv->afbcd.ops->exit(priv); From 587c7da877219e6185217bf64418e62e114dab1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= Date: Mon, 19 Sep 2022 02:09:39 +0100 Subject: [PATCH 459/610] drm/meson: explicitly remove aggregate driver at module unload time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 8616f2a0589a80e08434212324250eb22f6a66ce ] Because component_master_del wasn't being called when unloading the meson_drm module, the aggregate device would linger forever in the global aggregate_devices list. That means when unloading and reloading the meson_dw_hdmi module, component_add would call into try_to_bring_up_aggregate_device and find the unbound meson_drm aggregate device. This would in turn dereference some of the aggregate_device's struct entries which point to memory automatically freed by the devres API when unbinding the aggregate device from meson_drv_unbind, and trigger an use-after-free bug: [ +0.000014] ============================================================= [ +0.000007] BUG: KASAN: use-after-free in find_components+0x468/0x500 [ +0.000017] Read of size 8 at addr ffff000006731688 by task modprobe/2536 [ +0.000018] CPU: 4 PID: 2536 Comm: modprobe Tainted: G C O 5.19.0-rc6-lrmbkasan+ #1 [ +0.000010] Hardware name: Hardkernel ODROID-N2Plus (DT) [ +0.000008] Call trace: [ +0.000005] dump_backtrace+0x1ec/0x280 [ +0.000011] show_stack+0x24/0x80 [ +0.000007] dump_stack_lvl+0x98/0xd4 [ +0.000010] print_address_description.constprop.0+0x80/0x520 [ +0.000011] print_report+0x128/0x260 [ +0.000007] kasan_report+0xb8/0xfc [ +0.000007] __asan_report_load8_noabort+0x3c/0x50 [ +0.000009] find_components+0x468/0x500 [ +0.000008] try_to_bring_up_aggregate_device+0x64/0x390 [ +0.000009] __component_add+0x1dc/0x49c [ +0.000009] component_add+0x20/0x30 [ +0.000008] meson_dw_hdmi_probe+0x28/0x34 [meson_dw_hdmi] [ +0.000013] platform_probe+0xd0/0x220 [ +0.000008] really_probe+0x3ac/0xa80 [ +0.000008] __driver_probe_device+0x1f8/0x400 [ +0.000008] driver_probe_device+0x68/0x1b0 [ +0.000008] __driver_attach+0x20c/0x480 [ +0.000009] bus_for_each_dev+0x114/0x1b0 [ +0.000007] driver_attach+0x48/0x64 [ +0.000009] bus_add_driver+0x390/0x564 [ +0.000007] driver_register+0x1a8/0x3e4 [ +0.000009] __platform_driver_register+0x6c/0x94 [ +0.000007] meson_dw_hdmi_platform_driver_init+0x30/0x1000 [meson_dw_hdmi] [ +0.000014] do_one_initcall+0xc4/0x2b0 [ +0.000008] do_init_module+0x154/0x570 [ +0.000010] load_module+0x1a78/0x1ea4 [ +0.000008] __do_sys_init_module+0x184/0x1cc [ +0.000008] __arm64_sys_init_module+0x78/0xb0 [ +0.000008] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000009] do_el0_svc+0x50/0x70 [ +0.000008] el0_svc+0x68/0x1a0 [ +0.000009] el0t_64_sync_handler+0x11c/0x150 [ +0.000009] el0t_64_sync+0x18c/0x190 [ +0.000014] Allocated by task 902: [ +0.000007] kasan_save_stack+0x2c/0x5c [ +0.000009] __kasan_kmalloc+0x90/0xd0 [ +0.000007] __kmalloc_node+0x240/0x580 [ +0.000010] memcg_alloc_slab_cgroups+0xa4/0x1ac [ +0.000010] memcg_slab_post_alloc_hook+0xbc/0x4c0 [ +0.000008] kmem_cache_alloc_node+0x1d0/0x490 [ +0.000009] __alloc_skb+0x1d4/0x310 [ +0.000010] alloc_skb_with_frags+0x8c/0x620 [ +0.000008] sock_alloc_send_pskb+0x5ac/0x6d0 [ +0.000010] unix_dgram_sendmsg+0x2e0/0x12f0 [ +0.000010] sock_sendmsg+0xcc/0x110 [ +0.000007] sock_write_iter+0x1d0/0x304 [ +0.000008] new_sync_write+0x364/0x460 [ +0.000007] vfs_write+0x420/0x5ac [ +0.000008] ksys_write+0x19c/0x1f0 [ +0.000008] __arm64_sys_write+0x78/0xb0 [ +0.000007] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0x1a8/0x260 [ +0.000009] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000008] el0t_64_sync_handler+0x11c/0x150 [ +0.000008] el0t_64_sync+0x18c/0x190 [ +0.000013] Freed by task 2509: [ +0.000008] kasan_save_stack+0x2c/0x5c [ +0.000007] kasan_set_track+0x2c/0x40 [ +0.000008] kasan_set_free_info+0x28/0x50 [ +0.000008] ____kasan_slab_free+0x128/0x1d4 [ +0.000008] __kasan_slab_free+0x18/0x24 [ +0.000007] slab_free_freelist_hook+0x108/0x230 [ +0.000010] kfree+0x110/0x35c [ +0.000008] release_nodes+0xf0/0x16c [ +0.000008] devres_release_all+0xfc/0x180 [ +0.000008] device_unbind_cleanup+0x24/0x164 [ +0.000008] device_release_driver_internal+0x3e8/0x5b0 [ +0.000010] driver_detach+0xac/0x1b0 [ +0.000008] bus_remove_driver+0x158/0x29c [ +0.000008] driver_unregister+0x70/0xb0 [ +0.000009] platform_driver_unregister+0x20/0x2c [ +0.000007] 0xffff800003722d98 [ +0.000012] __do_sys_delete_module+0x288/0x400 [ +0.000009] __arm64_sys_delete_module+0x5c/0x80 [ +0.000008] invoke_syscall+0x74/0x260 [ +0.000008] el0_svc_common.constprop.0+0xcc/0x260 [ +0.000008] do_el0_svc+0x50/0x70 [ +0.000007] el0_svc+0x68/0x1a0 [ +0.000008] el0t_64_sync_handler+0x11c/0x150 [ +0.000009] el0t_64_sync+0x18c/0x190 [ +0.000013] Last potentially related work creation: [ +0.000007] kasan_save_stack+0x2c/0x5c [ +0.000007] __kasan_record_aux_stack+0xb8/0xf0 [ +0.000009] kasan_record_aux_stack_noalloc+0x14/0x20 [ +0.000008] insert_work+0x54/0x290 [ +0.000009] __queue_work+0x48c/0xd24 [ +0.000008] queue_work_on+0x90/0x11c [ +0.000008] call_usermodehelper_exec+0x188/0x404 [ +0.000010] kobject_uevent_env+0x5a8/0x794 [ +0.000010] kobject_uevent+0x14/0x20 [ +0.000008] driver_register+0x230/0x3e4 [ +0.000009] __platform_driver_register+0x6c/0x94 [ +0.000007] gxbb_driver_init+0x28/0x34 [ +0.000010] do_one_initcall+0xc4/0x2b0 [ +0.000008] do_initcalls+0x20c/0x24c [ +0.000010] kernel_init_freeable+0x22c/0x278 [ +0.000009] kernel_init+0x3c/0x170 [ +0.000008] ret_from_fork+0x10/0x20 [ +0.000013] The buggy address belongs to the object at ffff000006731600 which belongs to the cache kmalloc-256 of size 256 [ +0.000009] The buggy address is located 136 bytes inside of 256-byte region [ffff000006731600, ffff000006731700) [ +0.000015] The buggy address belongs to the physical page: [ +0.000008] page:fffffc000019cc00 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff000006730a00 pfn:0x6730 [ +0.000011] head:fffffc000019cc00 order:2 compound_mapcount:0 compound_pincount:0 [ +0.000008] flags: 0xffff00000010200(slab|head|node=0|zone=0|lastcpupid=0xffff) [ +0.000016] raw: 0ffff00000010200 fffffc00000c3d08 fffffc0000ef2b08 ffff000000002680 [ +0.000009] raw: ffff000006730a00 0000000000150014 00000001ffffffff 0000000000000000 [ +0.000006] page dumped because: kasan: bad access detected [ +0.000011] Memory state around the buggy address: [ +0.000007] ffff000006731580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ +0.000007] ffff000006731600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] >ffff000006731680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ +0.000007] ^ [ +0.000006] ffff000006731700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ +0.000007] ffff000006731780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ +0.000006] ================================================================== Fix by adding 'remove' driver callback for meson-drm, and explicitly deleting the aggregate device. Signed-off-by: Adrián Larumbe Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20220919010940.419893-3-adrian.larumbe@collabora.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/meson/meson_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 56c7daeb116a..6e37de4fcb46 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -520,6 +520,13 @@ static int meson_drv_probe(struct platform_device *pdev) return 0; }; +static int meson_drv_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &meson_drv_master_ops); + + return 0; +} + static struct meson_drm_match_data meson_drm_gxbb_data = { .compat = VPU_COMPATIBLE_GXBB, }; @@ -557,6 +564,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = { static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, + .remove = meson_drv_remove, .shutdown = meson_drv_shutdown, .driver = { .name = "meson-drm", From 668806a8268b175d806288caf6779f132ac45329 Mon Sep 17 00:00:00 2001 From: Richard Acayan Date: Thu, 22 Sep 2022 21:43:22 -0400 Subject: [PATCH 460/610] mmc: sdhci-msm: add compatible string check for sdm670 [ Upstream commit 4de95950d970c71a9e82a24573bb7a44fd95baa1 ] The Snapdragon 670 has the same quirk as Snapdragon 845 (needing to restore the dll config). Add a compatible string check to detect the need for this. Signed-off-by: Richard Acayan Reviewed-by: Bhupesh Sharma Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220923014322.33620-3-mailingradian@gmail.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci-msm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index ff9f5b63c337..83d38e44fc25 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2437,6 +2437,7 @@ static const struct sdhci_msm_variant_info sdm845_sdhci_var = { static const struct of_device_id sdhci_msm_dt_match[] = { {.compatible = "qcom,sdhci-msm-v4", .data = &sdhci_msm_mci_var}, {.compatible = "qcom,sdhci-msm-v5", .data = &sdhci_msm_v5_var}, + {.compatible = "qcom,sdm670-sdhci", .data = &sdm845_sdhci_var}, {.compatible = "qcom,sdm845-sdhci", .data = &sdm845_sdhci_var}, {.compatible = "qcom,sc7180-sdhci", .data = &sdm845_sdhci_var}, {}, From 88fd06740659c69ab69dd5eba76a41de6cb9d6cf Mon Sep 17 00:00:00 2001 From: Khaled Almahallawy Date: Thu, 15 Sep 2022 22:49:00 -0700 Subject: [PATCH 461/610] drm/dp: Don't rewrite link config when setting phy test pattern [ Upstream commit 7b4d8db657192066bc6f1f6635d348413dac1e18 ] The sequence for Source DP PHY CTS automation is [2][1]: 1- Emulate successful Link Training(LT) 2- Short HPD and change link rates and number of lanes by LT. (This is same flow for Link Layer CTS) 3- Short HPD and change PHY test pattern and swing/pre-emphasis levels (This step should not trigger LT) The problem is with DP PHY compliance setup as follow: [DPTX + on board LTTPR]------Main Link--->[Scope] ^ | | | | | ----------Aux Ch------>[Aux Emulator] At step 3, before writing TRAINING_LANEx_SET/LINK_QUAL_PATTERN_SET to declare the pattern/swing requested by scope, we write link config in LINK_BW_SET/LANE_COUNT_SET on a port that has LTTPR. As LTTPR snoops aux transaction, LINK_BW_SET/LANE_COUNT_SET writes indicate a LT will start [Check DP 2.0 E11 -Sec 3.6.8.2 & 3.6.8.6.3], and LTTPR will reset the link and stop sending DP signals to DPTX/Scope causing the measurements to fail. Note that step 3 will not trigger LT and DP link will never recovered by the Aux Emulator/Scope. The reset of link can be tested with a monitor connected to LTTPR port simply by writing to LINK_BW_SET or LANE_COUNT_SET as follow igt/tools/dpcd_reg write --offset=0x100 --value 0x14 --device=2 OR printf '\x14' | sudo dd of=/dev/drm_dp_aux2 bs=1 count=1 conv=notrunc seek=$((0x100)) This single aux write causes the screen to blank, sending short HPD to DPTX, setting LINK_STATUS_UPDATE = 1 in DPCD 0x204, and triggering LT. As stated in [1]: "Before any TX electrical testing can be performed, the link between a DPTX and DPRX (in this case, a piece of test equipment), including all LTTPRs within the path, shall be trained as defined in this Standard." In addition, changing Phy pattern/Swing/Pre-emphasis (Step 3) uses the same link rate and lane count applied on step 2, so no need to redo LT. The fix is to not rewrite link config in step 3, and just writes TRAINING_LANEx_SET and LINK_QUAL_PATTERN_SET [1]: DP 2.0 E11 - 3.6.11.1 LTTPR DPTX_PHY Electrical Compliance [2]: Configuring UnigrafDPTC Controller - Automation Test Sequence https://www.keysight.com/us/en/assets/9922-01244/help-files/ D9040DPPC-DisplayPort-Test-Software-Online-Help-latest.chm Cc: Imre Deak Cc: Jani Nikula Cc: Or Cochvi Signed-off-by: Khaled Almahallawy Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20220916054900.415804-1-khaled.almahallawy@intel.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_dp_helper.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 7bb24523a749..b8815e7f5832 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -2376,17 +2376,8 @@ int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux, struct drm_dp_phy_test_params *data, u8 dp_rev) { int err, i; - u8 link_config[2]; u8 test_pattern; - link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate); - link_config[1] = data->num_lanes; - if (data->enhanced_frame_cap) - link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2); - if (err < 0) - return err; - test_pattern = data->phy_pattern; if (dp_rev < 0x12) { test_pattern = (test_pattern << 2) & From 0f90671ff93fa2cbfcec4297cfede9bf7da824ce Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Fri, 9 Sep 2022 18:07:59 -0400 Subject: [PATCH 462/610] drm/amd/display: Remove interface for periodic interrupt 1 [ Upstream commit 97d8d6f075bd8f988589be02b91f6fa644d0b0b8 ] [why] Only a single VLINE interrupt is available so interface should not expose the second one which is used by DMU firmware. [how] Remove references to periodic_interrupt1 and VLINE1 from DC interfaces. Reviewed-by: Jaehyun Chung Acked-by: Jasdeep Dhillon Signed-off-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/display/dc/core/dc.c | 16 +++------ drivers/gpu/drm/amd/display/dc/dc_stream.h | 6 ++-- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 35 ++++++------------- .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 3 +- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 8 +---- 5 files changed, 18 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 1bde9d4e82d4..6c9378208127 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2462,11 +2462,8 @@ static void copy_stream_update_to_stream(struct dc *dc, if (update->abm_level) stream->abm_level = *update->abm_level; - if (update->periodic_interrupt0) - stream->periodic_interrupt0 = *update->periodic_interrupt0; - - if (update->periodic_interrupt1) - stream->periodic_interrupt1 = *update->periodic_interrupt1; + if (update->periodic_interrupt) + stream->periodic_interrupt = *update->periodic_interrupt; if (update->gamut_remap) stream->gamut_remap_matrix = *update->gamut_remap; @@ -2550,13 +2547,8 @@ static void commit_planes_do_stream_update(struct dc *dc, if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) { - if (stream_update->periodic_interrupt0 && - dc->hwss.setup_periodic_interrupt) - dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE0); - - if (stream_update->periodic_interrupt1 && - dc->hwss.setup_periodic_interrupt) - dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE1); + if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt) + dc->hwss.setup_periodic_interrupt(dc, pipe_ctx); if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || stream_update->vrr_infopacket || diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index b8ebc1f09538..7644f0e747d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -193,8 +193,7 @@ struct dc_stream_state { /* DMCU info */ unsigned int abm_level; - struct periodic_interrupt_config periodic_interrupt0; - struct periodic_interrupt_config periodic_interrupt1; + struct periodic_interrupt_config periodic_interrupt; /* from core_stream struct */ struct dc_context *ctx; @@ -260,8 +259,7 @@ struct dc_stream_update { struct dc_info_packet *hdr_static_metadata; unsigned int *abm_level; - struct periodic_interrupt_config *periodic_interrupt0; - struct periodic_interrupt_config *periodic_interrupt1; + struct periodic_interrupt_config *periodic_interrupt; struct dc_info_packet *vrr_infopacket; struct dc_info_packet *vsc_infopacket; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 93f31e4aeecb..91ab4dbbe1a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -3517,7 +3517,7 @@ void dcn10_calc_vupdate_position( { const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing; int vline_int_offset_from_vupdate = - pipe_ctx->stream->periodic_interrupt0.lines_offset; + pipe_ctx->stream->periodic_interrupt.lines_offset; int vupdate_offset_from_vsync = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); int start_position; @@ -3542,18 +3542,10 @@ void dcn10_calc_vupdate_position( static void dcn10_cal_vline_position( struct dc *dc, struct pipe_ctx *pipe_ctx, - enum vline_select vline, uint32_t *start_line, uint32_t *end_line) { - enum vertical_interrupt_ref_point ref_point = INVALID_POINT; - - if (vline == VLINE0) - ref_point = pipe_ctx->stream->periodic_interrupt0.ref_point; - else if (vline == VLINE1) - ref_point = pipe_ctx->stream->periodic_interrupt1.ref_point; - - switch (ref_point) { + switch (pipe_ctx->stream->periodic_interrupt.ref_point) { case START_V_UPDATE: dcn10_calc_vupdate_position( dc, @@ -3562,7 +3554,9 @@ static void dcn10_cal_vline_position( end_line); break; case START_V_SYNC: - // Suppose to do nothing because vsync is 0; + // vsync is line 0 so start_line is just the requested line offset + *start_line = pipe_ctx->stream->periodic_interrupt.lines_offset; + *end_line = *start_line + 2; break; default: ASSERT(0); @@ -3572,24 +3566,15 @@ static void dcn10_cal_vline_position( void dcn10_setup_periodic_interrupt( struct dc *dc, - struct pipe_ctx *pipe_ctx, - enum vline_select vline) + struct pipe_ctx *pipe_ctx) { struct timing_generator *tg = pipe_ctx->stream_res.tg; + uint32_t start_line = 0; + uint32_t end_line = 0; - if (vline == VLINE0) { - uint32_t start_line = 0; - uint32_t end_line = 0; + dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line); - dcn10_cal_vline_position(dc, pipe_ctx, vline, &start_line, &end_line); - - tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line); - - } else if (vline == VLINE1) { - pipe_ctx->stream_res.tg->funcs->setup_vertical_interrupt1( - tg, - pipe_ctx->stream->periodic_interrupt1.lines_offset); - } + tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line); } void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index 9ae07c77fdc0..0ef7bf7ddb75 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -175,8 +175,7 @@ void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx); void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx); void dcn10_setup_periodic_interrupt( struct dc *dc, - struct pipe_ctx *pipe_ctx, - enum vline_select vline); + struct pipe_ctx *pipe_ctx); enum dc_status dcn10_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index ad5f2adcc40d..c8427d738c87 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -32,11 +32,6 @@ #include "inc/hw/link_encoder.h" #include "core_status.h" -enum vline_select { - VLINE0, - VLINE1 -}; - struct pipe_ctx; struct dc_state; struct dc_stream_status; @@ -115,8 +110,7 @@ struct hw_sequencer_funcs { int group_index, int group_size, struct pipe_ctx *grouped_pipes[]); void (*setup_periodic_interrupt)(struct dc *dc, - struct pipe_ctx *pipe_ctx, - enum vline_select vline); + struct pipe_ctx *pipe_ctx); void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes, struct dc_crtc_timing_adjust adjust); void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx, From 9361ba779152a664a7c47330ed7dac8e042772f2 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Mon, 25 Jul 2022 18:16:22 +0800 Subject: [PATCH 463/610] ARM: dts: imx7d-sdb: config the max pressure for tsc2046 [ Upstream commit e7c4ebe2f9cd68588eb24ba4ed122e696e2d5272 ] Use the general touchscreen method to config the max pressure for touch tsc2046(data sheet suggest 8 bit pressure), otherwise, for ABS_PRESSURE, when config the same max and min value, weston will meet the following issue, [17:19:39.183] event1 - ADS7846 Touchscreen: is tagged by udev as: Touchscreen [17:19:39.183] event1 - ADS7846 Touchscreen: kernel bug: device has min == max on ABS_PRESSURE [17:19:39.183] event1 - ADS7846 Touchscreen: was rejected [17:19:39.183] event1 - not using input device '/dev/input/event1' This will then cause the APP weston-touch-calibrator can't list touch devices. root@imx6ul7d:~# weston-touch-calibrator could not load cursor 'dnd-move' could not load cursor 'dnd-copy' could not load cursor 'dnd-none' No devices listed. And accroding to binding Doc, "ti,x-max", "ti,y-max", "ti,pressure-max" belong to the deprecated properties, so remove them. Also for "ti,x-min", "ti,y-min", "ti,x-plate-ohms", the value set in dts equal to the default value in driver, so are redundant, also remove here. Signed-off-by: Haibo Chen Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx7d-sdb.dts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index e5f1bdbe7992..4e1a6cde90fe 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -206,12 +206,7 @@ interrupt-parent = <&gpio2>; interrupts = <29 0>; pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; - ti,x-min = /bits/ 16 <0>; - ti,x-max = /bits/ 16 <0>; - ti,y-min = /bits/ 16 <0>; - ti,y-max = /bits/ 16 <0>; - ti,pressure-max = /bits/ 16 <0>; - ti,x-plate-ohms = /bits/ 16 <400>; + touchscreen-max-pressure = <255>; wakeup-source; }; }; From 19fe40c5185d13c8a33278b0a0be8b6bd58eb713 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 26 Aug 2022 07:53:31 +0200 Subject: [PATCH 464/610] ARM: dts: imx6q: add missing properties for sram [ Upstream commit b11d083c5dcec7c42fe982c854706d404ddd3a5f ] All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6q.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 9caba4529c71..a8069e0a8fe8 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -163,6 +163,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x40000>; + ranges = <0 0x00900000 0x40000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; From 47666b9a11a139e9f555a7d8beb1901cd8e3a0db Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 26 Aug 2022 07:53:32 +0200 Subject: [PATCH 465/610] ARM: dts: imx6dl: add missing properties for sram [ Upstream commit f5848b95633d598bacf0500e0108dc5961af88c0 ] All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6dl.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index fdd81fdc3f35..cd3183c36488 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -84,6 +84,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; From 8c24dc621bb791f2cf12e0f2f4a4a521224621ad Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 26 Aug 2022 07:53:33 +0200 Subject: [PATCH 466/610] ARM: dts: imx6qp: add missing properties for sram [ Upstream commit 088fe5237435ee2f7ed4450519b2ef58b94c832f ] All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@940000: '#address-cells' is a required property sram@940000: '#size-cells' is a required property sram@940000: 'ranges' is a required property Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6qp.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi index b310f13a53f2..4d23c92aa8a6 100644 --- a/arch/arm/boot/dts/imx6qp.dtsi +++ b/arch/arm/boot/dts/imx6qp.dtsi @@ -9,12 +9,18 @@ ocram2: sram@940000 { compatible = "mmio-sram"; reg = <0x00940000 0x20000>; + ranges = <0 0x00940000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; ocram3: sram@960000 { compatible = "mmio-sram"; reg = <0x00960000 0x20000>; + ranges = <0 0x00960000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; From 6a12e1e23cb1abc2be2e69f6690faaabcb7da25e Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 26 Aug 2022 07:53:34 +0200 Subject: [PATCH 467/610] ARM: dts: imx6sl: add missing properties for sram [ Upstream commit 60c9213a1d9941a8b33db570796c3f9be8984974 ] All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6sl.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 997b96c1c47b..5b4dfc62030e 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -117,6 +117,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6SL_CLK_OCRAM>; }; From 602813650cbce2fbae0de7f870dbe20c017b06e3 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 26 Aug 2022 07:53:35 +0200 Subject: [PATCH 468/610] ARM: dts: imx6sll: add missing properties for sram [ Upstream commit 7492a83ed9b7a151e2dd11d64b06da7a7f0fa7f9 ] All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6sll.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi index 04f8d637a501..eecb2f68a1c3 100644 --- a/arch/arm/boot/dts/imx6sll.dtsi +++ b/arch/arm/boot/dts/imx6sll.dtsi @@ -117,6 +117,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; }; intc: interrupt-controller@a01000 { From 35365417333d49517d1bc45d8136db648ef0529d Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 26 Aug 2022 07:53:36 +0200 Subject: [PATCH 469/610] ARM: dts: imx6sx: add missing properties for sram [ Upstream commit 415432c008b2bce8138841356ba444631cabaa50 ] All 3 properties are required by sram.yaml. Fixes the dtbs_check warning: sram@900000: '#address-cells' is a required property sram@900000: '#size-cells' is a required property sram@900000: 'ranges' is a required property Signed-off-by: Alexander Stein Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6sx.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 8516730778df..8bef5440278b 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -164,12 +164,18 @@ ocram_s: sram@8f8000 { compatible = "mmio-sram"; reg = <0x008f8000 0x4000>; + ranges = <0 0x008f8000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6SX_CLK_OCRAM_S>; }; ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6SX_CLK_OCRAM>; }; From 82046b6a84e076cae683275ea19ed91a42168604 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 29 Aug 2022 17:06:56 +0100 Subject: [PATCH 470/610] kselftest/arm64: Fix validatation termination record after EXTRA_CONTEXT [ Upstream commit 5c152c2f66f9368394b89ac90dc7483476ef7b88 ] When arm64 signal context data overflows the base struct sigcontext it gets placed in an extra buffer pointed to by a record of type EXTRA_CONTEXT in the base struct sigcontext which is required to be the last record in the base struct sigframe. The current validation code attempts to check this by using GET_RESV_NEXT_HEAD() to step forward from the current record to the next but that is a macro which assumes it is being provided with a struct _aarch64_ctx and uses the size there to skip forward to the next record. Instead validate_extra_context() passes it a struct extra_context which has a separate size field. This compiles but results in us trying to validate a termination record in completely the wrong place, at best failing validation and at worst just segfaulting. Fix this by passing the struct _aarch64_ctx we meant to into the macro. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220829160703.874492-4-broonie@kernel.org Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- tools/testing/selftests/arm64/signal/testcases/testcases.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c index 8c2a57fc2f9c..341b3d5200bd 100644 --- a/tools/testing/selftests/arm64/signal/testcases/testcases.c +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c @@ -33,7 +33,7 @@ bool validate_extra_context(struct extra_context *extra, char **err) return false; fprintf(stderr, "Validating EXTRA...\n"); - term = GET_RESV_NEXT_HEAD(extra); + term = GET_RESV_NEXT_HEAD(&extra->head); if (!term || term->magic || term->size) { *err = "Missing terminator after EXTRA context"; return false; From d3c6d5be46de5824f154004808d3ef40929d9441 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Fri, 2 Sep 2022 10:42:13 +0200 Subject: [PATCH 471/610] arm64: dts: imx8mq-librem5: Add bq25895 as max17055's power supply [ Upstream commit 6effe295e1a87408033c29dbcea9d5a5c8b937d5 ] This allows the userspace to notice that there's not enough current provided to charge the battery, and also fixes issues with 0% SOC values being considered invalid. Signed-off-by: Sebastian Krzyszkowiak Signed-off-by: Martin Kepplinger Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi index 460ef0d86540..c86cd20d4e70 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi @@ -967,6 +967,7 @@ interrupts = <20 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gauge>; + power-supplies = <&bq25895>; maxim,over-heat-temp = <700>; maxim,over-volt = <4500>; maxim,rsns-microohm = <5000>; From f3857dd7c03a3962da8b0816df94655a17f0c0df Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 1 Aug 2022 09:35:57 +0800 Subject: [PATCH 472/610] btrfs: dump extra info if one free space cache has more bitmaps than it should [ Upstream commit 62cd9d4474282a1eb84f945955c56cbfc42e1ffe ] There is an internal report on hitting the following ASSERT() in recalculate_thresholds(): ASSERT(ctl->total_bitmaps <= max_bitmaps); Above @max_bitmaps is calculated using the following variables: - bytes_per_bg 8 * 4096 * 4096 (128M) for x86_64/x86. - block_group->length The length of the block group. @max_bitmaps is the rounded up value of block_group->length / 128M. Normally one free space cache should not have more bitmaps than above value, but when it happens the ASSERT() can be triggered if CONFIG_BTRFS_ASSERT is also enabled. But the ASSERT() itself won't provide enough info to know which is going wrong. Is the bg too small thus it only allows one bitmap? Or is there something else wrong? So although I haven't found extra reports or crash dump to do further investigation, add the extra info to make it more helpful to debug. Reviewed-by: Anand Jain Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/free-space-cache.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index da0eee7c9e5f..529907ea3825 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -672,6 +672,12 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) max_bitmaps = max_t(u64, max_bitmaps, 1); + if (ctl->total_bitmaps > max_bitmaps) + btrfs_err(block_group->fs_info, +"invalid free space control: bg start=%llu len=%llu total_bitmaps=%u unit=%u max_bitmaps=%llu bytes_per_bg=%llu", + block_group->start, block_group->length, + ctl->total_bitmaps, ctl->unit, max_bitmaps, + bytes_per_bg); ASSERT(ctl->total_bitmaps <= max_bitmaps); /* From 39a07058c7628dc6dbdde0829be649ef4e678599 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 2 Aug 2022 14:53:03 +0800 Subject: [PATCH 473/610] btrfs: scrub: try to fix super block errors [ Upstream commit f9eab5f0bba76742af654f33d517bf62a0db8f12 ] [BUG] The following script shows that, although scrub can detect super block errors, it never tries to fix it: mkfs.btrfs -f -d raid1 -m raid1 $dev1 $dev2 xfs_io -c "pwrite 67108864 4k" $dev2 mount $dev1 $mnt btrfs scrub start -B $dev2 btrfs scrub start -Br $dev2 umount $mnt The first scrub reports the super error correctly: scrub done for f3289218-abd3-41ac-a630-202f766c0859 Scrub started: Tue Aug 2 14:44:11 2022 Status: finished Duration: 0:00:00 Total to scrub: 1.26GiB Rate: 0.00B/s Error summary: super=1 Corrected: 0 Uncorrectable: 0 Unverified: 0 But the second read-only scrub still reports the same super error: Scrub started: Tue Aug 2 14:44:11 2022 Status: finished Duration: 0:00:00 Total to scrub: 1.26GiB Rate: 0.00B/s Error summary: super=1 Corrected: 0 Uncorrectable: 0 Unverified: 0 [CAUSE] The comments already shows that super block can be easily fixed by committing a transaction: /* * If we find an error in a super block, we just report it. * They will get written with the next transaction commit * anyway */ But the truth is, such assumption is not always true, and since scrub should try to repair every error it found (except for read-only scrub), we should really actively commit a transaction to fix this. [FIX] Just commit a transaction if we found any super block errors, after everything else is done. We cannot do this just after scrub_supers(), as btrfs_commit_transaction() will try to pause and wait for the running scrub, thus we can not call it with scrub_lock hold. Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/scrub.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 0785d9d645fc..ca8d6979c788 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -4072,6 +4072,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, int ret; struct btrfs_device *dev; unsigned int nofs_flag; + bool need_commit = false; if (btrfs_fs_closing(fs_info)) return -EAGAIN; @@ -4177,6 +4178,12 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, */ nofs_flag = memalloc_nofs_save(); if (!is_dev_replace) { + u64 old_super_errors; + + spin_lock(&sctx->stat_lock); + old_super_errors = sctx->stat.super_errors; + spin_unlock(&sctx->stat_lock); + btrfs_info(fs_info, "scrub: started on devid %llu", devid); /* * by holding device list mutex, we can @@ -4185,6 +4192,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, mutex_lock(&fs_info->fs_devices->device_list_mutex); ret = scrub_supers(sctx, dev); mutex_unlock(&fs_info->fs_devices->device_list_mutex); + + spin_lock(&sctx->stat_lock); + /* + * Super block errors found, but we can not commit transaction + * at current context, since btrfs_commit_transaction() needs + * to pause the current running scrub (hold by ourselves). + */ + if (sctx->stat.super_errors > old_super_errors && !sctx->readonly) + need_commit = true; + spin_unlock(&sctx->stat_lock); } if (!ret) @@ -4211,6 +4228,25 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, scrub_workers_put(fs_info); scrub_put_ctx(sctx); + /* + * We found some super block errors before, now try to force a + * transaction commit, as scrub has finished. + */ + if (need_commit) { + struct btrfs_trans_handle *trans; + + trans = btrfs_start_transaction(fs_info->tree_root, 0); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + btrfs_err(fs_info, + "scrub: failed to start transaction to fix super block errors: %d", ret); + return ret; + } + ret = btrfs_commit_transaction(trans); + if (ret < 0) + btrfs_err(fs_info, + "scrub: failed to commit transaction to fix super block errors: %d", ret); + } return ret; out: scrub_workers_put(fs_info); From 4a89c0befca795579a9fdf6dd7b64a5248233540 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Tue, 23 Aug 2022 17:28:20 +0200 Subject: [PATCH 474/610] btrfs: don't print information about space cache or tree every remount [ Upstream commit dbecac26630014d336a8e5ea67096ff18210fb9c ] btrfs currently prints information about space cache or free space tree being in use on every remount, regardless whether such remount actually enabled or disabled one of these features. This is actually unnecessary since providing remount options changing the state of these features will explicitly print the appropriate notice. Let's instead print such unconditional information just on an initial mount to avoid filling the kernel log when, for example, laptop-mode-tools remount the fs on some events. Signed-off-by: Maciej S. Szmigiero Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/super.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 969bf0724fdf..442fcd1b14a6 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -574,6 +574,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, int saved_compress_level; bool saved_compress_force; int no_compress = 0; + const bool remounting = test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state); if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); @@ -1065,10 +1066,12 @@ out: } if (!ret) ret = btrfs_check_mountopts_zoned(info); - if (!ret && btrfs_test_opt(info, SPACE_CACHE)) - btrfs_info(info, "disk space caching is enabled"); - if (!ret && btrfs_test_opt(info, FREE_SPACE_TREE)) - btrfs_info(info, "using free space tree"); + if (!ret && !remounting) { + if (btrfs_test_opt(info, SPACE_CACHE)) + btrfs_info(info, "disk space caching is enabled"); + if (btrfs_test_opt(info, FREE_SPACE_TREE)) + btrfs_info(info, "using free space tree"); + } return ret; } From 3680442cbaeedc582c40e28d644b23579f0e4274 Mon Sep 17 00:00:00 2001 From: Alex Sverdlin Date: Mon, 5 Sep 2022 16:26:59 +0100 Subject: [PATCH 475/610] ARM: 9242/1: kasan: Only map modules if CONFIG_KASAN_VMALLOC=n [ Upstream commit 823f606ab6b4759a1faf0388abcf4fb0776710d2 ] In case CONFIG_KASAN_VMALLOC=y kasan_populate_vmalloc() allocates the shadow pages dynamically. But even worse is that kasan_release_vmalloc() releases them, which is not compatible with create_mapping() of MODULES_VADDR..MODULES_END range: BUG: Bad page state in process kworker/9:1 pfn:2068b page:e5e06160 refcount:0 mapcount:0 mapping:00000000 index:0x0 flags: 0x1000(reserved) raw: 00001000 e5e06164 e5e06164 00000000 00000000 00000000 ffffffff 00000000 page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set bad because of flags: 0x1000(reserved) Modules linked in: ip_tables CPU: 9 PID: 154 Comm: kworker/9:1 Not tainted 5.4.188-... #1 Hardware name: LSI Axxia AXM55XX Workqueue: events do_free_init unwind_backtrace show_stack dump_stack bad_page free_pcp_prepare free_unref_page kasan_depopulate_vmalloc_pte __apply_to_page_range apply_to_existing_page_range kasan_release_vmalloc __purge_vmap_area_lazy _vm_unmap_aliases.part.0 __vunmap do_free_init process_one_work worker_thread kthread Reviewed-by: Linus Walleij Signed-off-by: Alexander Sverdlin Signed-off-by: Russell King (Oracle) Signed-off-by: Sasha Levin --- arch/arm/mm/kasan_init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c index 4b1619584b23..948ada4a2938 100644 --- a/arch/arm/mm/kasan_init.c +++ b/arch/arm/mm/kasan_init.c @@ -264,12 +264,17 @@ void __init kasan_init(void) /* * 1. The module global variables are in MODULES_VADDR ~ MODULES_END, - * so we need to map this area. + * so we need to map this area if CONFIG_KASAN_VMALLOC=n. With + * VMALLOC support KASAN will manage this region dynamically, + * refer to kasan_populate_vmalloc() and ARM's implementation of + * module_alloc(). * 2. PKMAP_BASE ~ PKMAP_BASE+PMD_SIZE's shadow and MODULES_VADDR * ~ MODULES_END's shadow is in the same PMD_SIZE, so we can't * use kasan_populate_zero_shadow. */ - create_mapping((void *)MODULES_VADDR, (void *)(PKMAP_BASE + PMD_SIZE)); + if (!IS_ENABLED(CONFIG_KASAN_VMALLOC) && IS_ENABLED(CONFIG_MODULES)) + create_mapping((void *)MODULES_VADDR, (void *)(MODULES_END)); + create_mapping((void *)PKMAP_BASE, (void *)(PKMAP_BASE + PMD_SIZE)); /* * KAsan may reuse the contents of kasan_early_shadow_pte directly, so From 0a07b13af04d0db7325018aaa83b5ffe864790c9 Mon Sep 17 00:00:00 2001 From: Ian Nam Date: Tue, 10 May 2022 12:31:54 +0530 Subject: [PATCH 476/610] clk: zynqmp: Fix stack-out-of-bounds in strncpy` [ Upstream commit dd80fb2dbf1cd8751efbe4e53e54056f56a9b115 ] "BUG: KASAN: stack-out-of-bounds in strncpy+0x30/0x68" Linux-ATF interface is using 16 bytes of SMC payload. In case clock name is longer than 15 bytes, string terminated NULL character will not be received by Linux. Add explicit NULL character at last byte to fix issues when clock name is longer. This fixes below bug reported by KASAN: ================================================================== BUG: KASAN: stack-out-of-bounds in strncpy+0x30/0x68 Read of size 1 at addr ffff0008c89a7410 by task swapper/0/1 CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.4.0-00396-g81ef9e7-dirty #3 Hardware name: Xilinx Versal vck190 Eval board revA (QSPI) (DT) Call trace: dump_backtrace+0x0/0x1e8 show_stack+0x14/0x20 dump_stack+0xd4/0x108 print_address_description.isra.0+0xbc/0x37c __kasan_report+0x144/0x198 kasan_report+0xc/0x18 __asan_load1+0x5c/0x68 strncpy+0x30/0x68 zynqmp_clock_probe+0x238/0x7b8 platform_drv_probe+0x6c/0xc8 really_probe+0x14c/0x418 driver_probe_device+0x74/0x130 __device_attach_driver+0xc4/0xe8 bus_for_each_drv+0xec/0x150 __device_attach+0x160/0x1d8 device_initial_probe+0x10/0x18 bus_probe_device+0xe0/0xf0 device_add+0x528/0x950 of_device_add+0x5c/0x80 of_platform_device_create_pdata+0x120/0x168 of_platform_bus_create+0x244/0x4e0 of_platform_populate+0x50/0xe8 zynqmp_firmware_probe+0x370/0x3a8 platform_drv_probe+0x6c/0xc8 really_probe+0x14c/0x418 driver_probe_device+0x74/0x130 device_driver_attach+0x94/0xa0 __driver_attach+0x70/0x108 bus_for_each_dev+0xe4/0x158 driver_attach+0x30/0x40 bus_add_driver+0x21c/0x2b8 driver_register+0xbc/0x1d0 __platform_driver_register+0x7c/0x88 zynqmp_firmware_driver_init+0x1c/0x24 do_one_initcall+0xa4/0x234 kernel_init_freeable+0x1b0/0x24c kernel_init+0x10/0x110 ret_from_fork+0x10/0x18 The buggy address belongs to the page: page:ffff0008f9be1c88 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 raw: 0008d00000000000 ffff0008f9be1c90 ffff0008f9be1c90 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff page dumped because: kasan: bad access detected addr ffff0008c89a7410 is located in stack of task swapper/0/1 at offset 112 in frame: zynqmp_clock_probe+0x0/0x7b8 this frame has 3 objects: [32, 44) 'response' [64, 80) 'ret_payload' [96, 112) 'name' Memory state around the buggy address: ffff0008c89a7300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff0008c89a7380: 00 00 00 00 f1 f1 f1 f1 00 04 f2 f2 00 00 f2 f2 >ffff0008c89a7400: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 ^ ffff0008c89a7480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff0008c89a7500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ================================================================== Signed-off-by: Ian Nam Signed-off-by: Shubhrajyoti Datta Link: https://lore.kernel.org/r/20220510070154.29528-3-shubhrajyoti.datta@xilinx.com Acked-by: Michal Simek Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/zynqmp/clkc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c index eb25303eefed..2c9da6623b84 100644 --- a/drivers/clk/zynqmp/clkc.c +++ b/drivers/clk/zynqmp/clkc.c @@ -710,6 +710,13 @@ static void zynqmp_get_clock_info(void) FIELD_PREP(CLK_ATTR_NODE_INDEX, i); zynqmp_pm_clock_get_name(clock[i].clk_id, &name); + + /* + * Terminate with NULL character in case name provided by firmware + * is longer and truncated due to size limit. + */ + name.name[sizeof(name.name) - 1] = '\0'; + if (!strcmp(name.name, RESERVED_CLK_NAME)) continue; strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN); From 6f21976095c1e92454ab030976f95f40d652351b Mon Sep 17 00:00:00 2001 From: Zheyu Ma Date: Thu, 28 Jul 2022 04:23:38 +0200 Subject: [PATCH 477/610] media: cx88: Fix a null-ptr-deref bug in buffer_prepare() [ Upstream commit 2b064d91440b33fba5b452f2d1b31f13ae911d71 ] When the driver calls cx88_risc_buffer() to prepare the buffer, the function call may fail, resulting in a empty buffer and null-ptr-deref later in buffer_queue(). The following log can reveal it: [ 41.822762] general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI [ 41.824488] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] [ 41.828027] RIP: 0010:buffer_queue+0xc2/0x500 [ 41.836311] Call Trace: [ 41.836945] __enqueue_in_driver+0x141/0x360 [ 41.837262] vb2_start_streaming+0x62/0x4a0 [ 41.838216] vb2_core_streamon+0x1da/0x2c0 [ 41.838516] __vb2_init_fileio+0x981/0xbc0 [ 41.839141] __vb2_perform_fileio+0xbf9/0x1120 [ 41.840072] vb2_fop_read+0x20e/0x400 [ 41.840346] v4l2_read+0x215/0x290 [ 41.840603] vfs_read+0x162/0x4c0 Fix this by checking the return value of cx88_risc_buffer() [hverkuil: fix coding style issues] Signed-off-by: Zheyu Ma Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/pci/cx88/cx88-vbi.c | 9 +++--- drivers/media/pci/cx88/cx88-video.c | 43 +++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index a075788c64d4..469aeaa725ad 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -144,11 +144,10 @@ static int buffer_prepare(struct vb2_buffer *vb) return -EINVAL; vb2_set_plane_payload(vb, 0, size); - cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, - 0, VBI_LINE_LENGTH * lines, - VBI_LINE_LENGTH, 0, - lines); - return 0; + return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, + 0, VBI_LINE_LENGTH * lines, + VBI_LINE_LENGTH, 0, + lines); } static void buffer_finish(struct vb2_buffer *vb) diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index c17ad9f7d822..99c55109c1e0 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -431,6 +431,7 @@ static int queue_setup(struct vb2_queue *q, static int buffer_prepare(struct vb2_buffer *vb) { + int ret; struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_core *core = dev->core; @@ -445,35 +446,35 @@ static int buffer_prepare(struct vb2_buffer *vb) switch (core->field) { case V4L2_FIELD_TOP: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, 0, UNSET, - buf->bpl, 0, core->height); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, 0, UNSET, + buf->bpl, 0, core->height); break; case V4L2_FIELD_BOTTOM: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, UNSET, 0, - buf->bpl, 0, core->height); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, UNSET, 0, + buf->bpl, 0, core->height); break; case V4L2_FIELD_SEQ_TB: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, - 0, buf->bpl * (core->height >> 1), - buf->bpl, 0, - core->height >> 1); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, + 0, buf->bpl * (core->height >> 1), + buf->bpl, 0, + core->height >> 1); break; case V4L2_FIELD_SEQ_BT: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, - buf->bpl * (core->height >> 1), 0, - buf->bpl, 0, - core->height >> 1); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, + buf->bpl * (core->height >> 1), 0, + buf->bpl, 0, + core->height >> 1); break; case V4L2_FIELD_INTERLACED: default: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, 0, buf->bpl, - buf->bpl, buf->bpl, - core->height >> 1); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, 0, buf->bpl, + buf->bpl, buf->bpl, + core->height >> 1); break; } dprintk(2, @@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb) buf, buf->vb.vb2_buf.index, __func__, core->width, core->height, dev->fmt->depth, dev->fmt->fourcc, (unsigned long)buf->risc.dma); - return 0; + return ret; } static void buffer_finish(struct vb2_buffer *vb) From 5c32cbf6ccea1625a0c2b92d6dcc34f529ba755c Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Tue, 16 Aug 2022 10:58:19 +0200 Subject: [PATCH 478/610] media: platform: fix some double free in meson-ge2d and mtk-jpeg and s5p-mfc [ Upstream commit c65c3f3a2cbf21ed429d9b9c725bdb5dc6abf4cf ] video_unregister_device will release device internally. There is no need to call video_device_release after video_unregister_device. Signed-off-by: Hangyu Hua Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/meson/ge2d/ge2d.c | 1 - drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 1 - drivers/media/platform/s5p-mfc/s5p_mfc.c | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/platform/meson/ge2d/ge2d.c b/drivers/media/platform/meson/ge2d/ge2d.c index a373dea9866b..a885cbc99e38 100644 --- a/drivers/media/platform/meson/ge2d/ge2d.c +++ b/drivers/media/platform/meson/ge2d/ge2d.c @@ -1032,7 +1032,6 @@ static int ge2d_remove(struct platform_device *pdev) video_unregister_device(ge2d->vfd); v4l2_m2m_release(ge2d->m2m_dev); - video_device_release(ge2d->vfd); v4l2_device_unregister(&ge2d->v4l2_dev); clk_disable_unprepare(ge2d->clk); diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index a89c7b206eef..470f8f167744 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -1457,7 +1457,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); video_unregister_device(jpeg->vdev); - video_device_release(jpeg->vdev); v4l2_m2m_release(jpeg->m2m_dev); v4l2_device_unregister(&jpeg->v4l2_dev); mtk_jpeg_clk_release(jpeg); diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index f336a9543273..4fc135d9f38b 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1406,6 +1406,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) /* Deinit MFC if probe had failed */ err_enc_reg: video_unregister_device(dev->vfd_dec); + dev->vfd_dec = NULL; err_dec_reg: video_device_release(dev->vfd_enc); err_enc_alloc: @@ -1451,8 +1452,6 @@ static int s5p_mfc_remove(struct platform_device *pdev) video_unregister_device(dev->vfd_enc); video_unregister_device(dev->vfd_dec); - video_device_release(dev->vfd_enc); - video_device_release(dev->vfd_dec); v4l2_device_unregister(&dev->v4l2_dev); s5p_mfc_unconfigure_dma_memory(dev); From 6bcd745c87a04c6a89f491ade86eebc9144561d1 Mon Sep 17 00:00:00 2001 From: Quanyang Wang Date: Fri, 26 Aug 2022 22:20:30 +0800 Subject: [PATCH 479/610] clk: zynqmp: pll: rectify rate rounding in zynqmp_pll_round_rate [ Upstream commit 30eaf02149ecc3c5815e45d27187bf09e925071d ] The function zynqmp_pll_round_rate is used to find a most appropriate PLL frequency which the hardware can generate according to the desired frequency. For example, if the desired frequency is 297MHz, considering the limited range from PS_PLL_VCO_MIN (1.5GHz) to PS_PLL_VCO_MAX (3.0GHz) of PLL, zynqmp_pll_round_rate should return 1.872GHz (297MHz * 5). There are two problems with the current code of zynqmp_pll_round_rate: 1) When the rate is below PS_PLL_VCO_MIN, it can't find a correct rate when the parameter "rate" is an integer multiple of *prate, in other words, if "f" is zero, zynqmp_pll_round_rate won't return a valid frequency which is from PS_PLL_VCO_MIN to PS_PLL_VCO_MAX. For example, *prate is 33MHz and the rate is 660MHz, zynqmp_pll_round_rate will not boost up rate and just return 660MHz, and this will cause clk_calc_new_rates failure since zynqmp_pll_round_rate returns an invalid rate out of its boundaries. 2) Even if the rate is higher than PS_PLL_VCO_MIN, there is still a risk that zynqmp_pll_round_rate returns an invalid rate because the function DIV_ROUND_CLOSEST makes some loss in the fractional part. If the parent clock *prate is 33333333Hz and we want to set the PLL rate to 1.5GHz, this function will return 1499999985Hz by using the formula below: value = *prate * DIV_ROUND_CLOSEST(rate, *prate)). This value is also invalid since it's slightly smaller than PS_PLL_VCO_MIN. because DIV_ROUND_CLOSEST makes some loss in the fractional part. Signed-off-by: Quanyang Wang Link: https://lore.kernel.org/r/20220826142030.213805-1-quanyang.wang@windriver.com Reviewed-by: Shubhrajyoti Datta Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/zynqmp/pll.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index 036e4ff64a2f..bc066f300345 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -102,26 +102,25 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { u32 fbdiv; - long rate_div, f; + u32 mult, div; - /* Enable the fractional mode if needed */ - rate_div = (rate * FRAC_DIV) / *prate; - f = rate_div % FRAC_DIV; - if (f) { - if (rate > PS_PLL_VCO_MAX) { - fbdiv = rate / PS_PLL_VCO_MAX; - rate = rate / (fbdiv + 1); - } - if (rate < PS_PLL_VCO_MIN) { - fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); - rate = rate * fbdiv; - } - return rate; + /* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */ + if (rate > PS_PLL_VCO_MAX) { + div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX); + rate = rate / div; + } + if (rate < PS_PLL_VCO_MIN) { + mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); + rate = rate * mult; } fbdiv = DIV_ROUND_CLOSEST(rate, *prate); - fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); - return *prate * fbdiv; + if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) { + fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); + rate = *prate * fbdiv; + } + + return rate; } /** From f002aa7c0ac5518a152ec24503c9f887031984a0 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Wed, 10 Aug 2022 15:27:34 -0700 Subject: [PATCH 480/610] usb: host: xhci-plat: suspend and resume clocks [ Upstream commit 8bd954c56197caf5e3a804d989094bc3fe6329aa ] Introduce XHCI_SUSPEND_RESUME_CLKS quirk as a means to suspend and resume clocks if the hardware is capable of doing so. We assume that clocks will be needed if the device may wake. Reviewed-by: Florian Fainelli Signed-off-by: Justin Chen Link: https://lore.kernel.org/r/1660170455-15781-2-git-send-email-justinpopo6@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-plat.c | 16 +++++++++++++++- drivers/usb/host/xhci.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index dc570ce4e831..2687662f26b6 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -447,7 +447,16 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev) * xhci_suspend() needs `do_wakeup` to know whether host is allowed * to do wakeup during suspend. */ - return xhci_suspend(xhci, device_may_wakeup(dev)); + ret = xhci_suspend(xhci, device_may_wakeup(dev)); + if (ret) + return ret; + + if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { + clk_disable_unprepare(xhci->clk); + clk_disable_unprepare(xhci->reg_clk); + } + + return 0; } static int __maybe_unused xhci_plat_resume(struct device *dev) @@ -456,6 +465,11 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ret; + if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { + clk_prepare_enable(xhci->clk); + clk_prepare_enable(xhci->reg_clk); + } + ret = xhci_priv_resume_quirk(hcd); if (ret) return ret; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 10a4230d95c3..3b39501f26ea 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1903,6 +1903,7 @@ struct xhci_hcd { #define XHCI_NO_SOFT_RETRY BIT_ULL(40) #define XHCI_BROKEN_D3COLD BIT_ULL(41) #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42) +#define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43) unsigned int num_active_eps; unsigned int limit_active_eps; From 518a2a1cc3612d115ebd81da02e470dcac90a34f Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Wed, 10 Aug 2022 15:27:35 -0700 Subject: [PATCH 481/610] usb: host: xhci-plat: suspend/resume clks for brcm [ Upstream commit c69400b09e471a3f1167adead55a808f0da6534a ] The xhci_plat_brcm xhci block can enter suspend with clock disabled to save power and re-enable them on resume. Make use of the XHCI_SUSPEND_RESUME_CLKS quirk to do so. Reviewed-by: Florian Fainelli Signed-off-by: Justin Chen Link: https://lore.kernel.org/r/1660170455-15781-3-git-send-email-justinpopo6@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-plat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 2687662f26b6..972a44b2a7f1 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -134,7 +134,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { }; static const struct xhci_plat_priv xhci_plat_brcm = { - .quirks = XHCI_RESET_ON_RESUME, + .quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS, }; static const struct of_device_id usb_xhci_of_match[] = { From d68da10b0cceb4177b653833e794b2923a4ffbd7 Mon Sep 17 00:00:00 2001 From: Vaishnav Achath Date: Tue, 2 Aug 2022 11:18:35 +0530 Subject: [PATCH 482/610] dmaengine: ti: k3-udma: Reset UDMA_CHAN_RT byte counters to prevent overflow [ Upstream commit 7c94dcfa8fcff2dba53915f1dabfee49a3df8b88 ] UDMA_CHAN_RT_*BCNT_REG stores the real-time channel bytecount statistics. These registers are 32-bit hardware counters and the driver uses these counters to monitor the operational progress status for a channel, when transferring more than 4GB of data it was observed that these counters overflow and completion calculation of a operation gets affected and the transfer hangs indefinitely. This commit adds changes to decrease the byte count for every complete transaction so that these registers never overflow and the proper byte count statistics is maintained for ongoing transaction by the RT counters. Earlier uc->bcnt used to maintain a count of the completed bytes at driver side, since the RT counters maintain the statistics of current transaction now, the maintenance of uc->bcnt is not necessary. Signed-off-by: Vaishnav Achath Acked-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220802054835.19482-1-vaishnav.a@ti.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/ti/k3-udma.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 041d8e32d630..75f2a0006c73 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -300,8 +300,6 @@ struct udma_chan { struct udma_tx_drain tx_drain; - u32 bcnt; /* number of bytes completed since the start of the channel */ - /* Channel configuration parameters */ struct udma_chan_config config; @@ -757,6 +755,20 @@ static void udma_reset_rings(struct udma_chan *uc) } } +static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val) +{ + if (uc->desc->dir == DMA_DEV_TO_MEM) { + udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); + udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); + udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); + } else { + udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); + udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); + if (!uc->bchan) + udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); + } +} + static void udma_reset_counters(struct udma_chan *uc) { u32 val; @@ -790,8 +802,6 @@ static void udma_reset_counters(struct udma_chan *uc) val = udma_rchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); } - - uc->bcnt = 0; } static int udma_reset_chan(struct udma_chan *uc, bool hard) @@ -1115,7 +1125,7 @@ static void udma_check_tx_completion(struct work_struct *work) if (uc->desc) { struct udma_desc *d = uc->desc; - uc->bcnt += d->residue; + udma_decrement_byte_counters(uc, d->residue); udma_start(uc); vchan_cookie_complete(&d->vd); break; @@ -1168,7 +1178,7 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data) vchan_cyclic_callback(&d->vd); } else { if (udma_is_desc_really_done(uc, d)) { - uc->bcnt += d->residue; + udma_decrement_byte_counters(uc, d->residue); udma_start(uc); vchan_cookie_complete(&d->vd); } else { @@ -1204,7 +1214,7 @@ static irqreturn_t udma_udma_irq_handler(int irq, void *data) vchan_cyclic_callback(&d->vd); } else { /* TODO: figure out the real amount of data */ - uc->bcnt += d->residue; + udma_decrement_byte_counters(uc, d->residue); udma_start(uc); vchan_cookie_complete(&d->vd); } @@ -3811,7 +3821,6 @@ static enum dma_status udma_tx_status(struct dma_chan *chan, bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_BCNT_REG); } - bcnt -= uc->bcnt; if (bcnt && !(bcnt % uc->desc->residue)) residue = 0; else From 9d54de866062576e2d627edcde726a7b7929f5f4 Mon Sep 17 00:00:00 2001 From: Letu Ren Date: Mon, 29 Aug 2022 19:01:15 +0800 Subject: [PATCH 483/610] scsi: 3w-9xxx: Avoid disabling device if failing to enable it [ Upstream commit 7eff437b5ee1309b34667844361c6bbb5c97df05 ] The original code will "goto out_disable_device" and call pci_disable_device() if pci_enable_device() fails. The kernel will generate a warning message like "3w-9xxx 0000:00:05.0: disabling already-disabled device". We shouldn't disable a device that failed to be enabled. A simple return is fine. Link: https://lore.kernel.org/r/20220829110115.38789-1-fantasquex@gmail.com Reported-by: Zheyu Ma Signed-off-by: Letu Ren Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/3w-9xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index e41cc354cc8a..6da591508f23 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -2006,7 +2006,7 @@ static int twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) retval = pci_enable_device(pdev); if (retval) { TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device"); - goto out_disable_device; + return -ENODEV; } pci_set_master(pdev); From c0d73be0af8c1310713bc39a8d7a22e35084e14f Mon Sep 17 00:00:00 2001 From: Shigeru Yoshida Date: Thu, 8 Sep 2022 01:35:02 +0900 Subject: [PATCH 484/610] nbd: Fix hung when signal interrupts nbd_start_device_ioctl() [ Upstream commit 1de7c3cf48fc41cd95adb12bd1ea9033a917798a ] syzbot reported hung task [1]. The following program is a simplified version of the reproducer: int main(void) { int sv[2], fd; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) return 1; if ((fd = open("/dev/nbd0", 0)) < 0) return 1; if (ioctl(fd, NBD_SET_SIZE_BLOCKS, 0x81) < 0) return 1; if (ioctl(fd, NBD_SET_SOCK, sv[0]) < 0) return 1; if (ioctl(fd, NBD_DO_IT) < 0) return 1; return 0; } When signal interrupt nbd_start_device_ioctl() waiting the condition atomic_read(&config->recv_threads) == 0, the task can hung because it waits the completion of the inflight IOs. This patch fixes the issue by clearing queue, not just shutdown, when signal interrupt nbd_start_device_ioctl(). Link: https://syzkaller.appspot.com/bug?id=7d89a3ffacd2b83fdd39549bc4d8e0a89ef21239 [1] Reported-by: syzbot+38e6c55d4969a14c1534@syzkaller.appspotmail.com Signed-off-by: Shigeru Yoshida Reviewed-by: Josef Bacik Link: https://lore.kernel.org/r/20220907163502.577561-1-syoshida@redhat.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/nbd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index b391ca062add..ec2b5dd2ce4a 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1351,10 +1351,12 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b mutex_unlock(&nbd->config_lock); ret = wait_event_interruptible(config->recv_wq, atomic_read(&config->recv_threads) == 0); - if (ret) + if (ret) { sock_shutdown(nbd); - flush_workqueue(nbd->recv_workq); + nbd_clear_que(nbd); + } + flush_workqueue(nbd->recv_workq); mutex_lock(&nbd->config_lock); nbd_bdev_reset(bdev); /* user requested, ignore socket errors */ From 3d6946180734379d161ff6c903ccff7cb2f288f0 Mon Sep 17 00:00:00 2001 From: Yicong Yang Date: Tue, 16 Aug 2022 19:44:10 +0800 Subject: [PATCH 485/610] iommu/arm-smmu-v3: Make default domain type of HiSilicon PTT device to identity [ Upstream commit 24b6c7798a0122012ca848ea0d25e973334266b0 ] The DMA operations of HiSilicon PTT device can only work properly with identical mappings. So add a quirk for the device to force the domain as passthrough. Acked-by: Will Deacon Signed-off-by: Yicong Yang Reviewed-by: John Garry Link: https://lore.kernel.org/r/20220816114414.4092-2-yangyicong@huawei.com Signed-off-by: Mathieu Poirier Signed-off-by: Sasha Levin --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 79edfdca6607..e7da4a47ce52 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2832,6 +2832,26 @@ static int arm_smmu_dev_disable_feature(struct device *dev, } } +/* + * HiSilicon PCIe tune and trace device can be used to trace TLP headers on the + * PCIe link and save the data to memory by DMA. The hardware is restricted to + * use identity mapping only. + */ +#define IS_HISI_PTT_DEVICE(pdev) ((pdev)->vendor == PCI_VENDOR_ID_HUAWEI && \ + (pdev)->device == 0xa12e) + +static int arm_smmu_def_domain_type(struct device *dev) +{ + if (dev_is_pci(dev)) { + struct pci_dev *pdev = to_pci_dev(dev); + + if (IS_HISI_PTT_DEVICE(pdev)) + return IOMMU_DOMAIN_IDENTITY; + } + + return 0; +} + static struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, @@ -2857,6 +2877,7 @@ static struct iommu_ops arm_smmu_ops = { .sva_unbind = arm_smmu_sva_unbind, .sva_get_pasid = arm_smmu_sva_get_pasid, .page_response = arm_smmu_page_response, + .def_domain_type = arm_smmu_def_domain_type, .pgsize_bitmap = -1UL, /* Restricted during device attach */ .owner = THIS_MODULE, }; From 7c8bc374659de19d846f7cab3eda9ebdb005c4cc Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sat, 27 Aug 2022 07:32:23 +0000 Subject: [PATCH 486/610] power: supply: adp5061: fix out-of-bounds read in adp5061_get_chg_type() [ Upstream commit 9d47e01b9d807808224347935562f7043a358054 ] ADP5061_CHG_STATUS_1_CHG_STATUS is masked with 0x07, which means a length of 8, but adp5061_chg_type array size is 4, may end up reading 4 elements beyond the end of the adp5061_chg_type[] array. Signed-off-by: Wei Yongjun Acked-by: Michael Hennerich Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/adp5061.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/adp5061.c b/drivers/power/supply/adp5061.c index 003557043ab3..daee1161c305 100644 --- a/drivers/power/supply/adp5061.c +++ b/drivers/power/supply/adp5061.c @@ -427,11 +427,11 @@ static int adp5061_get_chg_type(struct adp5061_state *st, if (ret < 0) return ret; - chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)]; - if (chg_type > ADP5061_CHG_FAST_CV) + chg_type = ADP5061_CHG_STATUS_1_CHG_STATUS(status1); + if (chg_type >= ARRAY_SIZE(adp5061_chg_type)) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; else - val->intval = chg_type; + val->intval = adp5061_chg_type[chg_type]; return ret; } From ff8551d411f12b5abc5ca929ab87643afa8a9588 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Fri, 9 Sep 2022 16:13:39 +0200 Subject: [PATCH 487/610] staging: vt6655: fix potential memory leak [ Upstream commit c8ff91535880d41b49699b3829fb6151942de29e ] In function device_init_td0_ring, memory is allocated for member td_info of priv->apTD0Rings[i], with i increasing from 0. In case of allocation failure, the memory is freed in reversed order, with i decreasing to 0. However, the case i=0 is left out and thus memory is leaked. Modify the memory freeing loop to include the case i=0. Tested-by: Philipp Hortmann Signed-off-by: Nam Cao Link: https://lore.kernel.org/r/20220909141338.19343-1-namcaov@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/vt6655/device_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 43e32360b6d9..775537b243aa 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -676,7 +676,7 @@ static int device_init_td0_ring(struct vnt_private *priv) return 0; err_free_desc: - while (--i) { + while (i--) { desc = &priv->apTD0Rings[i]; kfree(desc->td_info); } From 70b2adb1d698fbc63d3b3848c452524dc15872c5 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 29 Aug 2022 10:22:38 +0800 Subject: [PATCH 488/610] blk-throttle: prevent overflow while calculating wait time [ Upstream commit 8d6bbaada2e0a65f9012ac4c2506460160e7237a ] There is a problem found by code review in tg_with_in_bps_limit() that 'bps_limit * jiffy_elapsed_rnd' might overflow. Fix the problem by calling mul_u64_u64_div_u64() instead. Signed-off-by: Yu Kuai Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20220829022240.3348319-3-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/blk-throttle.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 7c4e7993ba97..68cf8dbb4c67 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -950,7 +950,7 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio, u64 bps_limit, unsigned long *wait) { bool rw = bio_data_dir(bio); - u64 bytes_allowed, extra_bytes, tmp; + u64 bytes_allowed, extra_bytes; unsigned long jiffy_elapsed, jiffy_wait, jiffy_elapsed_rnd; unsigned int bio_size = throtl_bio_data_size(bio); @@ -967,10 +967,8 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio, jiffy_elapsed_rnd = tg->td->throtl_slice; jiffy_elapsed_rnd = roundup(jiffy_elapsed_rnd, tg->td->throtl_slice); - - tmp = bps_limit * jiffy_elapsed_rnd; - do_div(tmp, HZ); - bytes_allowed = tmp; + bytes_allowed = mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed_rnd, + (u64)HZ); if (tg->bytes_disp[rw] + bio_size <= bytes_allowed) { if (wait) From eecb5ccc84a15336a06a1acb931de954d2936608 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 9 Sep 2022 22:36:06 +0300 Subject: [PATCH 489/610] ata: libahci_platform: Sanity check the DT child nodes number [ Upstream commit 3c132ea6508b34956e5ed88d04936983ec230601 ] Having greater than AHCI_MAX_PORTS (32) ports detected isn't that critical from the further AHCI-platform initialization point of view since exceeding the ports upper limit will cause allocating more resources than will be used afterwards. But detecting too many child DT-nodes doesn't seem right since it's very unlikely to have it on an ordinary platform. In accordance with the AHCI specification there can't be more than 32 ports implemented at least due to having the CAP.NP field of 5 bits wide and the PI register of dword size. Thus if such situation is found the DTB must have been corrupted and the data read from it shouldn't be reliable. Let's consider that as an erroneous situation and halt further resources allocation. Note it's logically more correct to have the nports set only after the initialization value is checked for being sane. So while at it let's make sure nports is assigned with a correct value. Signed-off-by: Serge Semin Reviewed-by: Hannes Reinecke Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin --- drivers/ata/libahci_platform.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 0910441321f7..64d6da0a5303 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -451,14 +451,24 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, } } - hpriv->nports = child_nodes = of_get_child_count(dev->of_node); + /* + * Too many sub-nodes most likely means having something wrong with + * the firmware. + */ + child_nodes = of_get_child_count(dev->of_node); + if (child_nodes > AHCI_MAX_PORTS) { + rc = -EINVAL; + goto err_out; + } /* * If no sub-node was found, we still need to set nports to * one in order to be able to use the * ahci_platform_[en|dis]able_[phys|regulators] functions. */ - if (!child_nodes) + if (child_nodes) + hpriv->nports = child_nodes; + else hpriv->nports = 1; hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL); From 1b4ed920b2ffa6bfd94a04417c60996d6a802025 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Tue, 20 Sep 2022 00:16:47 +0800 Subject: [PATCH 490/610] bcache: fix set_at_max_writeback_rate() for multiple attached devices [ Upstream commit d2d05b88035d2d51a5bb6c5afec88a0880c73df4 ] Inside set_at_max_writeback_rate() the calculation in following if() check is wrong, if (atomic_inc_return(&c->idle_counter) < atomic_read(&c->attached_dev_nr) * 6) Because each attached backing device has its own writeback thread running and increasing c->idle_counter, the counter increates much faster than expected. The correct calculation should be, (counter / dev_nr) < dev_nr * 6 which equals to, counter < dev_nr * dev_nr * 6 This patch fixes the above mistake with correct calculation, and helper routine idle_counter_exceeded() is added to make code be more clear. Reported-by: Mingzhe Zou Signed-off-by: Coly Li Acked-by: Mingzhe Zou Link: https://lore.kernel.org/r/20220919161647.81238-6-colyli@suse.de Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/md/bcache/writeback.c | 73 +++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 96a07839864b..ee7ad999e924 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -157,6 +157,53 @@ static void __update_writeback_rate(struct cached_dev *dc) dc->writeback_rate_target = target; } +static bool idle_counter_exceeded(struct cache_set *c) +{ + int counter, dev_nr; + + /* + * If c->idle_counter is overflow (idel for really long time), + * reset as 0 and not set maximum rate this time for code + * simplicity. + */ + counter = atomic_inc_return(&c->idle_counter); + if (counter <= 0) { + atomic_set(&c->idle_counter, 0); + return false; + } + + dev_nr = atomic_read(&c->attached_dev_nr); + if (dev_nr == 0) + return false; + + /* + * c->idle_counter is increased by writeback thread of all + * attached backing devices, in order to represent a rough + * time period, counter should be divided by dev_nr. + * Otherwise the idle time cannot be larger with more backing + * device attached. + * The following calculation equals to checking + * (counter / dev_nr) < (dev_nr * 6) + */ + if (counter < (dev_nr * dev_nr * 6)) + return false; + + return true; +} + +/* + * Idle_counter is increased every time when update_writeback_rate() is + * called. If all backing devices attached to the same cache set have + * identical dc->writeback_rate_update_seconds values, it is about 6 + * rounds of update_writeback_rate() on each backing device before + * c->at_max_writeback_rate is set to 1, and then max wrteback rate set + * to each dc->writeback_rate.rate. + * In order to avoid extra locking cost for counting exact dirty cached + * devices number, c->attached_dev_nr is used to calculate the idle + * throushold. It might be bigger if not all cached device are in write- + * back mode, but it still works well with limited extra rounds of + * update_writeback_rate(). + */ static bool set_at_max_writeback_rate(struct cache_set *c, struct cached_dev *dc) { @@ -167,21 +214,8 @@ static bool set_at_max_writeback_rate(struct cache_set *c, /* Don't set max writeback rate if gc is running */ if (!c->gc_mark_valid) return false; - /* - * Idle_counter is increased everytime when update_writeback_rate() is - * called. If all backing devices attached to the same cache set have - * identical dc->writeback_rate_update_seconds values, it is about 6 - * rounds of update_writeback_rate() on each backing device before - * c->at_max_writeback_rate is set to 1, and then max wrteback rate set - * to each dc->writeback_rate.rate. - * In order to avoid extra locking cost for counting exact dirty cached - * devices number, c->attached_dev_nr is used to calculate the idle - * throushold. It might be bigger if not all cached device are in write- - * back mode, but it still works well with limited extra rounds of - * update_writeback_rate(). - */ - if (atomic_inc_return(&c->idle_counter) < - atomic_read(&c->attached_dev_nr) * 6) + + if (!idle_counter_exceeded(c)) return false; if (atomic_read(&c->at_max_writeback_rate) != 1) @@ -195,13 +229,10 @@ static bool set_at_max_writeback_rate(struct cache_set *c, dc->writeback_rate_change = 0; /* - * Check c->idle_counter and c->at_max_writeback_rate agagain in case - * new I/O arrives during before set_at_max_writeback_rate() returns. - * Then the writeback rate is set to 1, and its new value should be - * decided via __update_writeback_rate(). + * In case new I/O arrives during before + * set_at_max_writeback_rate() returns. */ - if ((atomic_read(&c->idle_counter) < - atomic_read(&c->attached_dev_nr) * 6) || + if (!idle_counter_exceeded(c) || !atomic_read(&c->at_max_writeback_rate)) return false; From 093a5463aeecc8a8d13bac233652cf6532d53dd7 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Fri, 16 Sep 2022 11:35:05 +0100 Subject: [PATCH 491/610] soundwire: cadence: Don't overwrite msg->buf during write commands [ Upstream commit ba05b39d265bdd16913f7684600d9d41e2796745 ] The buf passed in struct sdw_msg must only be written for a READ, in that case the RDATA part of the response is the data value of the register. For a write command there is no RDATA, and buf should be assumed to be const and unmodifable. The original caller should not expect its data buffer to be corrupted by an sdw_nwrite(). Signed-off-by: Richard Fitzgerald Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220916103505.1562210-1-rf@opensource.cirrus.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/soundwire/cadence_master.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 4fcc3ba93004..18d2f9b3e201 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -545,9 +545,12 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns, return SDW_CMD_IGNORED; } - /* fill response */ - for (i = 0; i < count; i++) - msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]); + if (msg->flags == SDW_MSG_FLAG_READ) { + /* fill response */ + for (i = 0; i < count; i++) + msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, + cdns->response_buf[i]); + } return SDW_CMD_OK; } From f7f425d61de9bd5812fcf399888b7275afb97b58 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 20 Sep 2022 01:57:11 +0800 Subject: [PATCH 492/610] soundwire: intel: fix error handling on dai registration issues [ Upstream commit c6867cda906aadbce5e71efde9c78a26108b2bad ] The call to intel_register_dai() may fail because of memory allocation issues or problems reported by the ASoC core. In all cases, when a error is thrown the component is not registered, it's invalid to unregister it. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20220919175721.354679-2-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/soundwire/intel.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 38e7f1a2bb97..89ee033f0c35 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1407,7 +1407,6 @@ int intel_link_startup(struct auxiliary_device *auxdev) ret = intel_register_dai(sdw); if (ret) { dev_err(dev, "DAI registration failed: %d\n", ret); - snd_soc_unregister_component(dev); goto err_interrupt; } From c61786dc727d1850336d12c85a032c9a36ae396d Mon Sep 17 00:00:00 2001 From: Hyunwoo Kim Date: Sun, 4 Sep 2022 12:31:15 -0700 Subject: [PATCH 493/610] HID: roccat: Fix use-after-free in roccat_read() [ Upstream commit cacdb14b1c8d3804a3a7d31773bc7569837b71a4 ] roccat_report_event() is responsible for registering roccat-related reports in struct roccat_device. int roccat_report_event(int minor, u8 const *data) { struct roccat_device *device; struct roccat_reader *reader; struct roccat_report *report; uint8_t *new_value; device = devices[minor]; new_value = kmemdup(data, device->report_size, GFP_ATOMIC); if (!new_value) return -ENOMEM; report = &device->cbuf[device->cbuf_end]; /* passing NULL is safe */ kfree(report->value); ... The registered report is stored in the struct roccat_device member "struct roccat_report cbuf[ROCCAT_CBUF_SIZE];". If more reports are received than the "ROCCAT_CBUF_SIZE" value, kfree() the saved report from cbuf[0] and allocates a new reprot. Since there is no lock when this kfree() is performed, kfree() can be performed even while reading the saved report. static ssize_t roccat_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct roccat_reader *reader = file->private_data; struct roccat_device *device = reader->device; struct roccat_report *report; ssize_t retval = 0, len; DECLARE_WAITQUEUE(wait, current); mutex_lock(&device->cbuf_lock); ... report = &device->cbuf[reader->cbuf_start]; /* * If report is larger than requested amount of data, rest of report * is lost! */ len = device->report_size > count ? count : device->report_size; if (copy_to_user(buffer, report->value, len)) { retval = -EFAULT; goto exit_unlock; } ... The roccat_read() function receives the device->cbuf report and delivers it to the user through copy_to_user(). If the N+ROCCAT_CBUF_SIZE th report is received while copying of the Nth report->value is in progress, the pointer that copy_to_user() is working on is kfree()ed and UAF read may occur. (race condition) Since the device node of this driver does not set separate permissions, this is not a security vulnerability, but because it is used for requesting screen display of profile or dpi settings, a user using the roccat device can apply udev to this device node or There is a possibility to use it by giving. Signed-off-by: Hyunwoo Kim Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-roccat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index 26373b82fe81..6da80e442fdd 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -257,6 +257,8 @@ int roccat_report_event(int minor, u8 const *data) if (!new_value) return -ENOMEM; + mutex_lock(&device->cbuf_lock); + report = &device->cbuf[device->cbuf_end]; /* passing NULL is safe */ @@ -276,6 +278,8 @@ int roccat_report_event(int minor, u8 const *data) reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE; } + mutex_unlock(&device->cbuf_lock); + wake_up_interruptible(&device->wait); return 0; } From f8e80792c1a88c521c3aa2c377b766826ae89b81 Mon Sep 17 00:00:00 2001 From: Dylan Yudaken Date: Tue, 16 Aug 2022 06:59:59 -0700 Subject: [PATCH 494/610] eventfd: guard wake_up in eventfd fs calls as well [ Upstream commit 9f0deaa12d832f488500a5afe9b912e9b3cfc432 ] Guard wakeups that the user can trigger, and that may end up triggering a call back into eventfd_signal. This is in addition to the current approach that only guards in eventfd_signal. Rename in_eventfd_signal -> in_eventfd at the same time to reflect this. Without this there would be a deadlock in the following code using libaio: int main() { struct io_context *ctx = NULL; struct iocb iocb; struct iocb *iocbs[] = { &iocb }; int evfd; uint64_t val = 1; evfd = eventfd(0, EFD_CLOEXEC); assert(!io_setup(2, &ctx)); io_prep_poll(&iocb, evfd, POLLIN); io_set_eventfd(&iocb, evfd); assert(1 == io_submit(ctx, 1, iocbs)); write(evfd, &val, 8); } Signed-off-by: Dylan Yudaken Reviewed-by: Jens Axboe Link: https://lore.kernel.org/r/20220816135959.1490641-1-dylany@fb.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- fs/eventfd.c | 10 +++++++--- include/linux/eventfd.h | 2 +- include/linux/sched.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/eventfd.c b/fs/eventfd.c index 3627dd7d25db..c0ffee99ad23 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -69,17 +69,17 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n) * it returns false, the eventfd_signal() call should be deferred to a * safe context. */ - if (WARN_ON_ONCE(current->in_eventfd_signal)) + if (WARN_ON_ONCE(current->in_eventfd)) return 0; spin_lock_irqsave(&ctx->wqh.lock, flags); - current->in_eventfd_signal = 1; + current->in_eventfd = 1; if (ULLONG_MAX - ctx->count < n) n = ULLONG_MAX - ctx->count; ctx->count += n; if (waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, EPOLLIN); - current->in_eventfd_signal = 0; + current->in_eventfd = 0; spin_unlock_irqrestore(&ctx->wqh.lock, flags); return n; @@ -253,8 +253,10 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to) __set_current_state(TASK_RUNNING); } eventfd_ctx_do_read(ctx, &ucnt); + current->in_eventfd = 1; if (waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, EPOLLOUT); + current->in_eventfd = 0; spin_unlock_irq(&ctx->wqh.lock); if (unlikely(copy_to_iter(&ucnt, sizeof(ucnt), to) != sizeof(ucnt))) return -EFAULT; @@ -301,8 +303,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c } if (likely(res > 0)) { ctx->count += ucnt; + current->in_eventfd = 1; if (waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, EPOLLIN); + current->in_eventfd = 0; } spin_unlock_irq(&ctx->wqh.lock); diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index 305d5f19093b..30eb30d6909b 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h @@ -46,7 +46,7 @@ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt); static inline bool eventfd_signal_allowed(void) { - return !current->in_eventfd_signal; + return !current->in_eventfd; } #else /* CONFIG_EVENTFD */ diff --git a/include/linux/sched.h b/include/linux/sched.h index dcba347cbffa..e418935f8db6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -933,7 +933,7 @@ struct task_struct { #endif #ifdef CONFIG_EVENTFD /* Recursion prevention for eventfd_signal() */ - unsigned in_eventfd_signal:1; + unsigned in_eventfd:1; #endif unsigned long atomic_flags; /* Flags requiring atomic access. */ From 9e86dffd0b02594d2e7c60c6db9e889c0395414b Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Wed, 21 Sep 2022 10:28:37 -0600 Subject: [PATCH 495/610] md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d [ Upstream commit 5e2cf333b7bd5d3e62595a44d598a254c697cd74 ] A complicated deadlock exists when using the journal and an elevated group_thrtead_cnt. It was found with loop devices, but its not clear whether it can be seen with real disks. The deadlock can occur simply by writing data with an fio script. When the deadlock occurs, multiple threads will hang in different ways: 1) The group threads will hang in the blk-wbt code with bios waiting to be submitted to the block layer: io_schedule+0x70/0xb0 rq_qos_wait+0x153/0x210 wbt_wait+0x115/0x1b0 io_schedule+0x70/0xb0 rq_qos_wait+0x153/0x210 wbt_wait+0x115/0x1b0 __rq_qos_throttle+0x38/0x60 blk_mq_submit_bio+0x589/0xcd0 wbt_wait+0x115/0x1b0 __rq_qos_throttle+0x38/0x60 blk_mq_submit_bio+0x589/0xcd0 __submit_bio+0xe6/0x100 submit_bio_noacct_nocheck+0x42e/0x470 submit_bio_noacct+0x4c2/0xbb0 ops_run_io+0x46b/0x1a30 handle_stripe+0xcd3/0x36b0 handle_active_stripes.constprop.0+0x6f6/0xa60 raid5_do_work+0x177/0x330 Or: io_schedule+0x70/0xb0 rq_qos_wait+0x153/0x210 wbt_wait+0x115/0x1b0 __rq_qos_throttle+0x38/0x60 blk_mq_submit_bio+0x589/0xcd0 __submit_bio+0xe6/0x100 submit_bio_noacct_nocheck+0x42e/0x470 submit_bio_noacct+0x4c2/0xbb0 flush_deferred_bios+0x136/0x170 raid5_do_work+0x262/0x330 2) The r5l_reclaim thread will hang in the same way, submitting a bio to the block layer: io_schedule+0x70/0xb0 rq_qos_wait+0x153/0x210 wbt_wait+0x115/0x1b0 __rq_qos_throttle+0x38/0x60 blk_mq_submit_bio+0x589/0xcd0 __submit_bio+0xe6/0x100 submit_bio_noacct_nocheck+0x42e/0x470 submit_bio_noacct+0x4c2/0xbb0 submit_bio+0x3f/0xf0 md_super_write+0x12f/0x1b0 md_update_sb.part.0+0x7c6/0xff0 md_update_sb+0x30/0x60 r5l_do_reclaim+0x4f9/0x5e0 r5l_reclaim_thread+0x69/0x30b However, before hanging, the MD_SB_CHANGE_PENDING flag will be set for sb_flags in r5l_write_super_and_discard_space(). This flag will never be cleared because the submit_bio() call never returns. 3) Due to the MD_SB_CHANGE_PENDING flag being set, handle_stripe() will do no processing on any pending stripes and re-set STRIPE_HANDLE. This will cause the raid5d thread to enter an infinite loop, constantly trying to handle the same stripes stuck in the queue. The raid5d thread has a blk_plug that holds a number of bios that are also stuck waiting seeing the thread is in a loop that never schedules. These bios have been accounted for by blk-wbt thus preventing the other threads above from continuing when they try to submit bios. --Deadlock. To fix this, add the same wait_event() that is used in raid5_do_work() to raid5d() such that if MD_SB_CHANGE_PENDING is set, the thread will schedule and wait until the flag is cleared. The schedule action will flush the plug which will allow the r5l_reclaim thread to continue, thus preventing the deadlock. However, md_check_recovery() calls can also clear MD_SB_CHANGE_PENDING from the same thread and can thus deadlock if the thread is put to sleep. So avoid waiting if md_check_recovery() is being called in the loop. It's not clear when the deadlock was introduced, but the similar wait_event() call in raid5_do_work() was added in 2017 by this commit: 16d997b78b15 ("md/raid5: simplfy delaying of writes while metadata is updated.") Link: https://lore.kernel.org/r/7f3b87b6-b52a-f737-51d7-a4eec5c44112@deltatee.com Signed-off-by: Logan Gunthorpe Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/raid5.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 03bfb70f54bf..e4c82ecbaf0d 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -36,6 +36,7 @@ */ #include +#include #include #include #include @@ -6521,7 +6522,18 @@ static void raid5d(struct md_thread *thread) spin_unlock_irq(&conf->device_lock); md_check_recovery(mddev); spin_lock_irq(&conf->device_lock); + + /* + * Waiting on MD_SB_CHANGE_PENDING below may deadlock + * seeing md_check_recovery() is needed to clear + * the flag when using mdmon. + */ + continue; } + + wait_event_lock_irq(mddev->sb_wait, + !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), + conf->device_lock); } pr_debug("%d stripes handled\n", handled); From fcd594da0b5955119d9707e4e0a8d0fb1c969101 Mon Sep 17 00:00:00 2001 From: Jianglei Nie Date: Wed, 21 Sep 2022 15:34:45 +0300 Subject: [PATCH 496/610] usb: host: xhci: Fix potential memory leak in xhci_alloc_stream_info() [ Upstream commit 7e271f42a5cc3768cd2622b929ba66859ae21f97 ] xhci_alloc_stream_info() allocates stream context array for stream_info ->stream_ctx_array with xhci_alloc_stream_ctx(). When some error occurs, stream_info->stream_ctx_array is not released, which will lead to a memory leak. We can fix it by releasing the stream_info->stream_ctx_array with xhci_free_stream_ctx() on the error path to avoid the potential memory leak. Signed-off-by: Jianglei Nie Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20220921123450.671459-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-mem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index b398d3fdabf6..02cd4d7c3e7e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -642,7 +642,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci, num_stream_ctxs, &stream_info->ctx_array_dma, mem_flags); if (!stream_info->stream_ctx_array) - goto cleanup_ctx; + goto cleanup_ring_array; memset(stream_info->stream_ctx_array, 0, sizeof(struct xhci_stream_ctx)*num_stream_ctxs); @@ -703,6 +703,11 @@ cleanup_rings: } xhci_free_command(xhci, stream_info->free_streams_command); cleanup_ctx: + xhci_free_stream_ctx(xhci, + stream_info->num_stream_ctxs, + stream_info->stream_ctx_array, + stream_info->ctx_array_dma); +cleanup_ring_array: kfree(stream_info->stream_rings); cleanup_info: kfree(stream_info); From 3c84c7f592c4ba38f54ddaddd0115acc443025db Mon Sep 17 00:00:00 2001 From: Robin Guo Date: Tue, 6 Sep 2022 10:21:19 +0800 Subject: [PATCH 497/610] usb: musb: Fix musb_gadget.c rxstate overflow bug [ Upstream commit eea4c860c3b366369eff0489d94ee4f0571d467d ] The usb function device call musb_gadget_queue() adds the passed request to musb_ep::req_list,If the (request->length > musb_ep->packet_sz) and (is_buffer_mapped(req) return false),the rxstate() will copy all data in fifo to request->buf which may cause request->buf out of bounds. Fix it by add the length check : fifocnt = min_t(unsigned, request->length - request->actual, fifocnt); Signed-off-by: Robin Guo Link: https://lore.kernel.org/r/20220906102119.1b071d07a8391ff115e6d1ef@inspur.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/musb/musb_gadget.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 51274b87f46c..dc67fff8e941 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -760,6 +760,9 @@ static void rxstate(struct musb *musb, struct musb_request *req) musb_writew(epio, MUSB_RXCSR, csr); buffer_aint_mapped: + fifo_count = min_t(unsigned int, + request->length - request->actual, + (unsigned int)fifo_count); musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); request->actual += fifo_count; From 9d4f84a15f9c9727bc07f59d9dafc89e65aadb34 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Thu, 15 Sep 2022 08:28:54 +0200 Subject: [PATCH 498/610] arm64: dts: imx8mp: Add snps,gfladj-refclk-lpm-sel quirk to USB nodes [ Upstream commit 5c3d5ecf48ab06c709c012bf1e8f0c91e1fcd7ad ] With this set the SOF/ITP counter is based on ref_clk when 2.0 ports are suspended. snps,dis-u2-freeclk-exists-quirk can be removed as snps,gfladj-refclk-lpm-sel also clears the free running clock configuration bit. Signed-off-by: Alexander Stein Link: https://lore.kernel.org/r/20220915062855.751881-4-alexander.stein@ew.tq-group.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 9b07b26230a1..664177ed38d3 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -912,7 +912,7 @@ interrupts = ; phys = <&usb3_phy0>, <&usb3_phy0>; phy-names = "usb2-phy", "usb3-phy"; - snps,dis-u2-freeclk-exists-quirk; + snps,gfladj-refclk-lpm-sel-quirk; }; }; @@ -953,7 +953,7 @@ interrupts = ; phys = <&usb3_phy1>, <&usb3_phy1>; phy-names = "usb2-phy", "usb3-phy"; - snps,dis-u2-freeclk-exists-quirk; + snps,gfladj-refclk-lpm-sel-quirk; }; }; From 3a38985d8bfdc6b784d0f6990e8911579492518f Mon Sep 17 00:00:00 2001 From: Piyush Mehta Date: Tue, 20 Sep 2022 10:52:35 +0530 Subject: [PATCH 499/610] usb: dwc3: core: Enable GUCTL1 bit 10 for fixing termination error after resume bug [ Upstream commit 63d7f9810a38102cdb8cad214fac98682081e1a7 ] When configured in HOST mode, after issuing U3/L2 exit controller fails to send proper CRC checksum in CRC5 field. Because of this behavior Transaction Error is generated, resulting in reset and re-enumeration of usb device attached. Enabling chicken bit 10 of GUCTL1 will correct this problem. When this bit is set to '1', the UTMI/ULPI opmode will be changed to "normal" along with HS terminations, term, and xcvr signals after EOR. This option is to support certain legacy UTMI/ULPI PHYs. Added "snps,resume-hs-terminations" quirk to resolved the above issue. Signed-off-by: Piyush Mehta Link: https://lore.kernel.org/r/20220920052235.194272-3-piyush.mehta@amd.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/dwc3/core.c | 17 +++++++++++++++++ drivers/usb/dwc3/core.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c32ca691bcc7..a2f3e56aba05 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1041,6 +1041,21 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); } + /* + * When configured in HOST mode, after issuing U3/L2 exit controller + * fails to send proper CRC checksum in CRC5 feild. Because of this + * behaviour Transaction Error is generated, resulting in reset and + * re-enumeration of usb device attached. All the termsel, xcvrsel, + * opmode becomes 0 during end of resume. Enabling bit 10 of GUCTL1 + * will correct this problem. This option is to support certain + * legacy ULPI PHYs. + */ + if (dwc->resume_hs_terminations) { + reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); + reg |= DWC3_GUCTL1_RESUME_OPMODE_HS_HOST; + dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + } + if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) { reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); @@ -1383,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,dis-del-phy-power-chg-quirk"); dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev, "snps,dis-tx-ipgap-linecheck-quirk"); + dwc->resume_hs_terminations = device_property_read_bool(dev, + "snps,resume-hs-terminations"); dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev, "snps,parkmode-disable-ss-quirk"); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 077d03a33388..e82e4cbe4ec7 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -260,6 +260,7 @@ #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24) #define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17) +#define DWC3_GUCTL1_RESUME_OPMODE_HS_HOST BIT(10) /* Global Status Register */ #define DWC3_GSTS_OTG_IP BIT(10) @@ -1072,6 +1073,8 @@ struct dwc3_scratchpad_array { * change quirk. * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate * check during HS transmit. + * @resume-hs-terminations: Set if we enable quirk for fixing improper crc + * generation after resume from suspend. * @parkmode_disable_ss_quirk: set if we need to disable all SuperSpeed * instances in park mode. * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk @@ -1284,6 +1287,7 @@ struct dwc3 { unsigned dis_u2_freeclk_exists_quirk:1; unsigned dis_del_phy_power_chg_quirk:1; unsigned dis_tx_ipgap_linecheck_quirk:1; + unsigned resume_hs_terminations:1; unsigned parkmode_disable_ss_quirk:1; unsigned tx_de_emphasis_quirk:1; From eb24d93e3e0168c637d7acb7bd2d3d3e2a046273 Mon Sep 17 00:00:00 2001 From: sunghwan jung Date: Tue, 13 Sep 2022 20:49:13 +0900 Subject: [PATCH 500/610] Revert "usb: storage: Add quirk for Samsung Fit flash" [ Upstream commit ad5dbfc123e6ffbbde194e2a4603323e09f741ee ] This reverts commit 86d92f5465958752481269348d474414dccb1552, which fix the timeout issue for "Samsung Fit Flash". But the commit affects not only "Samsung Fit Flash" but also other usb storages that use the same controller and causes severe performance regression. # hdparm -t /dev/sda (without the quirk) Timing buffered disk reads: 622 MB in 3.01 seconds = 206.66 MB/sec # hdparm -t /dev/sda (with the quirk) Timing buffered disk reads: 220 MB in 3.00 seconds = 73.32 MB/sec The commit author mentioned that "Issue was reproduced after device has bad block", so this quirk should be applied when we have the timeout issue with a device that has bad blocks. We revert the commit so that we apply this quirk by adding kernel paramters using a bootloader or other ways when we really need it, without the performance regression with devices that don't have the issue. Signed-off-by: sunghwan jung Link: https://lore.kernel.org/r/20220913114913.3073-1-onenowy@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/storage/unusual_devs.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 4993227ab293..20dcbccb290b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1275,12 +1275,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, USB_SC_RBC, USB_PR_BULK, NULL, 0 ), -UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100, - "Samsung", - "Flash Drive FIT", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64), - /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", From b4573a2bad3c3e2643ef3939079eb7035a30e6ee Mon Sep 17 00:00:00 2001 From: Xiaoke Wang Date: Fri, 9 Sep 2022 18:39:35 +0800 Subject: [PATCH 501/610] staging: rtl8723bs: fix potential memory leak in rtw_init_drv_sw() [ Upstream commit 5a5aa9cce621e2c0e25a1e5d72d6be1749167cc0 ] In rtw_init_drv_sw(), there are various init functions are called to populate the padapter structure and some checks for their return value. However, except for the first one error path, the other five error paths do not properly release the previous allocated resources, which leads to various memory leaks. This patch fixes them and keeps the success and error separate. Note that these changes keep the form of `rtw_init_drv_sw()` in "drivers/staging/r8188eu/os_dep/os_intfs.c". As there is no proper device to test with, no runtime testing was performed. Signed-off-by: Xiaoke Wang Link: https://lore.kernel.org/r/tencent_C3B899D2FC3F1BC827F3552E0B0734056006@qq.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/rtl8723bs/os_dep/os_intfs.c | 60 +++++++++++---------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index f78bf174de8e..23f4f706f935 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -664,51 +664,36 @@ void rtw_reset_drv_sw(struct adapter *padapter) u8 rtw_init_drv_sw(struct adapter *padapter) { - u8 ret8 = _SUCCESS; - rtw_init_default_value(padapter); rtw_init_hal_com_default_value(padapter); - if (rtw_init_cmd_priv(&padapter->cmdpriv)) { - ret8 = _FAIL; - goto exit; - } + if (rtw_init_cmd_priv(&padapter->cmdpriv)) + return _FAIL; padapter->cmdpriv.padapter = padapter; - if (rtw_init_evt_priv(&padapter->evtpriv)) { - ret8 = _FAIL; - goto exit; - } + if (rtw_init_evt_priv(&padapter->evtpriv)) + goto free_cmd_priv; - - if (rtw_init_mlme_priv(padapter) == _FAIL) { - ret8 = _FAIL; - goto exit; - } + if (rtw_init_mlme_priv(padapter) == _FAIL) + goto free_evt_priv; init_mlme_ext_priv(padapter); - if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) { - ret8 = _FAIL; - goto exit; - } + if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) + goto free_mlme_ext; - if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) { - ret8 = _FAIL; - goto exit; - } + if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) + goto free_xmit_priv; /* add for CONFIG_IEEE80211W, none 11w also can use */ spin_lock_init(&padapter->security_key_mutex); /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ /* memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); */ - if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) { - ret8 = _FAIL; - goto exit; - } + if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) + goto free_recv_priv; padapter->stapriv.padapter = padapter; padapter->setband = GHZ24_50; @@ -719,9 +704,26 @@ u8 rtw_init_drv_sw(struct adapter *padapter) rtw_hal_dm_init(padapter); -exit: + return _SUCCESS; - return ret8; +free_recv_priv: + _rtw_free_recv_priv(&padapter->recvpriv); + +free_xmit_priv: + _rtw_free_xmit_priv(&padapter->xmitpriv); + +free_mlme_ext: + free_mlme_ext_priv(&padapter->mlmeextpriv); + + rtw_free_mlme_priv(&padapter->mlmepriv); + +free_evt_priv: + rtw_free_evt_priv(&padapter->evtpriv); + +free_cmd_priv: + rtw_free_cmd_priv(&padapter->cmdpriv); + + return _FAIL; } void rtw_cancel_all_timer(struct adapter *padapter) From 39bef9c6a91bbb790d04c1347cfeae584541fb6a Mon Sep 17 00:00:00 2001 From: Xiaoke Wang Date: Fri, 9 Sep 2022 19:27:21 +0800 Subject: [PATCH 502/610] staging: rtl8723bs: fix a potential memory leak in rtw_init_cmd_priv() [ Upstream commit 708056fba733a73d926772ea4ce9a42d240345da ] In rtw_init_cmd_priv(), if `pcmdpriv->rsp_allocated_buf` is allocated in failure, then `pcmdpriv->cmd_allocated_buf` will be not properly released. Besides, considering there are only two error paths and the first one can directly return, so we do not need implicitly jump to the `exit` tag to execute the error handler. So this patch added `kfree(pcmdpriv->cmd_allocated_buf);` on the error path to release the resource and simplified the return logic of rtw_init_cmd_priv(). As there is no proper device to test with, no runtime testing was performed. Signed-off-by: Xiaoke Wang Link: https://lore.kernel.org/r/tencent_2B7931B79BA38E22205C5A09EFDF11E48805@qq.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/rtl8723bs/core/rtw_cmd.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index d494c06dab96..93e3a4c9e115 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -161,8 +161,6 @@ static struct cmd_hdl wlancmds[] = { int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) { - int res = 0; - init_completion(&pcmdpriv->cmd_queue_comp); init_completion(&pcmdpriv->terminate_cmdthread_comp); @@ -174,18 +172,16 @@ int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ); - if (!pcmdpriv->cmd_allocated_buf) { - res = -ENOMEM; - goto exit; - } + if (!pcmdpriv->cmd_allocated_buf) + return -ENOMEM; pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4); if (!pcmdpriv->rsp_allocated_buf) { - res = -ENOMEM; - goto exit; + kfree(pcmdpriv->cmd_allocated_buf); + return -ENOMEM; } pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); @@ -195,8 +191,8 @@ int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) pcmdpriv->rsp_cnt = 0; mutex_init(&pcmdpriv->sctx_mutex); -exit: - return res; + + return 0; } static void c2h_wk_callback(struct work_struct *work); From 8c067a3051cdadf93c03c1d1863975c9c18d7472 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Wed, 7 Sep 2022 16:33:08 -0700 Subject: [PATCH 503/610] scsi: tracing: Fix compile error in trace_array calls when TRACING is disabled [ Upstream commit 1a77dd1c2bb5d4a58c16d198cf593720787c02e4 ] Fix this compilation error seen when CONFIG_TRACING is not enabled: drivers/scsi/qla2xxx/qla_os.c: In function 'qla_trace_init': drivers/scsi/qla2xxx/qla_os.c:2854:25: error: implicit declaration of function 'trace_array_get_by_name'; did you mean 'trace_array_set_clr_event'? [-Werror=implicit-function-declaration] 2854 | qla_trc_array = trace_array_get_by_name("qla2xxx"); | ^~~~~~~~~~~~~~~~~~~~~~~ | trace_array_set_clr_event drivers/scsi/qla2xxx/qla_os.c: In function 'qla_trace_uninit': drivers/scsi/qla2xxx/qla_os.c:2869:9: error: implicit declaration of function 'trace_array_put' [-Werror=implicit-function-declaration] 2869 | trace_array_put(qla_trc_array); | ^~~~~~~~~~~~~~~ Link: https://lore.kernel.org/r/20220907233308.4153-2-aeasi@marvell.com Reported-by: kernel test robot Reviewed-by: Steven Rostedt (Google) Signed-off-by: Arun Easi Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- include/linux/trace.h | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/include/linux/trace.h b/include/linux/trace.h index bf169612ffe1..b5e16e438448 100644 --- a/include/linux/trace.h +++ b/include/linux/trace.h @@ -2,8 +2,6 @@ #ifndef _LINUX_TRACE_H #define _LINUX_TRACE_H -#ifdef CONFIG_TRACING - #define TRACE_EXPORT_FUNCTION BIT(0) #define TRACE_EXPORT_EVENT BIT(1) #define TRACE_EXPORT_MARKER BIT(2) @@ -28,6 +26,8 @@ struct trace_export { int flags; }; +#ifdef CONFIG_TRACING + int register_ftrace_export(struct trace_export *export); int unregister_ftrace_export(struct trace_export *export); @@ -48,6 +48,38 @@ void osnoise_arch_unregister(void); void osnoise_trace_irq_entry(int id); void osnoise_trace_irq_exit(int id, const char *desc); +#else /* CONFIG_TRACING */ +static inline int register_ftrace_export(struct trace_export *export) +{ + return -EINVAL; +} +static inline int unregister_ftrace_export(struct trace_export *export) +{ + return 0; +} +static inline void trace_printk_init_buffers(void) +{ +} +static inline int trace_array_printk(struct trace_array *tr, unsigned long ip, + const char *fmt, ...) +{ + return 0; +} +static inline int trace_array_init_printk(struct trace_array *tr) +{ + return -EINVAL; +} +static inline void trace_array_put(struct trace_array *tr) +{ +} +static inline struct trace_array *trace_array_get_by_name(const char *name) +{ + return NULL; +} +static inline int trace_array_destroy(struct trace_array *tr) +{ + return 0; +} #endif /* CONFIG_TRACING */ #endif /* _LINUX_TRACE_H */ From b9b5560b342e40bd6a0a131fb1bd99684ee8f1e7 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 14 Sep 2022 17:29:33 +0200 Subject: [PATCH 504/610] ext2: Use kvmalloc() for group descriptor array [ Upstream commit e7c7fbb9a8574ebd89cc05db49d806c7476863ad ] Array of group descriptor block buffers can get rather large. In theory in can reach 1MB for perfectly valid filesystem and even more for maliciously crafted ones. Use kvmalloc() to allocate the array to avoid straining memory allocator with large order allocations unnecessarily. Reported-by: syzbot+0f2f7e65a3007d39539f@syzkaller.appspotmail.com Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/ext2/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext2/super.c b/fs/ext2/super.c index fd855574ef09..02d82f8fe85d 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -163,7 +163,7 @@ static void ext2_put_super (struct super_block * sb) db_count = sbi->s_gdb_count; for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); - kfree(sbi->s_group_desc); + kvfree(sbi->s_group_desc); kfree(sbi->s_debts); percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); @@ -1080,7 +1080,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) } db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / EXT2_DESC_PER_BLOCK(sb); - sbi->s_group_desc = kmalloc_array(db_count, + sbi->s_group_desc = kvmalloc_array(db_count, sizeof(struct buffer_head *), GFP_KERNEL); if (sbi->s_group_desc == NULL) { @@ -1206,7 +1206,7 @@ failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); failed_mount_group_desc: - kfree(sbi->s_group_desc); + kvfree(sbi->s_group_desc); kfree(sbi->s_debts); failed_mount: brelse(bh); From 1c6432884010507d49a43a29a7dbdb03b25231b5 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 19 Sep 2022 12:45:08 -0700 Subject: [PATCH 505/610] nvme: copy firmware_rev on each init [ Upstream commit a8eb6c1ba48bddea82e8d74cbe6e119f006be97d ] The firmware revision can change on after a reset so copy the most recent info each time instead of just the first time, otherwise the sysfs firmware_rev entry may contain stale data. Reported-by: Jeff Lien Signed-off-by: Keith Busch Reviewed-by: Sagi Grimberg Reviewed-by: Chaitanya Kulkarni Reviewed-by: Chao Leng Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 76d8a72f52e2..3527a0667568 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2732,7 +2732,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) nvme_init_subnqn(subsys, ctrl, id); memcpy(subsys->serial, id->sn, sizeof(subsys->serial)); memcpy(subsys->model, id->mn, sizeof(subsys->model)); - memcpy(subsys->firmware_rev, id->fr, sizeof(subsys->firmware_rev)); subsys->vendor_id = le16_to_cpu(id->vid); subsys->cmic = id->cmic; subsys->awupf = le16_to_cpu(id->awupf); @@ -2939,6 +2938,8 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl) ctrl->quirks |= core_quirks[i].quirks; } } + memcpy(ctrl->subsys->firmware_rev, id->fr, + sizeof(ctrl->subsys->firmware_rev)); if (force_apst && (ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS)) { dev_warn(ctrl->device, "forcibly allowing all power states due to nvme_core.force_apst -- use at your own risk\n"); From ec8adf767e1cfa7031f853b8c71ba1963f07df15 Mon Sep 17 00:00:00 2001 From: Varun Prakash Date: Wed, 21 Sep 2022 00:06:49 +0530 Subject: [PATCH 506/610] nvmet-tcp: add bounds check on Transfer Tag [ Upstream commit b6a545ffa2c192b1e6da4a7924edac5ba9f4ea2b ] ttag is used as an index to get cmd in nvmet_tcp_handle_h2c_data_pdu(), add a bounds check to avoid out-of-bounds access. Signed-off-by: Varun Prakash Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/tcp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index fba5a77c58d6..2add26637c87 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -934,10 +934,17 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) struct nvme_tcp_data_pdu *data = &queue->pdu.data; struct nvmet_tcp_cmd *cmd; - if (likely(queue->nr_cmds)) + if (likely(queue->nr_cmds)) { + if (unlikely(data->ttag >= queue->nr_cmds)) { + pr_err("queue %d: received out of bound ttag %u, nr_cmds %u\n", + queue->idx, data->ttag, queue->nr_cmds); + nvmet_tcp_fatal_error(queue); + return -EPROTO; + } cmd = &queue->cmds[data->ttag]; - else + } else { cmd = &queue->connect; + } if (le32_to_cpu(data->data_offset) != cmd->rbytes_done) { pr_err("ttag %u unexpected data offset %u (expected %u)\n", From 20b8c456df584ebb2387dc23d40ebe4ff334417c Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Thu, 22 Sep 2022 21:48:44 +0800 Subject: [PATCH 507/610] usb: idmouse: fix an uninit-value in idmouse_open [ Upstream commit bce2b0539933e485d22d6f6f076c0fcd6f185c4c ] In idmouse_create_image, if any ftip_command fails, it will go to the reset label. However, this leads to the data in bulk_in_buffer[HEADER..IMGSIZE] uninitialized. And the check for valid image incurs an uninitialized dereference. Fix this by moving the check before reset label since this check only be valid if the data after bulk_in_buffer[HEADER] has concrete data. Note that this is found by KMSAN, so only kernel compilation is tested. Reported-by: syzbot+79832d33eb89fb3cd092@syzkaller.appspotmail.com Signed-off-by: Dongliang Mu Link: https://lore.kernel.org/r/20220922134847.1101921-1-dzm91@hust.edu.cn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/misc/idmouse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index e9437a176518..ea39243efee3 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -177,10 +177,6 @@ static int idmouse_create_image(struct usb_idmouse *dev) bytes_read += bulk_read; } - /* reset the device */ -reset: - ftip_command(dev, FTIP_RELEASE, 0, 0); - /* check for valid image */ /* right border should be black (0x00) */ for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH) @@ -192,6 +188,10 @@ reset: if (dev->bulk_in_buffer[bytes_read] != 0xFF) return -EAGAIN; + /* reset the device */ +reset: + ftip_command(dev, FTIP_RELEASE, 0, 0); + /* should be IMGSIZE == 65040 */ dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n", bytes_read); From da17cbb229af34a03afec851d15cac9722623472 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 26 Sep 2022 10:45:09 +0200 Subject: [PATCH 508/610] clk: bcm2835: Make peripheral PLLC critical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 6c5422851d8be8c7451e968fd2e6da41b6109e17 ] When testing for a series affecting the VEC, it was discovered that turning off and on the VEC clock is crashing the system. It turns out that, when disabling the VEC clock, it's the only child of the PLLC-per clock which will also get disabled. The source of the crash is PLLC-per being disabled. It's likely that some other device might not take a clock reference that it actually needs, but it's unclear which at this point. Let's make PLLC-per critical so that we don't have that crash. Reported-by: Noralf Trønnes Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20220926084509.12233-1-maxime@cerno.tech Reviewed-by: Stefan Wahren Acked-by: Noralf Trønnes Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/bcm/clk-bcm2835.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 2200305a722d..f17b65d546e9 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1785,7 +1785,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLC_LOADPER, .hold_mask = CM_PLLC_HOLDPER, .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT), + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), /* * PLLD is the display PLL, used to drive DSI display panels. From e81bf40b280bd42e4e0fe169a27f5402fbb53af5 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 12 Sep 2022 11:13:04 +0300 Subject: [PATCH 509/610] clk: bcm2835: Round UART input clock up [ Upstream commit f690a4d7a8f66430662975511c86819dc9965bcc ] It was reported that RPi3[1] and RPi Zero 2W boards have issues with the Bluetooth. It turns out that when switching from initial to operation speed host and device no longer can talk each other because host uses incorrect UART baud rate. The UART driver used in this case is amba-pl011. Original fix, see below Github link[2], was inside pl011 module, but somehow it didn't look as the right place to fix. Beside that this original rounding function is not exactly perfect for all possible clock values. So I deiced to move the hack to the platform which actually need it. The UART clock is initialised to be as close to the requested frequency as possible without exceeding it. Now that there is a clock manager that returns the actual frequencies, an expected 48MHz clock is reported as 47999625. If the requested baud rate == requested clock/16, there is no headroom and the slight reduction in actual clock rate results in failure. If increasing a clock by less than 0.1% changes it from ..999.. to ..000.., round it up. [1] https://bugzilla.suse.com/show_bug.cgi?id=1188238 [2] https://github.com/raspberrypi/linux/commit/ab3f1b39537f6d3825b8873006fbe2fc5ff057b7 Cc: Phil Elwell Signed-off-by: Ivan T. Ivanov Reviewed-by: Stefan Wahren Link: https://lore.kernel.org/r/20220912081306.24662-1-iivanov@suse.de Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/bcm/clk-bcm2835.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index f17b65d546e9..141ce19bc570 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -502,6 +503,8 @@ struct bcm2835_clock_data { bool low_jitter; u32 tcnt_mux; + + bool round_up; }; struct bcm2835_gate_data { @@ -994,12 +997,34 @@ static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock return temp; } +static unsigned long bcm2835_round_rate(unsigned long rate) +{ + unsigned long scaler; + unsigned long limit; + + limit = rate / 100000; + + scaler = 1; + while (scaler < limit) + scaler *= 10; + + /* + * If increasing a clock by less than 0.1% changes it + * from ..999.. to ..000.., round up. + */ + if ((rate + scaler - 1) / scaler % 1000 == 0) + rate = roundup(rate, scaler); + + return rate; +} + static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, unsigned long parent_rate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; const struct bcm2835_clock_data *data = clock->data; + unsigned long rate; u32 div; if (data->int_bits == 0 && data->frac_bits == 0) @@ -1007,7 +1032,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, div = cprman_read(cprman, data->div_reg); - return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + rate = bcm2835_clock_rate_from_divisor(clock, parent_rate, div); + + if (data->round_up) + rate = bcm2835_round_rate(rate); + + return rate; } static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) @@ -2144,7 +2174,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .div_reg = CM_UARTDIV, .int_bits = 10, .frac_bits = 12, - .tcnt_mux = 28), + .tcnt_mux = 28, + .round_up = true), /* TV encoder clock. Only operating frequency is 108Mhz. */ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( From c69a2324fc6b0bbac8d98fab667176e187d8e3fd Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 12 Oct 2022 11:22:58 +0300 Subject: [PATCH 510/610] perf intel-pt: Fix segfault in intel_pt_print_info() with uClibc commit 5a3d47071f0ced0431ef82a5fb6bd077ed9493db upstream. uClibc segfaulted because NULL was passed as the format to fprintf(). That happened because one of the format strings was missing and intel_pt_print_info() didn't check that before calling fprintf(). Add the missing format string, and check format is not NULL before calling fprintf(). Fixes: 11fa7cb86b56d361 ("perf tools: Pass Intel PT information for decoding MTC and CYC") Signed-off-by: Adrian Hunter Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Ian Rogers Cc: Jiri Olsa Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20221012082259.22394-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Greg Kroah-Hartman --- tools/perf/util/intel-pt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index c3ceac138810..632419546705 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -3591,6 +3591,7 @@ static const char * const intel_pt_info_fmts[] = { [INTEL_PT_SNAPSHOT_MODE] = " Snapshot mode %"PRId64"\n", [INTEL_PT_PER_CPU_MMAPS] = " Per-cpu maps %"PRId64"\n", [INTEL_PT_MTC_BIT] = " MTC bit %#"PRIx64"\n", + [INTEL_PT_MTC_FREQ_BITS] = " MTC freq bits %#"PRIx64"\n", [INTEL_PT_TSC_CTC_N] = " TSC:CTC numerator %"PRIu64"\n", [INTEL_PT_TSC_CTC_D] = " TSC:CTC denominator %"PRIu64"\n", [INTEL_PT_CYC_BIT] = " CYC bit %#"PRIx64"\n", @@ -3605,8 +3606,12 @@ static void intel_pt_print_info(__u64 *arr, int start, int finish) if (!dump_trace) return; - for (i = start; i <= finish; i++) - fprintf(stdout, intel_pt_info_fmts[i], arr[i]); + for (i = start; i <= finish; i++) { + const char *fmt = intel_pt_info_fmts[i]; + + if (fmt) + fprintf(stdout, fmt, arr[i]); + } } static void intel_pt_print_info_str(const char *name, const char *str) From 813d8fe5d30388f73a21d3a2bf46b0a1fd72498c Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 16 Oct 2022 22:42:54 +0100 Subject: [PATCH 511/610] io_uring/af_unix: defer registered files gc to io_uring release [ upstream commit 0091bfc81741b8d3aeb3b7ab8636f911b2de6e80 ] Instead of putting io_uring's registered files in unix_gc() we want it to be done by io_uring itself. The trick here is to consider io_uring registered files for cycle detection but not actually putting them down. Because io_uring can't register other ring instances, this will remove all refs to the ring file triggering the ->release path and clean up with io_ring_ctx_free(). Cc: stable@vger.kernel.org Fixes: 6b06314c47e1 ("io_uring: add file set registration") Reported-and-tested-by: David Bouman Signed-off-by: Pavel Begunkov Signed-off-by: Thadeu Lima de Souza Cascardo [axboe: add kerneldoc comment to skb, fold in skb leak fix] Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 1 + include/linux/skbuff.h | 2 ++ net/unix/garbage.c | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index af856a8ce5ff..b94cbac07a59 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -8066,6 +8066,7 @@ static int __io_sqe_files_scm(struct io_ring_ctx *ctx, int nr, int offset) } skb->sk = sk; + skb->scm_io_uring = 1; nr_files = 0; fpl->user = get_uid(current_user()); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cfb889f66c70..19e595cab23a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -725,6 +725,7 @@ typedef unsigned char *sk_buff_data_t; * @csum_level: indicates the number of consecutive checksums found in * the packet minus one that have been verified as * CHECKSUM_UNNECESSARY (max 3) + * @scm_io_uring: SKB holds io_uring registered files * @dst_pending_confirm: need to confirm neighbour * @decrypted: Decrypted SKB * @slow_gro: state present at GRO time, slower prepare step required @@ -910,6 +911,7 @@ struct sk_buff { __u8 decrypted:1; #endif __u8 slow_gro:1; + __u8 scm_io_uring:1; #ifdef CONFIG_NET_SCHED __u16 tc_index; /* traffic control index */ diff --git a/net/unix/garbage.c b/net/unix/garbage.c index d45d5366115a..dc2763540393 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -204,6 +204,7 @@ void wait_for_unix_gc(void) /* The external entry point: unix_gc() */ void unix_gc(void) { + struct sk_buff *next_skb, *skb; struct unix_sock *u; struct unix_sock *next; struct sk_buff_head hitlist; @@ -297,11 +298,30 @@ void unix_gc(void) spin_unlock(&unix_gc_lock); + /* We need io_uring to clean its registered files, ignore all io_uring + * originated skbs. It's fine as io_uring doesn't keep references to + * other io_uring instances and so killing all other files in the cycle + * will put all io_uring references forcing it to go through normal + * release.path eventually putting registered files. + */ + skb_queue_walk_safe(&hitlist, skb, next_skb) { + if (skb->scm_io_uring) { + __skb_unlink(skb, &hitlist); + skb_queue_tail(&skb->sk->sk_receive_queue, skb); + } + } + /* Here we are. Hitlist is filled. Die. */ __skb_queue_purge(&hitlist); spin_lock(&unix_gc_lock); + /* There could be io_uring registered files, just push them back to + * the inflight list + */ + list_for_each_entry_safe(u, next, &gc_candidates, link) + list_move_tail(&u->link, &gc_inflight_list); + /* All candidates should have been detached by now. */ BUG_ON(!list_empty(&gc_candidates)); From cd148d4e3183d982e2c624a1cd88512ccab0b2ed Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 16 Oct 2022 22:42:55 +0100 Subject: [PATCH 512/610] io_uring: correct pinned_vm accounting [ upstream commit 42b6419d0aba47c5d8644cdc0b68502254671de5 ] ->mm_account should be released only after we free all registered buffers, otherwise __io_sqe_buffers_unregister() will see a NULL ->mm_account and skip locked_vm accounting. Cc: Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/6d798f65ed4ab8db3664c4d3397d4af16ca98846.1664849932.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index b94cbac07a59..4d32483f8e45 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -9303,11 +9303,6 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx) { io_sq_thread_finish(ctx); - if (ctx->mm_account) { - mmdrop(ctx->mm_account); - ctx->mm_account = NULL; - } - /* __io_rsrc_put_work() may need uring_lock to progress, wait w/o it */ io_wait_rsrc_data(ctx->buf_data); io_wait_rsrc_data(ctx->file_data); @@ -9343,6 +9338,11 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx) #endif WARN_ON_ONCE(!list_empty(&ctx->ltimeout_list)); + if (ctx->mm_account) { + mmdrop(ctx->mm_account); + ctx->mm_account = NULL; + } + io_mem_free(ctx->rings); io_mem_free(ctx->sq_sqes); From e857457c6f90974f584897e9905ff338426e6233 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 16 Oct 2022 22:42:56 +0100 Subject: [PATCH 513/610] io_uring/rw: fix short rw error handling [ upstream commit 89473c1a9205760c4fa6d158058da7b594a815f0 ] We have a couple of problems, first reports of unexpected link breakage for reads when cqe->res indicates that the IO was done in full. The reason here is partial IO with retries. TL;DR; we compare the result in __io_complete_rw_common() against req->cqe.res, but req->cqe.res doesn't store the full length but rather the length left to be done. So, when we pass the full corrected result via kiocb_done() -> __io_complete_rw_common(), it fails. The second problem is that we don't try to correct res in io_complete_rw(), which, for instance, might be a problem for O_DIRECT but when a prefix of data was cached in the page cache. We also definitely don't want to pass a corrected result into io_rw_done(). The fix here is to leave __io_complete_rw_common() alone, always pass not corrected result into it and fix it up as the last step just before actually finishing the I/O. Cc: stable@vger.kernel.org Signed-off-by: Pavel Begunkov Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 4d32483f8e45..49c0e4eb8987 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2701,6 +2701,20 @@ static bool __io_complete_rw_common(struct io_kiocb *req, long res) return false; } +static inline unsigned io_fixup_rw_res(struct io_kiocb *req, unsigned res) +{ + struct io_async_rw *io = req->async_data; + + /* add previously done IO, if any */ + if (io && io->bytes_done > 0) { + if (res < 0) + res = io->bytes_done; + else + res += io->bytes_done; + } + return res; +} + static void io_req_task_complete(struct io_kiocb *req, bool *locked) { unsigned int cflags = io_put_rw_kbuf(req); @@ -2724,7 +2738,7 @@ static void __io_complete_rw(struct io_kiocb *req, long res, long res2, { if (__io_complete_rw_common(req, res)) return; - __io_req_complete(req, issue_flags, req->result, io_put_rw_kbuf(req)); + __io_req_complete(req, issue_flags, io_fixup_rw_res(req, res), io_put_rw_kbuf(req)); } static void io_complete_rw(struct kiocb *kiocb, long res, long res2) @@ -2733,7 +2747,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res, long res2) if (__io_complete_rw_common(req, res)) return; - req->result = res; + req->result = io_fixup_rw_res(req, res); req->io_task_work.func = io_req_task_complete; io_req_task_work_add(req); } @@ -2979,15 +2993,6 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, unsigned int issue_flags) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb); - struct io_async_rw *io = req->async_data; - - /* add previously done IO, if any */ - if (io && io->bytes_done > 0) { - if (ret < 0) - ret = io->bytes_done; - else - ret += io->bytes_done; - } if (req->flags & REQ_F_CUR_POS) req->file->f_pos = kiocb->ki_pos; @@ -3004,6 +3009,7 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, unsigned int cflags = io_put_rw_kbuf(req); struct io_ring_ctx *ctx = req->ctx; + ret = io_fixup_rw_res(req, ret); req_set_fail(req); if (!(issue_flags & IO_URING_F_NONBLOCK)) { mutex_lock(&ctx->uring_lock); From d6b7efc722a2684b6652ee49546c83b544b1b4b6 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 16 Oct 2022 22:42:57 +0100 Subject: [PATCH 514/610] io_uring/rw: fix error'ed retry return values [ upstream commit 62bb0647b14646fa6c9aa25ecdf67ad18f13523c ] Kernel test robot reports that we test negativity of an unsigned in io_fixup_rw_res() after a recent change, which masks error codes and messes up the return value in case I/O is re-retried and failed with an error. Fixes: 4d9cb92ca41dd ("io_uring/rw: fix short rw error handling") Reported-by: kernel test robot Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/9754a0970af1861e7865f9014f735c70dc60bf79.1663071587.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 49c0e4eb8987..589e9e122e5d 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2701,7 +2701,7 @@ static bool __io_complete_rw_common(struct io_kiocb *req, long res) return false; } -static inline unsigned io_fixup_rw_res(struct io_kiocb *req, unsigned res) +static inline int io_fixup_rw_res(struct io_kiocb *req, unsigned res) { struct io_async_rw *io = req->async_data; From 98aada6e22786916d150a598c7a7eaf937ca464c Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 16 Oct 2022 22:42:58 +0100 Subject: [PATCH 515/610] io_uring/rw: fix unexpected link breakage [ upstream commit bf68b5b34311ee57ed40749a1257a30b46127556 ] req->cqe.res is set in io_read() to the amount of bytes left to be done, which is used to figure out whether to fail a read or not. However, io_read() may do another without returning, and we stash the previous value into ->bytes_done but forget to update cqe.res. Then we ask a read to do strictly less than cqe.res but expect the return to be exactly cqe.res. Fix the bug by updating cqe.res for retries. Cc: stable@vger.kernel.org Reported-and-Tested-by: Beld Zhang Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/3a1088440c7be98e5800267af922a67da0ef9f13.1664235732.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 589e9e122e5d..b8ae64df90e3 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3606,6 +3606,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags) return -EAGAIN; } + req->result = iov_iter_count(iter); /* * Now retry read with the IOCB_WAITQ parts set in the iocb. If * we get -EIOCBQUEUED, then we'll get a notification when the From 0db2efb3bff879566f05341d94c3de00ac95c4cc Mon Sep 17 00:00:00 2001 From: Liu Shixin Date: Fri, 23 Sep 2022 12:21:13 +0800 Subject: [PATCH 516/610] mm: hugetlb: fix UAF in hugetlb_handle_userfault commit 958f32ce832ba781ac20e11bb2d12a9352ea28fc upstream. The vma_lock and hugetlb_fault_mutex are dropped before handling userfault and reacquire them again after handle_userfault(), but reacquire the vma_lock could lead to UAF[1,2] due to the following race, hugetlb_fault hugetlb_no_page /*unlock vma_lock */ hugetlb_handle_userfault handle_userfault /* unlock mm->mmap_lock*/ vm_mmap_pgoff do_mmap mmap_region munmap_vma_range /* clean old vma */ /* lock vma_lock again <--- UAF */ /* unlock vma_lock */ Since the vma_lock will unlock immediately after hugetlb_handle_userfault(), let's drop the unneeded lock and unlock in hugetlb_handle_userfault() to fix the issue. [1] https://lore.kernel.org/linux-mm/000000000000d5e00a05e834962e@google.com/ [2] https://lore.kernel.org/linux-mm/20220921014457.1668-1-liuzixian4@huawei.com/ Link: https://lkml.kernel.org/r/20220923042113.137273-1-liushixin2@huawei.com Fixes: 1a1aad8a9b7b ("userfaultfd: hugetlbfs: add userfaultfd hugetlb hook") Signed-off-by: Liu Shixin Signed-off-by: Kefeng Wang Reported-by: syzbot+193f9cee8638750b23cf@syzkaller.appspotmail.com Reported-by: Liu Zixian Reviewed-by: Mike Kravetz Cc: David Hildenbrand Cc: John Hubbard Cc: Muchun Song Cc: Sidhartha Kumar Cc: [4.14+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/hugetlb.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d61b665c45d6..23085498f5c8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4844,7 +4844,6 @@ static inline vm_fault_t hugetlb_handle_userfault(struct vm_area_struct *vma, unsigned long haddr, unsigned long reason) { - vm_fault_t ret; u32 hash; struct vm_fault vmf = { .vma = vma, @@ -4861,18 +4860,14 @@ static inline vm_fault_t hugetlb_handle_userfault(struct vm_area_struct *vma, }; /* - * hugetlb_fault_mutex and i_mmap_rwsem must be - * dropped before handling userfault. Reacquire - * after handling fault to make calling code simpler. + * vma_lock and hugetlb_fault_mutex must be dropped before handling + * userfault. Also mmap_lock will be dropped during handling + * userfault, any vma operation should be careful from here. */ hash = hugetlb_fault_mutex_hash(mapping, idx); mutex_unlock(&hugetlb_fault_mutex_table[hash]); i_mmap_unlock_read(mapping); - ret = handle_userfault(&vmf, reason); - i_mmap_lock_read(mapping); - mutex_lock(&hugetlb_fault_mutex_table[hash]); - - return ret; + return handle_userfault(&vmf, reason); } static vm_fault_t hugetlb_no_page(struct mm_struct *mm, @@ -4889,6 +4884,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm, spinlock_t *ptl; unsigned long haddr = address & huge_page_mask(h); bool new_page, new_pagecache_page = false; + u32 hash = hugetlb_fault_mutex_hash(mapping, idx); /* * Currently, we are forced to kill the process in the event the @@ -4898,7 +4894,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm, if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) { pr_warn_ratelimited("PID %d killed due to inadequate hugepage pool\n", current->pid); - return ret; + goto out; } /* @@ -4915,12 +4911,10 @@ retry: page = find_lock_page(mapping, idx); if (!page) { /* Check for page in userfault range */ - if (userfaultfd_missing(vma)) { - ret = hugetlb_handle_userfault(vma, mapping, idx, + if (userfaultfd_missing(vma)) + return hugetlb_handle_userfault(vma, mapping, idx, flags, haddr, VM_UFFD_MISSING); - goto out; - } page = alloc_huge_page(vma, haddr, 0); if (IS_ERR(page)) { @@ -4980,10 +4974,9 @@ retry: if (userfaultfd_minor(vma)) { unlock_page(page); put_page(page); - ret = hugetlb_handle_userfault(vma, mapping, idx, + return hugetlb_handle_userfault(vma, mapping, idx, flags, haddr, VM_UFFD_MINOR); - goto out; } } @@ -5034,6 +5027,8 @@ retry: unlock_page(page); out: + mutex_unlock(&hugetlb_fault_mutex_table[hash]); + i_mmap_unlock_read(mapping); return ret; backout: @@ -5131,10 +5126,12 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, mutex_lock(&hugetlb_fault_mutex_table[hash]); entry = huge_ptep_get(ptep); - if (huge_pte_none(entry)) { - ret = hugetlb_no_page(mm, vma, mapping, idx, address, ptep, flags); - goto out_mutex; - } + if (huge_pte_none(entry)) + /* + * hugetlb_no_page will drop vma lock and hugetlb fault + * mutex internally, which make us return immediately. + */ + return hugetlb_no_page(mm, vma, mapping, idx, address, ptep, flags); ret = 0; From b8989e95d74ebf1d0e9c32d1ffe2a5590a76b0a1 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 5 Oct 2022 22:02:37 -0400 Subject: [PATCH 517/610] net: ieee802154: return -EINVAL for unknown addr type commit 30393181fdbc1608cc683b4ee99dcce05ffcc8c7 upstream. This patch adds handling to return -EINVAL for an unknown addr type. The current behaviour is to return 0 as successful but the size of an unknown addr type is not defined and should return an error like -EINVAL. Fixes: 94160108a70c ("net/ieee802154: fix uninit value bug in dgram_sendmsg") Signed-off-by: Alexander Aring Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/ieee802154_netdev.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index a8994f307fc3..03b64bf876a4 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -185,21 +185,27 @@ static inline int ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len) { struct ieee802154_addr_sa *sa; + int ret = 0; sa = &daddr->addr; if (len < IEEE802154_MIN_NAMELEN) return -EINVAL; switch (sa->addr_type) { + case IEEE802154_ADDR_NONE: + break; case IEEE802154_ADDR_SHORT: if (len < IEEE802154_NAMELEN_SHORT) - return -EINVAL; + ret = -EINVAL; break; case IEEE802154_ADDR_LONG: if (len < IEEE802154_NAMELEN_LONG) - return -EINVAL; + ret = -EINVAL; + break; + default: + ret = -EINVAL; break; } - return 0; + return ret; } static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, From 28787ff9fbeaf57684eb64cc33e2ec8ceedf21b5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Sep 2022 10:59:47 +0200 Subject: [PATCH 518/610] ALSA: usb-audio: Fix last interface check for registration commit 39efc9c8a973ddff5918191525d1679d0fb368ea upstream. The recent fix in commit 6392dcd1d0c7 ("ALSA: usb-audio: Register card at the last interface") tried to delay the card registration until the last found interface is probed. It assumed that the probe callback gets called for those later interfaces, but it's not always true; as the driver loops over the descriptor and probes the matching ones, it's not separately called via multiple probe calls. This results in the missing card registration, i.e. no sound device. For addressing this problem, replace the check whether the last interface is processed with usb_interface_claimed() instead of the comparison with the probe interface number. Fixes: 6392dcd1d0c7 ("ALSA: usb-audio: Register card at the last interface") Link: https://lore.kernel.org/r/20220915085947.7922-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 207c212eabde..4526f1d1fd6e 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -883,7 +883,7 @@ static int usb_audio_probe(struct usb_interface *intf, * one given via option */ if (check_delayed_register_option(chip) == ifnum || - chip->last_iface == ifnum) { + usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) { err = snd_card_register(chip->card); if (err < 0) goto __error; From d7eadffce0329c76b39ed182c3d13d6d0fbcdb97 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Sun, 9 Oct 2022 18:10:38 +0800 Subject: [PATCH 519/610] blk-wbt: fix that 'rwb->wc' is always set to 1 in wbt_init() commit 285febabac4a16655372d23ff43e89ff6f216691 upstream. commit 8c5035dfbb94 ("blk-wbt: call rq_qos_add() after wb_normal is initialized") moves wbt_set_write_cache() before rq_qos_add(), which is wrong because wbt_rq_qos() is still NULL. Fix the problem by removing wbt_set_write_cache() and setting 'rwb->wc' directly. Noted that this patch also remove the redundant setting of 'rab->wc'. Fixes: 8c5035dfbb94 ("blk-wbt: call rq_qos_add() after wb_normal is initialized") Reported-by: kernel test robot Link: https://lore.kernel.org/r/202210081045.77ddf59b-yujie.liu@intel.com Signed-off-by: Yu Kuai Reviewed-by: Ming Lei Link: https://lore.kernel.org/r/20221009101038.1692875-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/blk-wbt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index d5aa2a32df25..e91d334b2788 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -841,12 +841,11 @@ int wbt_init(struct request_queue *q) rwb->last_comp = rwb->last_issue = jiffies; rwb->win_nsec = RWB_WINDOW_NSEC; rwb->enable_state = WBT_STATE_ON_DEFAULT; - rwb->wc = 1; + rwb->wc = test_bit(QUEUE_FLAG_WC, &q->queue_flags); rwb->rq_depth.default_depth = RWB_DEF_DEPTH; rwb->min_lat_nsec = wbt_default_latency_nsec(q); wbt_queue_depth_changed(&rwb->rqos); - wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags)); /* * Assign rwb and add the stats callback. From 9c65eef9d6c93a4a3e1de6610770c238e05412f7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 23 Aug 2022 19:42:16 -0700 Subject: [PATCH 520/610] net: ethernet: ti: davinci_mdio: fix build for mdio bitbang uses commit 35bbe652c421037822aba29423f5f1f7d0d69f3f upstream. davinci_mdio.c uses mdio bitbang APIs, so it should select MDIO_BITBANG to prevent build errors. arm-linux-gnueabi-ld: drivers/net/ethernet/ti/davinci_mdio.o: in function `davinci_mdio_remove': drivers/net/ethernet/ti/davinci_mdio.c:649: undefined reference to `free_mdio_bitbang' arm-linux-gnueabi-ld: drivers/net/ethernet/ti/davinci_mdio.o: in function `davinci_mdio_probe': drivers/net/ethernet/ti/davinci_mdio.c:545: undefined reference to `alloc_mdio_bitbang' arm-linux-gnueabi-ld: drivers/net/ethernet/ti/davinci_mdio.o: in function `davinci_mdiobb_read': drivers/net/ethernet/ti/davinci_mdio.c:236: undefined reference to `mdiobb_read' arm-linux-gnueabi-ld: drivers/net/ethernet/ti/davinci_mdio.o: in function `davinci_mdiobb_write': drivers/net/ethernet/ti/davinci_mdio.c:253: undefined reference to `mdiobb_write' Fixes: d04807b80691 ("net: ethernet: ti: davinci_mdio: Add workaround for errata i2329") Signed-off-by: Randy Dunlap Cc: Grygorii Strashko Cc: Ravi Gunasekaran Cc: Eric Dumazet Cc: Paolo Abeni Cc: Naresh Kamboju Cc: Sudip Mukherjee (Codethink) Link: https://lore.kernel.org/r/20220824024216.4939-1-rdunlap@infradead.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/ti/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index affcf92cd3aa..6cba4d2c4483 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -33,6 +33,7 @@ config TI_DAVINCI_MDIO tristate "TI DaVinci MDIO Support" depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST select PHYLIB + select MDIO_BITBANG help This driver supports TI's DaVinci MDIO module. From de904d0fe1cbadba91ac8de05640c6b6cab6c032 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 4 Oct 2022 21:47:49 -0400 Subject: [PATCH 521/610] Revert "net/ieee802154: reject zero-sized raw_sendmsg()" [ Upstream commit 2eb2756f6c9e9621e022d78321ce40a62c4520b5 ] This reverts commit 3a4d061c699bd3eedc80dc97a4b2a2e1af83c6f5. There is a v2 which does return zero if zero length is given. Signed-off-by: Alexander Aring Link: https://lore.kernel.org/r/20221005014750.3685555-1-aahringo@redhat.com Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin --- net/ieee802154/socket.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c index f160cfc3e8f0..fd5862f9e26a 100644 --- a/net/ieee802154/socket.c +++ b/net/ieee802154/socket.c @@ -251,9 +251,6 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) return -EOPNOTSUPP; } - if (!size) - return -EINVAL; - lock_sock(sk); if (!sk->sk_bound_dev_if) dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); From 34f31a2b667914ab701ca725554a0b447809d7ef Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 4 Oct 2022 21:47:50 -0400 Subject: [PATCH 522/610] net/ieee802154: don't warn zero-sized raw_sendmsg() [ Upstream commit b12e924a2f5b960373459c8f8a514f887adf5cac ] syzbot is hitting skb_assert_len() warning at __dev_queue_xmit() [1], for PF_IEEE802154 socket's zero-sized raw_sendmsg() request is hitting __dev_queue_xmit() with skb->len == 0. Since PF_IEEE802154 socket's zero-sized raw_sendmsg() request was able to return 0, don't call __dev_queue_xmit() if packet length is 0. ---------- #include #include int main(int argc, char *argv[]) { struct sockaddr_in addr = { .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK) }; struct iovec iov = { }; struct msghdr hdr = { .msg_name = &addr, .msg_namelen = sizeof(addr), .msg_iov = &iov, .msg_iovlen = 1 }; sendmsg(socket(PF_IEEE802154, SOCK_RAW, 0), &hdr, 0); return 0; } ---------- Note that this might be a sign that commit fd1894224407c484 ("bpf: Don't redirect packets with invalid pkt_len") should be reverted, for skb->len == 0 was acceptable for at least PF_IEEE802154 socket. Link: https://syzkaller.appspot.com/bug?extid=5ea725c25d06fb9114c4 [1] Reported-by: syzbot Fixes: fd1894224407c484 ("bpf: Don't redirect packets with invalid pkt_len") Signed-off-by: Tetsuo Handa Signed-off-by: Alexander Aring Link: https://lore.kernel.org/r/20221005014750.3685555-2-aahringo@redhat.com Signed-off-by: Stefan Schmidt Signed-off-by: Sasha Levin --- net/ieee802154/socket.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c index fd5862f9e26a..d0aaa0346cb1 100644 --- a/net/ieee802154/socket.c +++ b/net/ieee802154/socket.c @@ -272,6 +272,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) err = -EMSGSIZE; goto out_dev; } + if (!size) { + err = 0; + goto out_dev; + } hlen = LL_RESERVED_SPACE(dev); tlen = dev->needed_tailroom; From e1591557e3a082b5ee7fe2205bea4827cdf523c2 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Fri, 14 Oct 2022 08:21:03 -0700 Subject: [PATCH 523/610] drm/amd/display: Fix build breakage with CONFIG_DEBUG_FS=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 2130b87b2273389cafe6765bf09ef564cda01407 upstream. After commit 8799c0be89eb ("drm/amd/display: Fix vblank refcount in vrr transition"), a build with CONFIG_DEBUG_FS=n is broken due to a misplaced brace, along the lines of: In file included from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_trace.h:39, from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:41: drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: At top level: ./include/drm/drm_atomic.h:864:9: error: expected identifier or ‘(’ before ‘for’ 864 | for ((__i) = 0; \ | ^~~ drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:8317:9: note: in expansion of macro ‘for_each_new_crtc_in_state’ 8317 | for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) | ^~~~~~~~~~~~~~~~~~~~~~~~~~ Move the brace within the #ifdef so that the file can be built with or without CONFIG_DEBUG_FS. Fixes: 8799c0be89eb ("drm/amd/display: Fix vblank refcount in vrr transition") Signed-off-by: Nathan Chancellor Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 484c28919271..d9f99212e624 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9679,8 +9679,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) crtc, dm_new_crtc_state, cur_crc_src)) DRM_DEBUG_DRIVER("Failed to configure crc source"); } -#endif } +#endif } for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) From 371aaf6b48f5b20708dfc8cc319d66c7cce7f50a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 5 Oct 2022 01:29:03 +0900 Subject: [PATCH 524/610] Kconfig.debug: simplify the dependency of DEBUG_INFO_DWARF4/5 commit 4f001a21080ff2e2f0e1c3692f5e119aedbb3bc1 upstream. Commit c0a5c81ca9be ("Kconfig.debug: drop GCC 5+ version check for DWARF5") could have cleaned up the code a bit more. "CC_IS_CLANG &&" is unneeded. No functional change is intended. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor [nathan: Only apply to DWARF5, as 5.15 does not have 32ef9e5054ec032] Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 7fd3fa05379e..095156b70cbe 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -295,7 +295,7 @@ config DEBUG_INFO_DWARF4 config DEBUG_INFO_DWARF5 bool "Generate DWARF Version 5 debuginfo" - depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502))) + depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502) depends on !DEBUG_INFO_BTF help Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc From 84cd0b20fada657debc0a6bc820648c120588ea6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 5 Oct 2022 01:29:04 +0900 Subject: [PATCH 525/610] Kconfig.debug: add toolchain checks for DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT commit bb1435f3f575b5213eaf27434efa3971f51c01de upstream. CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT does not give explicit -gdwarf-* flag. The actual DWARF version is up to the toolchain. The combination of GCC and GAS works fine, and Clang with the integrated assembler is good too. The combination of Clang and GAS is tricky, but at least, the -g flag works for Clang <=13, which defaults to DWARF v4. Clang 14 switched its default to DWARF v5. Now, CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT has the same issue as addressed by commit 98cd6f521f10 ("Kconfig: allow explicit opt in to DWARF v5"). CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y for Clang >= 14 and GAS < 2.35 produces a ton of errors like follows: /tmp/main-c2741c.s: Assembler messages: /tmp/main-c2741c.s:109: Error: junk at end of line, first unrecognized character is `"' /tmp/main-c2741c.s:109: Error: file number less than one Add 'depends on' to check toolchains. Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor [nathan: Fix conflict due to lack of f9b3cd24578401e] Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 095156b70cbe..646778e68f00 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -274,6 +274,7 @@ choice config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT bool "Rely on the toolchain's implicit default DWARF version" + depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502) help The implicit default version of DWARF debug info produced by a toolchain changes over time. From 0e63de6d7e4ca9257fb32c0293bbd95e355d0f2d Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Fri, 14 Oct 2022 13:42:11 -0700 Subject: [PATCH 526/610] lib/Kconfig.debug: Add check for non-constant .{s,u}leb128 support to DWARF5 commit 0a6de78cff600cb991f2a1b7ed376935871796a0 upstream. When building with a RISC-V kernel with DWARF5 debug info using clang and the GNU assembler, several instances of the following error appear: /tmp/vgettimeofday-48aa35.s:2963: Error: non-constant .uleb128 is not supported Dumping the .s file reveals these .uleb128 directives come from .debug_loc and .debug_ranges: .Ldebug_loc0: .byte 4 # DW_LLE_offset_pair .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset .byte 1 # Loc expr size .byte 90 # DW_OP_reg10 .byte 0 # DW_LLE_end_of_list .Ldebug_ranges0: .byte 4 # DW_RLE_offset_pair .uleb128 .Ltmp6-.Lfunc_begin0 # starting offset .uleb128 .Ltmp27-.Lfunc_begin0 # ending offset .byte 4 # DW_RLE_offset_pair .uleb128 .Ltmp28-.Lfunc_begin0 # starting offset .uleb128 .Ltmp30-.Lfunc_begin0 # ending offset .byte 0 # DW_RLE_end_of_list There is an outstanding binutils issue to support a non-constant operand to .sleb128 and .uleb128 in GAS for RISC-V but there does not appear to be any movement on it, due to concerns over how it would work with linker relaxation. To avoid these build errors, prevent DWARF5 from being selected when using clang and an assembler that does not have support for these symbol deltas, which can be easily checked in Kconfig with as-instr plus the small test program from the dwz test suite from the binutils issue. Link: https://sourceware.org/bugzilla/show_bug.cgi?id=27215 Link: https://github.com/ClangBuiltLinux/linux/issues/1719 Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Masahiro Yamada [nathan: Fix conflicts due to lack of f9b3cd24578401e] Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig.debug | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 646778e68f00..1699b2124558 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -208,6 +208,11 @@ config DEBUG_BUGVERBOSE endmenu # "printk and dmesg options" +# Clang is known to generate .{s,u}leb128 with symbol deltas with DWARF5, which +# some targets may not support: https://sourceware.org/bugzilla/show_bug.cgi?id=27215 +config AS_HAS_NON_CONST_LEB128 + def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:) + menu "Compile-time checks and compiler options" config DEBUG_INFO @@ -274,7 +279,7 @@ choice config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT bool "Rely on the toolchain's implicit default DWARF version" - depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502) + depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128) help The implicit default version of DWARF debug info produced by a toolchain changes over time. @@ -296,7 +301,7 @@ config DEBUG_INFO_DWARF4 config DEBUG_INFO_DWARF5 bool "Generate DWARF Version 5 debuginfo" - depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502) + depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128) depends on !DEBUG_INFO_BTF help Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc From 55c824b62067ddcf6d60356cef4d960bc4607249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jerry=20Lee=20=E6=9D=8E=E4=BF=AE=E8=B3=A2?= Date: Mon, 18 Jul 2022 10:25:19 +0000 Subject: [PATCH 527/610] ext4: continue to expand file system when the target size doesn't reach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit df3cb754d13d2cd5490db9b8d536311f8413a92e upstream. When expanding a file system from (16TiB-2MiB) to 18TiB, the operation exits early which leads to result inconsistency between resize2fs and Ext4 kernel driver. === before === ○ → resize2fs /dev/mapper/thin resize2fs 1.45.5 (07-Jan-2020) Filesystem at /dev/mapper/thin is mounted on /mnt/test; on-line resizing required old_desc_blocks = 2048, new_desc_blocks = 2304 The filesystem on /dev/mapper/thin is now 4831837696 (4k) blocks long. [ 865.186308] EXT4-fs (dm-5): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none. [ 912.091502] dm-4: detected capacity change from 34359738368 to 38654705664 [ 970.030550] dm-5: detected capacity change from 34359734272 to 38654701568 [ 1000.012751] EXT4-fs (dm-5): resizing filesystem from 4294966784 to 4831837696 blocks [ 1000.012878] EXT4-fs (dm-5): resized filesystem to 4294967296 === after === [ 129.104898] EXT4-fs (dm-5): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none. [ 143.773630] dm-4: detected capacity change from 34359738368 to 38654705664 [ 198.203246] dm-5: detected capacity change from 34359734272 to 38654701568 [ 207.918603] EXT4-fs (dm-5): resizing filesystem from 4294966784 to 4831837696 blocks [ 207.918754] EXT4-fs (dm-5): resizing filesystem from 4294967296 to 4831837696 blocks [ 207.918758] EXT4-fs (dm-5): Converting file system to meta_bg [ 207.918790] EXT4-fs (dm-5): resizing filesystem from 4294967296 to 4831837696 blocks [ 221.454050] EXT4-fs (dm-5): resized to 4658298880 blocks [ 227.634613] EXT4-fs (dm-5): resized filesystem to 4831837696 Signed-off-by: Jerry Lee Link: https://lore.kernel.org/r/PU1PR04MB22635E739BD21150DC182AC6A18C9@PU1PR04MB2263.apcprd04.prod.outlook.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/resize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 862cbbc01d6e..62bbfe8960f3 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -2088,7 +2088,7 @@ retry: goto out; } - if (ext4_blocks_count(es) == n_blocks_count) + if (ext4_blocks_count(es) == n_blocks_count && n_blocks_count_retry == 0) goto out; err = ext4_alloc_flex_bg_array(sb, n_group + 1); From 8418c1672c1ffa43bf73ba5d534a528fc1be7572 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 13 Oct 2022 14:50:28 +0200 Subject: [PATCH 528/610] thermal: intel_powerclamp: Use first online CPU as control_cpu commit 4bb7f6c2781e46fc5bd00475a66df2ea30ef330d upstream. Commit 68b99e94a4a2 ("thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash") fixed an issue related to using smp_processor_id() in preemptible context by replacing it with a pair of get_cpu()/put_cpu(), but what is needed there really is any online CPU and not necessarily the one currently running the code. Arguably, getting the one that's running the code in there is confusing. For this reason, simply give the control CPU role to the first online one which automatically will be CPU0 if it is online, so one check can be dropped from the code for an added benefit. Link: https://lore.kernel.org/linux-pm/20221011113646.GA12080@duo.ucw.cz/ Fixes: 68b99e94a4a2 ("thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash") Signed-off-by: Rafael J. Wysocki Reviewed-by: Chen Yu Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/intel/intel_powerclamp.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c index 9121ae4f5068..5b19e2d46043 100644 --- a/drivers/thermal/intel/intel_powerclamp.c +++ b/drivers/thermal/intel/intel_powerclamp.c @@ -531,11 +531,7 @@ static int start_power_clamp(void) cpus_read_lock(); /* prefer BSP */ - control_cpu = 0; - if (!cpu_online(control_cpu)) { - control_cpu = get_cpu(); - put_cpu(); - } + control_cpu = cpumask_first(cpu_online_mask); clamping = true; schedule_delayed_work(&poll_pkg_cstate_work, 0); From 7c359e28492fdfa34cdafb990f0b3a1d62fa611c Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 13 Oct 2022 09:40:59 +0200 Subject: [PATCH 529/610] gcov: support GCC 12.1 and newer compilers commit 977ef30a7d888eeb52fb6908f99080f33e5309a8 upstream. Starting with GCC 12.1, the created .gcda format can't be read by gcov tool. There are 2 significant changes to the .gcda file format that need to be supported: a) [gcov: Use system IO buffering] (23eb66d1d46a34cb28c4acbdf8a1deb80a7c5a05) changed that all sizes in the format are in bytes and not in words (4B) b) [gcov: make profile merging smarter] (72e0c742bd01f8e7e6dcca64042b9ad7e75979de) add a new checksum to the file header. Tested with GCC 7.5, 10.4, 12.2 and the current master. Link: https://lkml.kernel.org/r/624bda92-f307-30e9-9aaa-8cc678b2dfb2@suse.cz Signed-off-by: Martin Liska Tested-by: Peter Oberparleiter Reviewed-by: Peter Oberparleiter Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- kernel/gcov/gcc_4_7.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c index 460c12b7dfea..7971e989e425 100644 --- a/kernel/gcov/gcc_4_7.c +++ b/kernel/gcov/gcc_4_7.c @@ -30,6 +30,13 @@ #define GCOV_TAG_FUNCTION_LENGTH 3 +/* Since GCC 12.1 sizes are in BYTES and not in WORDS (4B). */ +#if (__GNUC__ >= 12) +#define GCOV_UNIT_SIZE 4 +#else +#define GCOV_UNIT_SIZE 1 +#endif + static struct gcov_info *gcov_info_head; /** @@ -383,12 +390,18 @@ size_t convert_to_gcda(char *buffer, struct gcov_info *info) pos += store_gcov_u32(buffer, pos, info->version); pos += store_gcov_u32(buffer, pos, info->stamp); +#if (__GNUC__ >= 12) + /* Use zero as checksum of the compilation unit. */ + pos += store_gcov_u32(buffer, pos, 0); +#endif + for (fi_idx = 0; fi_idx < info->n_functions; fi_idx++) { fi_ptr = info->functions[fi_idx]; /* Function record. */ pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION); - pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION_LENGTH); + pos += store_gcov_u32(buffer, pos, + GCOV_TAG_FUNCTION_LENGTH * GCOV_UNIT_SIZE); pos += store_gcov_u32(buffer, pos, fi_ptr->ident); pos += store_gcov_u32(buffer, pos, fi_ptr->lineno_checksum); pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum); @@ -402,7 +415,8 @@ size_t convert_to_gcda(char *buffer, struct gcov_info *info) /* Counter record. */ pos += store_gcov_u32(buffer, pos, GCOV_TAG_FOR_COUNTER(ct_idx)); - pos += store_gcov_u32(buffer, pos, ci_ptr->num * 2); + pos += store_gcov_u32(buffer, pos, + ci_ptr->num * 2 * GCOV_UNIT_SIZE); for (cv_idx = 0; cv_idx < ci_ptr->num; cv_idx++) { pos += store_gcov_u64(buffer, pos, From b6e2c54be37d5eb4f6666e6aa59cd0581c7ffc3c Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Wed, 19 Oct 2022 22:47:09 -0300 Subject: [PATCH 530/610] io-wq: Fix memory leak in worker creation commit 996d3efeb091c503afd3ee6b5e20eabf446fd955 upstream. If the CPU mask allocation for a node fails, then the memory allocated for the 'io_wqe' struct of the current node doesn't get freed on the error handling path, since it has not yet been added to the 'wqes' array. This was spotted when fuzzing v6.1-rc1 with Syzkaller: BUG: memory leak unreferenced object 0xffff8880093d5000 (size 1024): comm "syz-executor.2", pid 7701, jiffies 4295048595 (age 13.900s) 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: [<00000000cb463369>] __kmem_cache_alloc_node+0x18e/0x720 [<00000000147a3f9c>] kmalloc_node_trace+0x2a/0x130 [<000000004e107011>] io_wq_create+0x7b9/0xdc0 [<00000000c38b2018>] io_uring_alloc_task_context+0x31e/0x59d [<00000000867399da>] __io_uring_add_tctx_node.cold+0x19/0x1ba [<000000007e0e7a79>] io_uring_setup.cold+0x1b80/0x1dce [<00000000b545e9f6>] __x64_sys_io_uring_setup+0x5d/0x80 [<000000008a8a7508>] do_syscall_64+0x5d/0x90 [<000000004ac08bec>] entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: 0e03496d1967 ("io-wq: use private CPU mask") Cc: stable@vger.kernel.org Signed-off-by: Rafael Mendonca Link: https://lore.kernel.org/r/20221020014710.902201-1-rafaelmendsr@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io-wq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/io-wq.c b/fs/io-wq.c index 01d4e3ff3170..6031fb319d87 100644 --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -1152,10 +1152,10 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) wqe = kzalloc_node(sizeof(struct io_wqe), GFP_KERNEL, alloc_node); if (!wqe) goto err; + wq->wqes[node] = wqe; if (!alloc_cpumask_var(&wqe->cpu_mask, GFP_KERNEL)) goto err; cpumask_copy(wqe->cpu_mask, cpumask_of_node(node)); - wq->wqes[node] = wqe; wqe->node = alloc_node; wqe->acct[IO_WQ_ACCT_BOUND].max_workers = bounded; wqe->acct[IO_WQ_ACCT_UNBOUND].max_workers = From bd8a595958a5b02e58cdd6fed82d4ebc77b1988a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 26 Oct 2022 12:35:57 +0200 Subject: [PATCH 531/610] Linux 5.15.75 Link: https://lore.kernel.org/r/20221024113044.976326639@linuxfoundation.org Tested-by: Jon Hunter Tested-by: Florian Fainelli Tested-by: Allen Pais Tested-by: Shuah Khan Tested-by: Kelsey Steele Tested-by: Bagas Sanjaya Tested-by: Slade Watkins Tested-by: Guenter Roeck Tested-by: Ron Economos 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 e2bed548d450..e3d63d529e0d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 15 -SUBLEVEL = 74 +SUBLEVEL = 75 EXTRAVERSION = NAME = Trick or Treat From 5b20aacff7ada539c597f863045422e632b10b5e Mon Sep 17 00:00:00 2001 From: Jean-Francois Le Fillatre Date: Wed, 24 Aug 2022 21:14:36 +0200 Subject: [PATCH 532/610] r8152: add PID for the Lenovo OneLink+ Dock commit 1bd3a383075c64d638e65d263c9267b08ee7733c upstream. The Lenovo OneLink+ Dock contains an RTL8153 controller that behaves as a broken CDC device by default. Add the custom Lenovo PID to the r8152 driver to support it properly. Also, systems compatible with this dock provide a BIOS option to enable MAC address passthrough (as per Lenovo document "ThinkPad Docking Solutions 2017"). Add the custom PID to the MAC passthrough list too. Tested on a ThinkPad 13 1st gen with the expected results: passthrough disabled: Invalid header when reading pass-thru MAC addr passthrough enabled: Using pass-thru MAC addr XX:XX:XX:XX:XX:XX Signed-off-by: Jean-Francois Le Fillatre Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/cdc_ether.c | 7 +++++++ drivers/net/usb/r8152.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 9b4dfa3001d6..c6b0de1b752f 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -776,6 +776,13 @@ static const struct usb_device_id products[] = { }, #endif +/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* ThinkPad USB-C Dock (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index c7169243aa6e..109c288d8b47 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -770,6 +770,7 @@ enum rtl8152_flags { RX_EPROTO, }; +#define DEVICE_ID_THINKPAD_ONELINK_PLUS_DOCK 0x3054 #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 #define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387 @@ -9651,6 +9652,7 @@ static int rtl8152_probe(struct usb_interface *intf, if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO) { switch (le16_to_cpu(udev->descriptor.idProduct)) { + case DEVICE_ID_THINKPAD_ONELINK_PLUS_DOCK: case DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2: case DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2: tp->lenovo_macpassthru = 1; @@ -9809,6 +9811,7 @@ static const struct usb_device_id rtl8152_table[] = { REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927), REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101), REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f), + REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3054), REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062), REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069), REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082), From f9681a67503ec15ba2b1e6313fc6149d90efb631 Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Tue, 25 Jan 2022 20:08:33 +0530 Subject: [PATCH 533/610] arm64/mm: Consolidate TCR_EL1 fields commit e921da6bc7cac5f0e8458fe5df18ae08eb538f54 upstream. This renames and moves SYS_TCR_EL1_TCMA1 and SYS_TCR_EL1_TCMA0 definitions into pgtable-hwdef.h thus consolidating all TCR fields in a single header. This does not cause any functional change. Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Acked-by: Catalin Marinas Signed-off-by: Anshuman Khandual Link: https://lore.kernel.org/r/1643121513-21854-1-git-send-email-anshuman.khandual@arm.com Signed-off-by: Will Deacon Cc: Evgenii Stepanov Signed-off-by: Greg Kroah-Hartman --- arch/arm64/include/asm/pgtable-hwdef.h | 2 ++ arch/arm64/include/asm/sysreg.h | 4 ---- arch/arm64/mm/proc.S | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 40085e53f573..66671ff05183 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -273,6 +273,8 @@ #define TCR_NFD1 (UL(1) << 54) #define TCR_E0PD0 (UL(1) << 55) #define TCR_E0PD1 (UL(1) << 56) +#define TCR_TCMA0 (UL(1) << 57) +#define TCR_TCMA1 (UL(1) << 58) /* * TTBR. diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 394fc5998a4b..f79f3720e4cb 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1094,10 +1094,6 @@ #define CPACR_EL1_ZEN_EL0EN (BIT(17)) /* enable EL0 access, if EL1EN set */ #define CPACR_EL1_ZEN (CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN) -/* TCR EL1 Bit Definitions */ -#define SYS_TCR_EL1_TCMA1 (BIT(58)) -#define SYS_TCR_EL1_TCMA0 (BIT(57)) - /* GCR_EL1 Definitions */ #define SYS_GCR_EL1_RRND (BIT(16)) #define SYS_GCR_EL1_EXCL_MASK 0xffffUL diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index d35c90d2e47a..50bbed947bec 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -46,7 +46,7 @@ #endif #ifdef CONFIG_KASAN_HW_TAGS -#define TCR_MTE_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1 +#define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1 #else /* * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on From d80db2f1450c50cdc794cda1ef02bac4e8a761ca Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Mon, 18 Oct 2021 09:20:59 +0200 Subject: [PATCH 534/610] usb: gadget: uvc: consistently use define for headerlen commit 859c675d84d488e2f9b515c713ea890c9f045f0c upstream. The uvc request headerlen of 2 was defined as UVCG_REQUEST_HEADER_LEN in commit e81e7f9a0eb9 ("usb: gadget: uvc: add scatter gather support"). We missed to use it consistently. This patch fixes that. Reviewed-by: Paul Elder Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20211018072059.11465-1-m.grzeschik@pengutronix.de Reviewed-by: Laurent Pinchart Cc: Dan Vacura Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/uvc.h | 4 +++- drivers/usb/gadget/function/uvc_video.c | 6 +++--- drivers/usb/gadget/function/uvc_video.h | 2 -- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 0966c5aa2492..9727111959b0 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -69,6 +69,8 @@ extern unsigned int uvc_gadget_trace_param; #define UVC_MAX_REQUEST_SIZE 64 #define UVC_MAX_EVENTS 4 +#define UVCG_REQUEST_HEADER_LEN 2 + /* ------------------------------------------------------------------------ * Structures */ @@ -77,7 +79,7 @@ struct uvc_request { u8 *req_buffer; struct uvc_video *video; struct sg_table sgt; - u8 header[2]; + u8 header[UVCG_REQUEST_HEADER_LEN]; }; struct uvc_video { diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index e170e88abf3a..d222200b0f38 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -33,7 +33,7 @@ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf, if (buf->bytesused - video->queue.buf_used <= len - UVCG_REQUEST_HEADER_LEN) data[1] |= UVC_STREAM_EOF; - return 2; + return UVCG_REQUEST_HEADER_LEN; } static int @@ -302,8 +302,8 @@ uvc_video_alloc_requests(struct uvc_video *video) list_add_tail(&video->ureq[i].req->list, &video->req_free); /* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */ sg_alloc_table(&video->ureq[i].sgt, - DIV_ROUND_UP(req_size - 2, PAGE_SIZE) + 2, - GFP_KERNEL); + DIV_ROUND_UP(req_size - UVCG_REQUEST_HEADER_LEN, + PAGE_SIZE) + 2, GFP_KERNEL); } video->req_size = req_size; diff --git a/drivers/usb/gadget/function/uvc_video.h b/drivers/usb/gadget/function/uvc_video.h index 9bf19475f6f9..03adeefa343b 100644 --- a/drivers/usb/gadget/function/uvc_video.h +++ b/drivers/usb/gadget/function/uvc_video.h @@ -12,8 +12,6 @@ #ifndef __UVC_VIDEO_H__ #define __UVC_VIDEO_H__ -#define UVCG_REQUEST_HEADER_LEN 2 - struct uvc_video; int uvcg_video_enable(struct uvc_video *video, int enable); From 2f54ce7392d7c7cc5760f625c1b36c36a9f64cf4 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Fri, 22 Oct 2021 11:32:22 +0200 Subject: [PATCH 535/610] usb: gadget: uvc: use on returned header len in video_encode_isoc_sg commit f262ce66d40cc6858d1fcb11e7b7f960448a4f38 upstream. The function uvc_video_encode_header function returns the number of bytes used for the header. We change the video_encode_isoc_sg function to use the returned header_len rather than UVCG_REQUEST_HEADER_LEN and make the encode function more flexible. Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20211022093223.26493-1-m.grzeschik@pengutronix.de Cc: Dan Vacura Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/uvc_video.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index d222200b0f38..fb414c1dd6cd 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -104,22 +104,22 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, unsigned int len = video->req_size; unsigned int sg_left, part = 0; unsigned int i; - int ret; + int header_len; sg = ureq->sgt.sgl; sg_init_table(sg, ureq->sgt.nents); /* Init the header. */ - ret = uvc_video_encode_header(video, buf, ureq->header, + header_len = uvc_video_encode_header(video, buf, ureq->header, video->req_size); - sg_set_buf(sg, ureq->header, UVCG_REQUEST_HEADER_LEN); - len -= ret; + sg_set_buf(sg, ureq->header, header_len); + len -= header_len; if (pending <= len) len = pending; req->length = (len == pending) ? - len + UVCG_REQUEST_HEADER_LEN : video->req_size; + len + header_len : video->req_size; /* Init the pending sgs with payload */ sg = sg_next(sg); @@ -148,7 +148,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, req->num_sgs = i + 1; req->length -= len; - video->queue.buf_used += req->length - UVCG_REQUEST_HEADER_LEN; + video->queue.buf_used += req->length - header_len; if (buf->bytesused == video->queue.buf_used || !buf->sg) { video->queue.buf_used = 0; From aee340dccf5a09a4a346db7a46cef6cf26cb48fa Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Sun, 3 Apr 2022 01:27:42 +0200 Subject: [PATCH 536/610] usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer commit 61aa709ca58a0dbeeb817bfa9230c1a92979f2c6 upstream. The function uvcg_queue_next_buffer is used different than its name suggests. The return value nextbuf is never used by any caller. This patch reworks the function to its actual purpose, by removing the unused code and renaming it. The function name uvcg_complete_buffer makes it more clear that it is actually marking the current video buffer as complete. Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20220402232744.3622565-2-m.grzeschik@pengutronix.de Cc: Dan Vacura Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/uvc_queue.c | 13 ++----------- drivers/usb/gadget/function/uvc_queue.h | 2 +- drivers/usb/gadget/function/uvc_video.c | 6 +++--- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index a64b842665b9..d9eda91ba4de 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -335,24 +335,17 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable) } /* called with &queue_irqlock held.. */ -struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, +void uvcg_complete_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { - struct uvc_buffer *nextbuf; - if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->length != buf->bytesused) { buf->state = UVC_BUF_STATE_QUEUED; vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0); - return buf; + return; } list_del(&buf->queue); - if (!list_empty(&queue->irqqueue)) - nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - else - nextbuf = NULL; buf->buf.field = V4L2_FIELD_NONE; buf->buf.sequence = queue->sequence++; @@ -360,8 +353,6 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); - - return nextbuf; } struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue) diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 05360a0767f6..b668927b5d2c 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -93,7 +93,7 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect); int uvcg_queue_enable(struct uvc_video_queue *queue, int enable); -struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, +void uvcg_complete_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue); diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index fb414c1dd6cd..1b8d8b9bb3ec 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -83,7 +83,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video, if (buf->bytesused == video->queue.buf_used) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; - uvcg_queue_next_buffer(&video->queue, buf); + uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; video->payload_size = 0; @@ -154,7 +154,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; buf->offset = 0; - uvcg_queue_next_buffer(&video->queue, buf); + uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; } } @@ -181,7 +181,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, if (buf->bytesused == video->queue.buf_used) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; - uvcg_queue_next_buffer(&video->queue, buf); + uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; } } From db11d8c72a5d8e740329f0fb4a626415598249f7 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Sun, 3 Apr 2022 01:27:43 +0200 Subject: [PATCH 537/610] usb: gadget: uvc: giveback vb2 buffer on req complete commit 9b969f93bcef9b3d9e92f1810e22bbd6c344a0e5 upstream. On uvc_video_encode_isoc_sg the mapped vb2 buffer is returned to early. Only after the last usb_request worked with the buffer it is allowed to give it back to vb2. This patch fixes that. Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20220402232744.3622565-3-m.grzeschik@pengutronix.de Cc: Dan Vacura Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/uvc.h | 1 + drivers/usb/gadget/function/uvc_queue.c | 2 -- drivers/usb/gadget/function/uvc_video.c | 11 ++++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 9727111959b0..d1a4ef74742b 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -80,6 +80,7 @@ struct uvc_request { struct uvc_video *video; struct sg_table sgt; u8 header[UVCG_REQUEST_HEADER_LEN]; + struct uvc_buffer *last_buf; }; struct uvc_video { diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index d9eda91ba4de..ec299f5cc65a 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -345,8 +345,6 @@ void uvcg_complete_buffer(struct uvc_video_queue *queue, return; } - list_del(&buf->queue); - buf->buf.field = V4L2_FIELD_NONE; buf->buf.sequence = queue->sequence++; buf->buf.vb2_buf.timestamp = ktime_get_ns(); diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 1b8d8b9bb3ec..8b49bbcd894e 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -83,6 +83,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video, if (buf->bytesused == video->queue.buf_used) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; + list_del(&buf->queue); uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; @@ -154,8 +155,9 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; buf->offset = 0; - uvcg_complete_buffer(&video->queue, buf); + list_del(&buf->queue); video->fid ^= UVC_STREAM_FID; + ureq->last_buf = buf; } } @@ -181,6 +183,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, if (buf->bytesused == video->queue.buf_used) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; + list_del(&buf->queue); uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; } @@ -231,6 +234,11 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) uvcg_queue_cancel(queue, 0); } + if (ureq->last_buf) { + uvcg_complete_buffer(&video->queue, ureq->last_buf); + ureq->last_buf = NULL; + } + spin_lock_irqsave(&video->req_lock, flags); list_add_tail(&req->list, &video->req_free); spin_unlock_irqrestore(&video->req_lock, flags); @@ -298,6 +306,7 @@ uvc_video_alloc_requests(struct uvc_video *video) video->ureq[i].req->complete = uvc_video_complete; video->ureq[i].req->context = &video->ureq[i]; video->ureq[i].video = video; + video->ureq[i].last_buf = NULL; list_add_tail(&video->ureq[i].req->list, &video->req_free); /* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */ From 738515cf8bb48c6a1a8a59db140bd226a4c5a70a Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Sun, 3 Apr 2022 01:27:44 +0200 Subject: [PATCH 538/610] usb: gadget: uvc: improve sg exit condition commit aef11279888c00e1841a3533a35d279285af3a51 upstream. The exit condition to quit iterating over the sg_list, while encoding the sg entries, has to consider the case that the dma_len of the entry could be zero. This patch takes this condition to account. Signed-off-by: Michael Grzeschik Link: https://lore.kernel.org/r/20220402232744.3622565-4-m.grzeschik@pengutronix.de Cc: Dan Vacura Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/uvc_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 8b49bbcd894e..1889d75f8788 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -126,7 +126,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, sg = sg_next(sg); for_each_sg(sg, iter, ureq->sgt.nents - 1, i) { - if (!len || !buf->sg) + if (!len || !buf->sg || !sg_dma_len(buf->sg)) break; sg_left = sg_dma_len(buf->sg) - buf->offset; From 8ddc58e0e312f85e975f350cbe43ba1d9836eb1f Mon Sep 17 00:00:00 2001 From: James Morse Date: Thu, 14 Jul 2022 17:15:23 +0100 Subject: [PATCH 539/610] arm64: errata: Remove AES hwcap for COMPAT tasks commit 44b3834b2eed595af07021b1c64e6f9bc396398b upstream. Cortex-A57 and Cortex-A72 have an erratum where an interrupt that occurs between a pair of AES instructions in aarch32 mode may corrupt the ELR. The task will subsequently produce the wrong AES result. The AES instructions are part of the cryptographic extensions, which are optional. User-space software will detect the support for these instructions from the hwcaps. If the platform doesn't support these instructions a software implementation should be used. Remove the hwcap bits on affected parts to indicate user-space should not use the AES instructions. Acked-by: Ard Biesheuvel Signed-off-by: James Morse Link: https://lore.kernel.org/r/20220714161523.279570-3-james.morse@arm.com Signed-off-by: Will Deacon [florian: resolved conflicts in arch/arm64/tools/cpucaps and cpu_errata.c] Signed-off-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- Documentation/arm64/silicon-errata.rst | 4 ++++ arch/arm64/Kconfig | 16 ++++++++++++++++ arch/arm64/kernel/cpu_errata.c | 16 ++++++++++++++++ arch/arm64/kernel/cpufeature.c | 14 +++++++++++++- arch/arm64/tools/cpucaps | 1 + 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 21715d1e538d..1cee230338a2 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -78,10 +78,14 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A57 | #1319537 | ARM64_ERRATUM_1319367 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A57 | #1742098 | ARM64_ERRATUM_1742098 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A72 | #853709 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A72 | #1319367 | ARM64_ERRATUM_1319367 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A72 | #1655431 | ARM64_ERRATUM_1742098 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #1188873,1418040| ARM64_ERRATUM_1418040 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1e5a03d51d46..9d3cbe786f8d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -487,6 +487,22 @@ config ARM64_ERRATUM_834220 If unsure, say Y. +config ARM64_ERRATUM_1742098 + bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence" + depends on COMPAT + default y + help + This option removes the AES hwcap for aarch32 user-space to + workaround erratum 1742098 on Cortex-A57 and Cortex-A72. + + Affected parts may corrupt the AES state if an interrupt is + taken between a pair of AES instructions. These instructions + are only present if the cryptography extensions are present. + All software should have a fallback implementation for CPUs + that don't implement the cryptography extensions. + + If unsure, say Y. + config ARM64_ERRATUM_845719 bool "Cortex-A53: 845719: a load might read incorrect data" depends on COMPAT diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index a3a9b1537329..ce59811616d8 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -355,6 +355,14 @@ static const struct midr_range erratum_1463225[] = { }; #endif +#ifdef CONFIG_ARM64_ERRATUM_1742098 +static struct midr_range broken_aarch32_aes[] = { + MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), + {}, +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -564,6 +572,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { /* Cortex-A510 r0p0-r1p1 */ CAP_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1) }, +#endif +#ifdef CONFIG_ARM64_ERRATUM_1742098 + { + .desc = "ARM erratum 1742098", + .capability = ARM64_WORKAROUND_1742098, + CAP_MIDR_RANGE_LIST(broken_aarch32_aes), + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + }, #endif { } diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 3e52a9e8b50b..13e3cb1acbdf 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -1915,6 +1916,14 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) } #endif /* CONFIG_ARM64_MTE */ +static void elf_hwcap_fixup(void) +{ +#ifdef CONFIG_ARM64_ERRATUM_1742098 + if (cpus_have_const_cap(ARM64_WORKAROUND_1742098)) + compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES; +#endif /* ARM64_ERRATUM_1742098 */ +} + #ifdef CONFIG_KVM static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused) { @@ -2942,8 +2951,10 @@ void __init setup_cpu_features(void) setup_system_capabilities(); setup_elf_hwcaps(arm64_elf_hwcaps); - if (system_supports_32bit_el0()) + if (system_supports_32bit_el0()) { setup_elf_hwcaps(compat_elf_hwcaps); + elf_hwcap_fixup(); + } if (system_uses_ttbr0_pan()) pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n"); @@ -2995,6 +3006,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu) cpu_active_mask); get_cpu_device(lucky_winner)->offline_disabled = true; setup_elf_hwcaps(compat_elf_hwcaps); + elf_hwcap_fixup(); pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug disabled on CPU %u\n", cpu, lucky_winner); return 0; diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index cfaffd3c8289..6b1e70aee8cf 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -54,6 +54,7 @@ WORKAROUND_1418040 WORKAROUND_1463225 WORKAROUND_1508412 WORKAROUND_1542419 +WORKAROUND_1742098 WORKAROUND_2457168 WORKAROUND_CAVIUM_23154 WORKAROUND_CAVIUM_27456 From 537412c5471211a686738e5f37a00aea7da6ddc3 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 31 Jan 2022 09:24:49 +0200 Subject: [PATCH 540/610] perf/x86/intel/pt: Relax address filter validation commit c243cecb58e3905baeace8827201c14df8481e2a upstream. The requirement for 64-bit address filters is that they are canonical addresses. In other respects any address range is allowed which would include user space addresses. That can be useful for tracing virtual machine guests because address filtering can be used to advantage in place of current privilege level (CPL) filtering. Signed-off-by: Adrian Hunter Signed-off-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/20220131072453.2839535-2-adrian.hunter@intel.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/events/intel/pt.c | 63 ++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 215aed65e978..9ac205487804 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -13,6 +13,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include +#include #include #include @@ -1348,11 +1350,37 @@ static void pt_addr_filters_fini(struct perf_event *event) event->hw.addr_filters = NULL; } -static inline bool valid_kernel_ip(unsigned long ip) +#ifdef CONFIG_X86_64 +static u64 canonical_address(u64 vaddr, u8 vaddr_bits) { - return virt_addr_valid(ip) && kernel_ip(ip); + return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); } +static u64 is_canonical_address(u64 vaddr, u8 vaddr_bits) +{ + return canonical_address(vaddr, vaddr_bits) == vaddr; +} + +/* Clamp to a canonical address greater-than-or-equal-to the address given */ +static u64 clamp_to_ge_canonical_addr(u64 vaddr, u8 vaddr_bits) +{ + return is_canonical_address(vaddr, vaddr_bits) ? + vaddr : + -BIT_ULL(vaddr_bits - 1); +} + +/* Clamp to a canonical address less-than-or-equal-to the address given */ +static u64 clamp_to_le_canonical_addr(u64 vaddr, u8 vaddr_bits) +{ + return is_canonical_address(vaddr, vaddr_bits) ? + vaddr : + BIT_ULL(vaddr_bits - 1) - 1; +} +#else +#define clamp_to_ge_canonical_addr(x, y) (x) +#define clamp_to_le_canonical_addr(x, y) (x) +#endif + static int pt_event_addr_filters_validate(struct list_head *filters) { struct perf_addr_filter *filter; @@ -1367,14 +1395,6 @@ static int pt_event_addr_filters_validate(struct list_head *filters) filter->action == PERF_ADDR_FILTER_ACTION_START) return -EOPNOTSUPP; - if (!filter->path.dentry) { - if (!valid_kernel_ip(filter->offset)) - return -EINVAL; - - if (!valid_kernel_ip(filter->offset + filter->size)) - return -EINVAL; - } - if (++range > intel_pt_validate_hw_cap(PT_CAP_num_address_ranges)) return -EOPNOTSUPP; } @@ -1398,9 +1418,26 @@ static void pt_event_addr_filters_sync(struct perf_event *event) if (filter->path.dentry && !fr[range].start) { msr_a = msr_b = 0; } else { - /* apply the offset */ - msr_a = fr[range].start; - msr_b = msr_a + fr[range].size - 1; + unsigned long n = fr[range].size - 1; + unsigned long a = fr[range].start; + unsigned long b; + + if (a > ULONG_MAX - n) + b = ULONG_MAX; + else + b = a + n; + /* + * Apply the offset. 64-bit addresses written to the + * MSRs must be canonical, but the range can encompass + * non-canonical addresses. Since software cannot + * execute at non-canonical addresses, adjusting to + * canonical addresses does not affect the result of the + * address filter. + */ + msr_a = clamp_to_ge_canonical_addr(a, boot_cpu_data.x86_virt_bits); + msr_b = clamp_to_le_canonical_addr(b, boot_cpu_data.x86_virt_bits); + if (msr_b < msr_a) + msr_a = msr_b = 0; } filters->filter[range].msr_a = msr_a; From ded9d535be0da14e6879222abb26163aa9ef8e77 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 9 Aug 2022 13:02:16 +0800 Subject: [PATCH 541/610] btrfs: enhance unsupported compat RO flags handling commit 81d5d61454c365718655cfc87d8200c84e25d596 upstream. Currently there are two corner cases not handling compat RO flags correctly: - Remount We can still mount the fs RO with compat RO flags, then remount it RW. We should not allow any write into a fs with unsupported RO flags. - Still try to search block group items In fact, behavior/on-disk format change to extent tree should not need a full incompat flag. And since we can ensure fs with unsupported RO flags never got any writes (with above case fixed), then we can even skip block group items search at mount time. This patch will enhance the unsupported RO compat flags by: - Reject read-write remount if there are unsupported RO compat flags - Go dummy block group items directly for unsupported RO compat flags In fact, only changes to chunk/subvolume/root/csum trees should go incompat flags. The latter part should allow future change to extent tree to be compat RO flags. Thus this patch also needs to be backported to all stable trees. CC: stable@vger.kernel.org # 4.9+ Reviewed-by: Nikolay Borisov Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/block-group.c | 11 ++++++++++- fs/btrfs/super.c | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 474dcc0540a8..5eea56789ccc 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -2139,7 +2139,16 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) int need_clear = 0; u64 cache_gen; - if (!info->extent_root) + /* + * Either no extent root (with ibadroots rescue option) or we have + * unsupported RO options. The fs can never be mounted read-write, so no + * need to waste time searching block group items. + * + * This also allows new extent tree related changes to be RO compat, + * no need for a full incompat flag. + */ + if (!info->extent_root || (btrfs_super_compat_ro_flags(info->super_copy) & + ~BTRFS_FEATURE_COMPAT_RO_SUPP)) return fill_dummy_bgs(info); key.objectid = 0; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 442fcd1b14a6..61b84391be58 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2048,6 +2048,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) ret = -EINVAL; goto restore; } + if (btrfs_super_compat_ro_flags(fs_info->super_copy) & + ~BTRFS_FEATURE_COMPAT_RO_SUPP) { + btrfs_err(fs_info, + "can not remount read-write due to unsupported optional flags 0x%llx", + btrfs_super_compat_ro_flags(fs_info->super_copy) & + ~BTRFS_FEATURE_COMPAT_RO_SUPP); + ret = -EINVAL; + goto restore; + } if (fs_info->fs_devices->rw_devices == 0) { ret = -EACCES; goto restore; From e469db818ec95249d44d0f53f3331b4c9e6c84be Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Mon, 17 Oct 2022 21:02:27 +0800 Subject: [PATCH 542/610] ocfs2: clear dinode links count in case of error commit 28f4821b1b53e0649706912e810c6c232fc506f9 upstream. In ocfs2_mknod(), if error occurs after dinode successfully allocated, ocfs2 i_links_count will not be 0. So even though we clear inode i_nlink before iput in error handling, it still won't wipe inode since we'll refresh inode from dinode during inode lock. So just like clear inode i_nlink, we clear ocfs2 i_links_count as well. Also do the same change for ocfs2_symlink(). Link: https://lkml.kernel.org/r/20221017130227.234480-2-joseph.qi@linux.alibaba.com Signed-off-by: Joseph Qi Reported-by: Yan Wang 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/namei.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 2c46ff6ba4ea..33ab5ac3197d 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -231,6 +231,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns, handle_t *handle = NULL; struct ocfs2_super *osb; struct ocfs2_dinode *dirfe; + struct ocfs2_dinode *fe = NULL; struct buffer_head *new_fe_bh = NULL; struct inode *inode = NULL; struct ocfs2_alloc_context *inode_ac = NULL; @@ -381,6 +382,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns, goto leave; } + fe = (struct ocfs2_dinode *) new_fe_bh->b_data; if (S_ISDIR(mode)) { status = ocfs2_fill_new_dir(osb, handle, dir, inode, new_fe_bh, data_ac, meta_ac); @@ -453,8 +455,11 @@ roll_back: leave: if (status < 0 && did_quota_inode) dquot_free_inode(inode); - if (handle) + if (handle) { + if (status < 0 && fe) + ocfs2_set_links_count(fe, 0); ocfs2_commit_trans(osb, handle); + } ocfs2_inode_unlock(dir, 1); if (did_block_signals) @@ -2027,8 +2032,11 @@ bail: ocfs2_clusters_to_bytes(osb->sb, 1)); if (status < 0 && did_quota_inode) dquot_free_inode(inode); - if (handle) + if (handle) { + if (status < 0 && fe) + ocfs2_set_links_count(fe, 0); ocfs2_commit_trans(osb, handle); + } ocfs2_inode_unlock(dir, 1); if (did_block_signals) From 1b31cb0065e257381457c1178a4d2bbc0c7e7c6d Mon Sep 17 00:00:00 2001 From: Joseph Qi Date: Mon, 17 Oct 2022 21:02:26 +0800 Subject: [PATCH 543/610] ocfs2: fix BUG when iput after ocfs2_mknod fails commit 759a7c6126eef5635506453e9b9d55a6a3ac2084 upstream. Commit b1529a41f777 "ocfs2: should reclaim the inode if '__ocfs2_mknod_locked' returns an error" tried to reclaim the claimed inode if __ocfs2_mknod_locked() fails later. But this introduce a race, the freed bit may be reused immediately by another thread, which will update dinode, e.g. i_generation. Then iput this inode will lead to BUG: inode->i_generation != le32_to_cpu(fe->i_generation) We could make this inode as bad, but we did want to do operations like wipe in some cases. Since the claimed inode bit can only affect that an dinode is missing and will return back after fsck, it seems not a big problem. So just leave it as is by revert the reclaim logic. Link: https://lkml.kernel.org/r/20221017130227.234480-1-joseph.qi@linux.alibaba.com Fixes: b1529a41f777 ("ocfs2: should reclaim the inode if '__ocfs2_mknod_locked' returns an error") Signed-off-by: Joseph Qi Reported-by: Yan Wang 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/namei.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 33ab5ac3197d..11807034dd48 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -636,18 +636,9 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, return status; } - status = __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, + return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, parent_fe_bh, handle, inode_ac, fe_blkno, suballoc_loc, suballoc_bit); - if (status < 0) { - u64 bg_blkno = ocfs2_which_suballoc_group(fe_blkno, suballoc_bit); - int tmp = ocfs2_free_suballoc_bits(handle, inode_ac->ac_inode, - inode_ac->ac_bh, suballoc_bit, bg_blkno, 1); - if (tmp) - mlog_errno(tmp); - } - - return status; } static int ocfs2_mkdir(struct user_namespace *mnt_userns, From 3006766d247bc93a25b34e92fff2f75bda597e2e Mon Sep 17 00:00:00 2001 From: "GONG, Ruiqi" Date: Wed, 19 Oct 2022 10:57:10 +0800 Subject: [PATCH 544/610] selinux: enable use of both GFP_KERNEL and GFP_ATOMIC in convert_context() commit abe3c631447dcd1ba7af972fe6f054bee6f136fa upstream. The following warning was triggered on a hardware environment: SELinux: Converting 162 SID table entries... BUG: sleeping function called from invalid context at __might_sleep+0x60/0x74 0x0 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 5943, name: tar CPU: 7 PID: 5943 Comm: tar Tainted: P O 5.10.0 #1 Call trace: dump_backtrace+0x0/0x1c8 show_stack+0x18/0x28 dump_stack+0xe8/0x15c ___might_sleep+0x168/0x17c __might_sleep+0x60/0x74 __kmalloc_track_caller+0xa0/0x7dc kstrdup+0x54/0xac convert_context+0x48/0x2e4 sidtab_context_to_sid+0x1c4/0x36c security_context_to_sid_core+0x168/0x238 security_context_to_sid_default+0x14/0x24 inode_doinit_use_xattr+0x164/0x1e4 inode_doinit_with_dentry+0x1c0/0x488 selinux_d_instantiate+0x20/0x34 security_d_instantiate+0x70/0xbc d_splice_alias+0x4c/0x3c0 ext4_lookup+0x1d8/0x200 [ext4] __lookup_slow+0x12c/0x1e4 walk_component+0x100/0x200 path_lookupat+0x88/0x118 filename_lookup+0x98/0x130 user_path_at_empty+0x48/0x60 vfs_statx+0x84/0x140 vfs_fstatat+0x20/0x30 __se_sys_newfstatat+0x30/0x74 __arm64_sys_newfstatat+0x1c/0x2c el0_svc_common.constprop.0+0x100/0x184 do_el0_svc+0x1c/0x2c el0_svc+0x20/0x34 el0_sync_handler+0x80/0x17c el0_sync+0x13c/0x140 SELinux: Context system_u:object_r:pssp_rsyslog_log_t:s0:c0 is not valid (left unmapped). It was found that within a critical section of spin_lock_irqsave in sidtab_context_to_sid(), convert_context() (hooked by sidtab_convert_params.func) might cause the process to sleep via allocating memory with GFP_KERNEL, which is problematic. As Ondrej pointed out [1], convert_context()/sidtab_convert_params.func has another caller sidtab_convert_tree(), which is okay with GFP_KERNEL. Therefore, fix this problem by adding a gfp_t argument for convert_context()/sidtab_convert_params.func and pass GFP_KERNEL/_ATOMIC properly in individual callers. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20221018120111.1474581-1-gongruiqi1@huawei.com/ [1] Reported-by: Tan Ninghao Fixes: ee1a84fdfeed ("selinux: overhaul sidtab to fix bug and improve performance") Signed-off-by: GONG, Ruiqi Reviewed-by: Ondrej Mosnacek [PM: wrap long BUG() output lines, tweak subject line] Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- security/selinux/ss/services.c | 5 +++-- security/selinux/ss/sidtab.c | 4 ++-- security/selinux/ss/sidtab.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e8035e4876df..01716ed76592 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2021,7 +2021,8 @@ static inline int convert_context_handle_invalid_context( * in `newc'. Verify that the context is valid * under the new policy. */ -static int convert_context(struct context *oldc, struct context *newc, void *p) +static int convert_context(struct context *oldc, struct context *newc, void *p, + gfp_t gfp_flags) { struct convert_context_args *args; struct ocontext *oc; @@ -2035,7 +2036,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) args = p; if (oldc->str) { - s = kstrdup(oldc->str, GFP_KERNEL); + s = kstrdup(oldc->str, gfp_flags); if (!s) return -ENOMEM; diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 656d50b09f76..1981c5af13e0 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -325,7 +325,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, } rc = convert->func(context, &dst_convert->context, - convert->args); + convert->args, GFP_ATOMIC); if (rc) { context_destroy(&dst->context); goto out_unlock; @@ -404,7 +404,7 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst, while (i < SIDTAB_LEAF_ENTRIES && *pos < count) { rc = convert->func(&esrc->ptr_leaf->entries[i].context, &edst->ptr_leaf->entries[i].context, - convert->args); + convert->args, GFP_KERNEL); if (rc) return rc; (*pos)++; diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 4eff0e49dcb2..9fce0d553fe2 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -65,7 +65,7 @@ struct sidtab_isid_entry { }; struct sidtab_convert_params { - int (*func)(struct context *oldc, struct context *newc, void *args); + int (*func)(struct context *oldc, struct context *newc, void *args, gfp_t gfp_flags); void *args; struct sidtab *target; }; From 14d260f94ff89543597ffea13db8b277a810e08e Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Sat, 15 Oct 2022 15:04:23 +0200 Subject: [PATCH 545/610] cpufreq: qcom: fix writes in read-only memory region commit 01039fb8e90c9cb684430414bff70cea9eb168c5 upstream. This commit fixes a kernel oops because of a write in some read-only memory: [ 9.068287] Unable to handle kernel write to read-only memory at virtual address ffff800009240ad8 ..snip.. [ 9.138790] Internal error: Oops: 9600004f [#1] PREEMPT SMP ..snip.. [ 9.269161] Call trace: [ 9.276271] __memcpy+0x5c/0x230 [ 9.278531] snprintf+0x58/0x80 [ 9.282002] qcom_cpufreq_msm8939_name_version+0xb4/0x190 [ 9.284869] qcom_cpufreq_probe+0xc8/0x39c ..snip.. The following line defines a pointer that point to a char buffer stored in read-only memory: char *pvs_name = "speedXX-pvsXX-vXX"; This pointer is meant to hold a template "speedXX-pvsXX-vXX" where the XX values get overridden by the qcom_cpufreq_krait_name_version function. Since the template is actually stored in read-only memory, when the function executes the following call we get an oops: snprintf(*pvs_name, sizeof("speedXX-pvsXX-vXX"), "speed%d-pvs%d-v%d", speed, pvs, pvs_ver); To fix this issue, we instead store the template name onto the stack by using the following syntax: char pvs_name_buffer[] = "speedXX-pvsXX-vXX"; Because the `pvs_name` needs to be able to be assigned to NULL, the template buffer is stored in the pvs_name_buffer and not under the pvs_name variable. Cc: v5.7+ # v5.7+ Fixes: a8811ec764f9 ("cpufreq: qcom: Add support for krait based socs") Signed-off-by: Fabien Parent Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/qcom-cpufreq-nvmem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index 6dfa86971a75..937e9ec2f51a 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -264,7 +264,8 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) struct nvmem_cell *speedbin_nvmem; struct device_node *np; struct device *cpu_dev; - char *pvs_name = "speedXX-pvsXX-vXX"; + char pvs_name_buffer[] = "speedXX-pvsXX-vXX"; + char *pvs_name = pvs_name_buffer; unsigned cpu; const struct of_device_id *match; int ret; From 93d7e2b47a72f91be1b4e9ce9ce667fe801824bf Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Tue, 18 Oct 2022 03:19:20 +0100 Subject: [PATCH 546/610] i2c: qcom-cci: Fix ordering of pm_runtime_xx and i2c_add_adapter commit 61775d54d674ff8ec3658495e0dbc537227dc5c1 upstream. When we compile-in the CCI along with the imx412 driver and run on the RB5 we see that i2c_add_adapter() causes the probe of the imx412 driver to happen. This probe tries to perform an i2c xfer() and the xfer() in i2c-qcom-cci.c fails on pm_runtime_get() because the i2c-qcom-cci.c::probe() function has not completed to pm_runtime_enable(dev). Fix this sequence by ensuring pm_runtime_xxx() calls happen prior to adding the i2c adapter. Fixes: e517526195de ("i2c: Add Qualcomm CCI I2C driver") Reported-by: Vladimir Zapolskiy Reviewed-by: Vladimir Zapolskiy Tested-by: Vladimir Zapolskiy Cc: Signed-off-by: Bryan O'Donoghue Reviewed-by: Robert Foss Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-qcom-cci.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index cf54f1cb4c57..2bdb86ab2ea8 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -638,6 +638,11 @@ static int cci_probe(struct platform_device *pdev) if (ret < 0) goto error; + pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + for (i = 0; i < cci->data->num_masters; i++) { if (!cci->master[i].cci) continue; @@ -649,14 +654,12 @@ static int cci_probe(struct platform_device *pdev) } } - pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); - pm_runtime_use_autosuspend(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - return 0; error_i2c: + pm_runtime_disable(dev); + pm_runtime_dont_use_autosuspend(dev); + for (--i ; i >= 0; i--) { if (cci->master[i].cci) { i2c_del_adapter(&cci->master[i].adap); From 2f7171465f2638e295e400a5d26261a31588d040 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 5 Oct 2022 12:00:08 +0200 Subject: [PATCH 547/610] x86/microcode/AMD: Apply the patch early on every logical thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e7ad18d1169c62e6c78c01ff693fd362d9d65278 upstream. Currently, the patch application logic checks whether the revision needs to be applied on each logical CPU (SMT thread). Therefore, on SMT designs where the microcode engine is shared between the two threads, the application happens only on one of them as that is enough to update the shared microcode engine. However, there are microcode patches which do per-thread modification, see Link tag below. Therefore, drop the revision check and try applying on each thread. This is what the BIOS does too so this method is very much tested. Btw, change only the early paths. On the late loading paths, there's no point in doing per-thread modification because if is it some case like in the bugzilla below - removing a CPUID flag - the kernel cannot go and un-use features it has detected are there early. For that, one should use early loading anyway. [ bp: Fixes does not contain the oldest commit which did check for equality but that is good enough. ] Fixes: 8801b3fcb574 ("x86/microcode/AMD: Rework container parsing") Reported-by: Ștefan Talpalaru Signed-off-by: Borislav Petkov Tested-by: Ștefan Talpalaru Cc: Link: https://bugzilla.kernel.org/show_bug.cgi?id=216211 Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/microcode/amd.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 5a16844b99d3..7c758f1afbf0 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -440,7 +440,13 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_p return ret; native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); - if (rev >= mc->hdr.patch_id) + + /* + * Allow application of the same revision to pick up SMT-specific + * changes even if the revision of the other SMT thread is already + * up-to-date. + */ + if (rev > mc->hdr.patch_id) return ret; if (!__apply_microcode_amd(mc)) { @@ -522,8 +528,12 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax) native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); - /* Check whether we have saved a new patch already: */ - if (*new_rev && rev < mc->hdr.patch_id) { + /* + * Check whether a new patch has been saved already. Also, allow application of + * the same revision in order to pick up SMT-thread-specific configuration even + * if the sibling SMT thread already has an up-to-date revision. + */ + if (*new_rev && rev <= mc->hdr.patch_id) { if (!__apply_microcode_amd(mc)) { *new_rev = mc->hdr.patch_id; return; From 30cf0dee372baf9b515f2d9c7218f905fddf3cdb Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 14 Oct 2022 17:01:45 +0800 Subject: [PATCH 548/610] hwmon/coretemp: Handle large core ID value commit 7108b80a542b9d65e44b36d64a700a83658c0b73 upstream. The coretemp driver supports up to a hard-coded limit of 128 cores. Today, the driver can not support a core with an ID above that limit. Yet, the encoding of core ID's is arbitrary (BIOS APIC-ID) and so they may be sparse and they may be large. Update the driver to map arbitrary core ID numbers into appropriate array indexes so that 128 cores can be supported, no matter the encoding of core ID's. Signed-off-by: Zhang Rui Signed-off-by: Dave Hansen Acked-by: Len Brown Acked-by: Guenter Roeck Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20221014090147.1836-3-rui.zhang@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/coretemp.c | 56 +++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index bb9211215a68..032129292957 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -46,9 +46,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) -#define TO_CORE_ID(cpu) (cpu_data(cpu).cpu_core_id) -#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) - #ifdef CONFIG_SMP #define for_each_sibling(i, cpu) \ for_each_cpu(i, topology_sibling_cpumask(cpu)) @@ -91,6 +88,8 @@ struct temp_data { struct platform_data { struct device *hwmon_dev; u16 pkg_id; + u16 cpu_map[NUM_REAL_CORES]; + struct ida ida; struct cpumask cpumask; struct temp_data *core_data[MAX_CORE_DATA]; struct device_attribute name_attr; @@ -441,7 +440,7 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) MSR_IA32_THERM_STATUS; tdata->is_pkg_data = pkg_flag; tdata->cpu = cpu; - tdata->cpu_core_id = TO_CORE_ID(cpu); + tdata->cpu_core_id = topology_core_id(cpu); tdata->attr_size = MAX_CORE_ATTRS; mutex_init(&tdata->update_lock); return tdata; @@ -454,7 +453,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, struct platform_data *pdata = platform_get_drvdata(pdev); struct cpuinfo_x86 *c = &cpu_data(cpu); u32 eax, edx; - int err, attr_no; + int err, index, attr_no; /* * Find attr number for sysfs: @@ -462,14 +461,26 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, * The attr number is always core id + 2 * The Pkgtemp will always show up as temp1_*, if available */ - attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu); + if (pkg_flag) { + attr_no = PKG_SYSFS_ATTR_NO; + } else { + index = ida_alloc(&pdata->ida, GFP_KERNEL); + if (index < 0) + return index; + pdata->cpu_map[index] = topology_core_id(cpu); + attr_no = index + BASE_SYSFS_ATTR_NO; + } - if (attr_no > MAX_CORE_DATA - 1) - return -ERANGE; + if (attr_no > MAX_CORE_DATA - 1) { + err = -ERANGE; + goto ida_free; + } tdata = init_temp_data(cpu, pkg_flag); - if (!tdata) - return -ENOMEM; + if (!tdata) { + err = -ENOMEM; + goto ida_free; + } /* Test if we can access the status register */ err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx); @@ -505,6 +516,9 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, exit_free: pdata->core_data[attr_no] = NULL; kfree(tdata); +ida_free: + if (!pkg_flag) + ida_free(&pdata->ida, index); return err; } @@ -524,6 +538,9 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx) kfree(pdata->core_data[indx]); pdata->core_data[indx] = NULL; + + if (indx >= BASE_SYSFS_ATTR_NO) + ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO); } static int coretemp_probe(struct platform_device *pdev) @@ -537,6 +554,7 @@ static int coretemp_probe(struct platform_device *pdev) return -ENOMEM; pdata->pkg_id = pdev->id; + ida_init(&pdata->ida); platform_set_drvdata(pdev, pdata); pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME, @@ -553,6 +571,7 @@ static int coretemp_remove(struct platform_device *pdev) if (pdata->core_data[i]) coretemp_remove_core(pdata, i); + ida_destroy(&pdata->ida); return 0; } @@ -647,7 +666,7 @@ static int coretemp_cpu_offline(unsigned int cpu) struct platform_device *pdev = coretemp_get_pdev(cpu); struct platform_data *pd; struct temp_data *tdata; - int indx, target; + int i, indx = -1, target; /* * Don't execute this on suspend as the device remove locks @@ -660,12 +679,19 @@ static int coretemp_cpu_offline(unsigned int cpu) if (!pdev) return 0; - /* The core id is too big, just return */ - indx = TO_ATTR_NO(cpu); - if (indx > MAX_CORE_DATA - 1) + pd = platform_get_drvdata(pdev); + + for (i = 0; i < NUM_REAL_CORES; i++) { + if (pd->cpu_map[i] == topology_core_id(cpu)) { + indx = i + BASE_SYSFS_ATTR_NO; + break; + } + } + + /* Too many cores and this core is not populated, just return */ + if (indx < 0) return 0; - pd = platform_get_drvdata(pdev); tdata = pd->core_data[indx]; cpumask_clear_cpu(cpu, &pd->cpumask); From 5d6a037b3a94feb8a157f57aa16cac249b2663a5 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 12 Oct 2022 15:11:05 +0200 Subject: [PATCH 549/610] ata: ahci-imx: Fix MODULE_ALIAS commit 979556f1521a835a059de3b117b9c6c6642c7d58 upstream. 'ahci:' is an invalid prefix, preventing the module from autoloading. Fix this by using the 'platform:' prefix and DRV_NAME. Fixes: 9e54eae23bc9 ("ahci_imx: add ahci sata support on imx platforms") Cc: stable@vger.kernel.org Signed-off-by: Alexander Stein Reviewed-by: Fabio Estevam Signed-off-by: Damien Le Moal Signed-off-by: Greg Kroah-Hartman --- drivers/ata/ahci_imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 388baf528fa8..189f75d53741 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -1230,4 +1230,4 @@ module_platform_driver(imx_ahci_driver); MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver"); MODULE_AUTHOR("Richard Zhu "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ahci:imx"); +MODULE_ALIAS("platform:" DRV_NAME); From 8fbe13de1cc7cef2564be3cbf60400b33eee023b Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 11 Oct 2022 10:46:17 +0800 Subject: [PATCH 550/610] ata: ahci: Match EM_MAX_SLOTS with SATA_PMP_MAX_PORTS commit 1e41e693f458eef2d5728207dbd327cd3b16580a upstream. UBSAN complains about array-index-out-of-bounds: [ 1.980703] kernel: UBSAN: array-index-out-of-bounds in /build/linux-9H675w/linux-5.15.0/drivers/ata/libahci.c:968:41 [ 1.980709] kernel: index 15 is out of range for type 'ahci_em_priv [8]' [ 1.980713] kernel: CPU: 0 PID: 209 Comm: scsi_eh_8 Not tainted 5.15.0-25-generic #25-Ubuntu [ 1.980716] kernel: Hardware name: System manufacturer System Product Name/P5Q3, BIOS 1102 06/11/2010 [ 1.980718] kernel: Call Trace: [ 1.980721] kernel: [ 1.980723] kernel: show_stack+0x52/0x58 [ 1.980729] kernel: dump_stack_lvl+0x4a/0x5f [ 1.980734] kernel: dump_stack+0x10/0x12 [ 1.980736] kernel: ubsan_epilogue+0x9/0x45 [ 1.980739] kernel: __ubsan_handle_out_of_bounds.cold+0x44/0x49 [ 1.980742] kernel: ahci_qc_issue+0x166/0x170 [libahci] [ 1.980748] kernel: ata_qc_issue+0x135/0x240 [ 1.980752] kernel: ata_exec_internal_sg+0x2c4/0x580 [ 1.980754] kernel: ? vprintk_default+0x1d/0x20 [ 1.980759] kernel: ata_exec_internal+0x67/0xa0 [ 1.980762] kernel: sata_pmp_read+0x8d/0xc0 [ 1.980765] kernel: sata_pmp_read_gscr+0x3c/0x90 [ 1.980768] kernel: sata_pmp_attach+0x8b/0x310 [ 1.980771] kernel: ata_eh_revalidate_and_attach+0x28c/0x4b0 [ 1.980775] kernel: ata_eh_recover+0x6b6/0xb30 [ 1.980778] kernel: ? ahci_do_hardreset+0x180/0x180 [libahci] [ 1.980783] kernel: ? ahci_stop_engine+0xb0/0xb0 [libahci] [ 1.980787] kernel: ? ahci_do_softreset+0x290/0x290 [libahci] [ 1.980792] kernel: ? trace_event_raw_event_ata_eh_link_autopsy_qc+0xe0/0xe0 [ 1.980795] kernel: sata_pmp_eh_recover.isra.0+0x214/0x560 [ 1.980799] kernel: sata_pmp_error_handler+0x23/0x40 [ 1.980802] kernel: ahci_error_handler+0x43/0x80 [libahci] [ 1.980806] kernel: ata_scsi_port_error_handler+0x2b1/0x600 [ 1.980810] kernel: ata_scsi_error+0x9c/0xd0 [ 1.980813] kernel: scsi_error_handler+0xa1/0x180 [ 1.980817] kernel: ? scsi_unjam_host+0x1c0/0x1c0 [ 1.980820] kernel: kthread+0x12a/0x150 [ 1.980823] kernel: ? set_kthread_struct+0x50/0x50 [ 1.980826] kernel: ret_from_fork+0x22/0x30 [ 1.980831] kernel: This happens because sata_pmp_init_links() initialize link->pmp up to SATA_PMP_MAX_PORTS while em_priv is declared as 8 elements array. I can't find the maximum Enclosure Management ports specified in AHCI spec v1.3.1, but "12.2.1 LED message type" states that "Port Multiplier Information" can utilize 4 bits, which implies it can support up to 16 ports. Hence, use SATA_PMP_MAX_PORTS as EM_MAX_SLOTS to resolve the issue. BugLink: https://bugs.launchpad.net/bugs/1970074 Cc: stable@vger.kernel.org Signed-off-by: Kai-Heng Feng Signed-off-by: Damien Le Moal Signed-off-by: Greg Kroah-Hartman --- drivers/ata/ahci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 2e89499bd9c3..60ae707a88cc 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -254,7 +254,7 @@ enum { PCS_7 = 0x94, /* 7+ port PCS (Denverton) */ /* em constants */ - EM_MAX_SLOTS = 8, + EM_MAX_SLOTS = SATA_PMP_MAX_PORTS, EM_MAX_RETRY = 5, /* em_ctl bits */ From d866f5982c1561e2a07232edac060dcb9c5638ed Mon Sep 17 00:00:00 2001 From: Babu Moger Date: Tue, 27 Sep 2022 15:16:29 -0500 Subject: [PATCH 551/610] x86/resctrl: Fix min_cbm_bits for AMD commit 67bf6493449b09590f9f71d7df29efb392b12d25 upstream. AMD systems support zero CBM (capacity bit mask) for cache allocation. That is reflected in rdt_init_res_defs_amd() by: r->cache.arch_has_empty_bitmaps = true; However given the unified code in cbm_validate(), checking for: val == 0 && !arch_has_empty_bitmaps is not enough because of another check in cbm_validate(): if ((zero_bit - first_bit) < r->cache.min_cbm_bits) The default value of r->cache.min_cbm_bits = 1. Leading to: $ cd /sys/fs/resctrl $ mkdir foo $ cd foo $ echo L3:0=0 > schemata -bash: echo: write error: Invalid argument $ cat /sys/fs/resctrl/info/last_cmd_status Need at least 1 bits in the mask Initialize the min_cbm_bits to 0 for AMD. Also, remove the default setting of min_cbm_bits and initialize it separately. After the fix: $ cd /sys/fs/resctrl $ mkdir foo $ cd foo $ echo L3:0=0 > schemata $ cat /sys/fs/resctrl/info/last_cmd_status ok Fixes: 316e7f901f5a ("x86/resctrl: Add struct rdt_cache::arch_has_{sparse, empty}_bitmaps") Co-developed-by: Stephane Eranian Signed-off-by: Stephane Eranian Signed-off-by: Babu Moger Signed-off-by: Borislav Petkov Reviewed-by: Ingo Molnar Reviewed-by: James Morse Reviewed-by: Reinette Chatre Reviewed-by: Fenghua Yu Cc: Link: https://lore.kernel.org/lkml/20220517001234.3137157-1-eranian@google.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/resctrl/core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index bb1c3f5f60c8..a5c51a14fbce 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -66,9 +66,6 @@ struct rdt_hw_resource rdt_resources_all[] = { .rid = RDT_RESOURCE_L3, .name = "L3", .cache_level = 3, - .cache = { - .min_cbm_bits = 1, - }, .domains = domain_init(RDT_RESOURCE_L3), .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", @@ -83,9 +80,6 @@ struct rdt_hw_resource rdt_resources_all[] = { .rid = RDT_RESOURCE_L2, .name = "L2", .cache_level = 2, - .cache = { - .min_cbm_bits = 1, - }, .domains = domain_init(RDT_RESOURCE_L2), .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", @@ -877,6 +871,7 @@ static __init void rdt_init_res_defs_intel(void) r->cache.arch_has_sparse_bitmaps = false; r->cache.arch_has_empty_bitmaps = false; r->cache.arch_has_per_cpu_cfg = false; + r->cache.min_cbm_bits = 1; } else if (r->rid == RDT_RESOURCE_MBA) { hw_res->msr_base = MSR_IA32_MBA_THRTL_BASE; hw_res->msr_update = mba_wrmsr_intel; @@ -897,6 +892,7 @@ static __init void rdt_init_res_defs_amd(void) r->cache.arch_has_sparse_bitmaps = true; r->cache.arch_has_empty_bitmaps = true; r->cache.arch_has_per_cpu_cfg = true; + r->cache.min_cbm_bits = 0; } else if (r->rid == RDT_RESOURCE_MBA) { hw_res->msr_base = MSR_IA32_MBA_BW_BASE; hw_res->msr_update = mba_wrmsr_amd; From b5606e3ab1f7cc00d89903f4a11fe57747bb3a68 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Sat, 15 Oct 2022 15:04:22 +0200 Subject: [PATCH 552/610] cpufreq: qcom: fix memory leak in error path commit 9f42cf54403a42cb092636804d2628d8ecf71e75 upstream. If for some reason the speedbin length is incorrect, then there is a memory leak in the error path because we never free the speedbin buffer. This commit fixes the error path to always free the speedbin buffer. Cc: v5.7+ # v5.7+ Fixes: a8811ec764f9 ("cpufreq: qcom: Add support for krait based socs") Signed-off-by: Fabien Parent Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/qcom-cpufreq-nvmem.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c index 937e9ec2f51a..6e011e8bfb6a 100644 --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -215,6 +215,7 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, int speed = 0, pvs = 0, pvs_ver = 0; u8 *speedbin; size_t len; + int ret = 0; speedbin = nvmem_cell_read(speedbin_nvmem, &len); @@ -232,7 +233,8 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, break; default: dev_err(cpu_dev, "Unable to read nvmem data. Defaulting to 0!\n"); - return -ENODEV; + ret = -ENODEV; + goto len_error; } snprintf(*pvs_name, sizeof("speedXX-pvsXX-vXX"), "speed%d-pvs%d-v%d", @@ -240,8 +242,9 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev, drv->versions = (1 << speed); +len_error: kfree(speedbin); - return 0; + return ret; } static const struct qcom_cpufreq_match_data match_data_kryo = { From 2d508b4e653636e2cacfc6844513c371349522a6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 19 Oct 2022 16:57:42 -0400 Subject: [PATCH 553/610] drm/amdgpu: fix sdma doorbell init ordering on APUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 50b0e4d4da09fa501e722af886f97e60a4f820d6 upstream. Commit 8795e182b02d ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()") uncovered a bug in amdgpu that required a reordering of the driver init sequence to avoid accessing a special register on the GPU before it was properly set up leading to an PCI AER error. This reordering uncovered a different hw programming ordering dependency in some APUs where the SDMA doorbells need to be programmed before the GFX doorbells. To fix this, move the SDMA doorbell programming back into the soc15 common code, but use the actual doorbell range values directly rather than the values stored in the ring structure since those will not be initialized at this point. This is a partial revert, but with the doorbell assignment fixed so the proper doorbell index is set before it's used. Fixes: e3163bc8ffdfdb ("drm/amdgpu: move nbio sdma_doorbell_range() into sdma code for vega") Acked-by: Christian König Signed-off-by: Alex Deucher Cc: skhan@linuxfoundation.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 5 ----- drivers/gpu/drm/amd/amdgpu/soc15.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 8b20326c4c05..9014f71d52dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1507,11 +1507,6 @@ static int sdma_v4_0_start(struct amdgpu_device *adev) WREG32_SDMA(i, mmSDMA0_CNTL, temp); if (!amdgpu_sriov_vf(adev)) { - ring = &adev->sdma.instance[i].ring; - adev->nbio.funcs->sdma_doorbell_range(adev, i, - ring->use_doorbell, ring->doorbell_index, - adev->doorbell_index.sdma_doorbell_range); - /* unhalt engine */ temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL); temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 7d5ff50435e5..0cde8fb9e30d 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -1416,6 +1416,20 @@ static int soc15_common_sw_fini(void *handle) return 0; } +static void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev) +{ + int i; + + /* sdma doorbell range is programed by hypervisor */ + if (!amdgpu_sriov_vf(adev)) { + for (i = 0; i < adev->sdma.num_instances; i++) { + adev->nbio.funcs->sdma_doorbell_range(adev, i, + true, adev->doorbell_index.sdma_engine[i] << 1, + adev->doorbell_index.sdma_doorbell_range); + } + } +} + static int soc15_common_hw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -1435,6 +1449,13 @@ static int soc15_common_hw_init(void *handle) /* enable the doorbell aperture */ soc15_enable_doorbell_aperture(adev, true); + /* HW doorbell routing policy: doorbell writing not + * in SDMA/IH/MM/ACV range will be routed to CP. So + * we need to init SDMA doorbell range prior + * to CP ip block init and ring test. IH already + * happens before CP. + */ + soc15_sdma_doorbell_range_init(adev); return 0; } From 112a005d1ded04a4b41b6d01833cc0bda90625cc Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Mon, 17 Oct 2022 20:25:05 -0400 Subject: [PATCH 554/610] mm,hugetlb: take hugetlb_lock before decrementing h->resv_huge_pages commit 12df140f0bdfae5dcfc81800970dd7f6f632e00c upstream. The h->*_huge_pages counters are protected by the hugetlb_lock, but alloc_huge_page has a corner case where it can decrement the counter outside of the lock. This could lead to a corrupted value of h->resv_huge_pages, which we have observed on our systems. Take the hugetlb_lock before decrementing h->resv_huge_pages to avoid a potential race. Link: https://lkml.kernel.org/r/20221017202505.0e6a4fcd@imladris.surriel.com Fixes: a88c76954804 ("mm: hugetlb: fix hugepage memory leak caused by wrong reserve count") Signed-off-by: Rik van Riel Reviewed-by: Mike Kravetz Cc: Naoya Horiguchi Cc: Glen McCready Cc: Mike Kravetz Cc: Muchun Song Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/hugetlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 23085498f5c8..f5f8929fad51 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2813,11 +2813,11 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, page = alloc_buddy_huge_page_with_mpol(h, vma, addr); if (!page) goto out_uncharge_cgroup; + spin_lock_irq(&hugetlb_lock); if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) { SetHPageRestoreReserve(page); h->resv_huge_pages--; } - spin_lock_irq(&hugetlb_lock); list_add(&page->lru, &h->hugepage_activelist); /* Fall through */ } From 5bf2fda26a720305ce4cfb96a15dd404475e01a2 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 17 Oct 2022 20:45:39 +0200 Subject: [PATCH 555/610] kvm: Add support for arch compat vm ioctls commit ed51862f2f57cbce6fed2d4278cfe70a490899fd upstream. We will introduce the first architecture specific compat vm ioctl in the next patch. Add all necessary boilerplate to allow architectures to override compat vm ioctls when necessary. Signed-off-by: Alexander Graf Message-Id: <20221017184541.2658-2-graf@amazon.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- include/linux/kvm_host.h | 2 ++ virt/kvm/kvm_main.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 725f8f13adb5..7e2423ffaf59 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1124,6 +1124,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap); long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); +long kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg); int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu); int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 3ae5f6a3eae4..3ffed093d3ea 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4609,6 +4609,12 @@ struct compat_kvm_clear_dirty_log { }; }; +long __weak kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) +{ + return -ENOTTY; +} + static long kvm_vm_compat_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -4617,6 +4623,11 @@ static long kvm_vm_compat_ioctl(struct file *filp, if (kvm->mm != current->mm || kvm->vm_bugged) return -EIO; + + r = kvm_arch_vm_compat_ioctl(filp, ioctl, arg); + if (r != -ENOTTY) + return r; + switch (ioctl) { #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT case KVM_CLEAR_DIRTY_LOG: { From 1e4e71f9e1970ea01c8b14b13794eb1e8bbc685f Mon Sep 17 00:00:00 2001 From: Eric Ren Date: Sat, 15 Oct 2022 11:19:28 +0800 Subject: [PATCH 556/610] KVM: arm64: vgic: Fix exit condition in scan_its_table() commit c000a2607145d28b06c697f968491372ea56c23a upstream. With some PCIe topologies, restoring a guest fails while parsing the ITS device tables. Reproducer hints: 1. Create ARM virt VM with pxb-pcie bus which adds extra host bridges, with qemu command like: ``` -device pxb-pcie,bus_nr=8,id=pci.x,numa_node=0,bus=pcie.0 \ -device pcie-root-port,..,bus=pci.x \ ... -device pxb-pcie,bus_nr=37,id=pci.y,numa_node=1,bus=pcie.0 \ -device pcie-root-port,..,bus=pci.y \ ... ``` 2. Ensure the guest uses 2-level device table 3. Perform VM migration which calls save/restore device tables In that setup, we get a big "offset" between 2 device_ids, which makes unsigned "len" round up a big positive number, causing the scan loop to continue with a bad GPA. For example: 1. L1 table has 2 entries; 2. and we are now scanning at L2 table entry index 2075 (pointed to by L1 first entry) 3. if next device id is 9472, we will get a big offset: 7397; 4. with unsigned 'len', 'len -= offset * esz', len will underflow to a positive number, mistakenly into next iteration with a bad GPA; (It should break out of the current L2 table scanning, and jump into the next L1 table entry) 5. that bad GPA fails the guest read. Fix it by stopping the L2 table scan when the next device id is outside of the current table, allowing the scan to continue from the next L1 table entry. Thanks to Eric Auger for the fix suggestion. Fixes: 920a7a8fa92a ("KVM: arm64: vgic-its: Add infrastructure for tableookup") Suggested-by: Eric Auger Signed-off-by: Eric Ren [maz: commit message tidy-up] Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/d9c3a564af9e2c5bf63f48a7dcbf08cd593c5c0b.1665802985.git.renzhengeek@gmail.com Signed-off-by: Greg Kroah-Hartman --- arch/arm64/kvm/vgic/vgic-its.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index 61728c543eb9..1d534283378a 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -2096,7 +2096,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz, memset(entry, 0, esz); - while (len > 0) { + while (true) { int next_offset; size_t byte_offset; @@ -2109,6 +2109,9 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz, return next_offset; byte_offset = next_offset * esz; + if (byte_offset >= len) + break; + id += next_offset; gpa += byte_offset; len -= byte_offset; From 5265cc1202a31f7097691c3483a0d60d624424a5 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 25 Aug 2022 20:36:37 +0200 Subject: [PATCH 557/610] media: ipu3-imgu: Fix NULL pointer dereference in active selection access commit b9eb3ab6f30bf32f7326909f17949ccb11bab514 upstream. What the IMGU driver did was that it first acquired the pointers to active and try V4L2 subdev state, and only then figured out which one to use. The problem with that approach and a later patch (see Fixes: tag) is that as sd_state argument to v4l2_subdev_get_try_crop() et al is NULL, there is now an attempt to dereference that. Fix this. Also rewrap lines a little. Fixes: 0d346d2a6f54 ("media: v4l2-subdev: add subdev-wide state struct") Cc: stable@vger.kernel.org # for v5.14 and later Signed-off-by: Sakari Ailus Reviewed-by: Bingbu Cao Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/ipu3/ipu3-v4l2.c | 31 ++++++++++++-------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 90c86ba5040e..f0e61c1b6ffd 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -192,33 +192,30 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { - struct v4l2_rect *try_sel, *r; - struct imgu_v4l2_subdev *imgu_sd = container_of(sd, - struct imgu_v4l2_subdev, - subdev); + struct imgu_v4l2_subdev *imgu_sd = + container_of(sd, struct imgu_v4l2_subdev, subdev); if (sel->pad != IMGU_NODE_IN) return -EINVAL; switch (sel->target) { case V4L2_SEL_TGT_CROP: - try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); - r = &imgu_sd->rect.eff; - break; + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) + sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, + sel->pad); + else + sel->r = imgu_sd->rect.eff; + return 0; case V4L2_SEL_TGT_COMPOSE: - try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); - r = &imgu_sd->rect.bds; - break; + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) + sel->r = *v4l2_subdev_get_try_compose(sd, sd_state, + sel->pad); + else + sel->r = imgu_sd->rect.bds; + return 0; default: return -EINVAL; } - - if (sel->which == V4L2_SUBDEV_FORMAT_TRY) - sel->r = *try_sel; - else - sel->r = *r; - - return 0; } static int imgu_subdev_set_selection(struct v4l2_subdev *sd, From b22b4823a0a5685be7fa8625019fe999ff3fbc2c Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 2 Sep 2022 12:32:21 +0200 Subject: [PATCH 558/610] media: mceusb: set timeout to at least timeout provided commit 20b794ddce475ed012deb365000527c17b3e93e6 upstream. By rounding down, the actual timeout can be lower than requested. As a result, long spaces just below the requested timeout can be incorrectly reported as timeout and truncated. Fixes: 877f1a7cee3f ("media: rc: mceusb: allow the timeout to be configurable") Cc: stable@vger.kernel.org Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/rc/mceusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index deb3db45a94c..391de68365f6 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1077,7 +1077,7 @@ static int mceusb_set_timeout(struct rc_dev *dev, unsigned int timeout) struct mceusb_dev *ir = dev->priv; unsigned int units; - units = DIV_ROUND_CLOSEST(timeout, MCE_TIME_UNIT); + units = DIV_ROUND_UP(timeout, MCE_TIME_UNIT); cmdbuf[2] = units >> 8; cmdbuf[3] = units; From fcc96e89b3ff488733dcfa34824962454610b3e2 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Tue, 26 Jul 2022 04:14:54 +0200 Subject: [PATCH 559/610] media: venus: dec: Handle the case where find_format fails commit 06a2da340f762addc5935bf851d95b14d4692db2 upstream. Debugging the decoder on msm8916 I noticed the vdec probe was crashing if the fmt pointer was NULL. A similar fix from Colin Ian King found by Coverity was implemented for the encoder. Implement the same fix on the decoder. Fixes: 7472c1c69138 ("[media] media: venus: vdec: add video decoder files") Cc: stable@vger.kernel.org # v4.13+ Signed-off-by: Bryan O'Donoghue Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/venus/vdec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 198e47eb63f4..9a4443a390b1 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -158,6 +158,8 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) else return NULL; fmt = find_format(inst, pixmp->pixelformat, f->type); + if (!fmt) + return NULL; } pixmp->width = clamp(pixmp->width, frame_width_min(inst), From d31f4bc225967fdd41957533e53f48cbaf897878 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 14 Oct 2022 17:01:46 +0800 Subject: [PATCH 560/610] x86/topology: Fix multiple packages shown on a single-package system commit 2b12a7a126d62bdbd81f4923c21bf6e9a7fbd069 upstream. CPUID.1F/B does not enumerate Package level explicitly, instead, all the APIC-ID bits above the enumerated levels are assumed to be package ID bits. Current code gets package ID by shifting out all the APIC-ID bits that Linux supports, rather than shifting out all the APIC-ID bits that CPUID.1F enumerates. This introduces problems when CPUID.1F enumerates a level that Linux does not support. For example, on a single package AlderLake-N, there are 2 Ecore Modules with 4 atom cores in each module. Linux does not support the Module level and interprets the Module ID bits as package ID and erroneously reports a multi module system as a multi-package system. Fix this by using APIC-ID bits above all the CPUID.1F enumerated levels as package ID. [ dhansen: spelling fix ] Fixes: 7745f03eb395 ("x86/topology: Add CPUID.1F multi-die/package support") Suggested-by: Len Brown Signed-off-by: Zhang Rui Signed-off-by: Dave Hansen Reviewed-by: Len Brown Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20221014090147.1836-4-rui.zhang@intel.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/topology.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 132a2de44d2f..f7592814e5d5 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -96,6 +96,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c) unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width; unsigned int core_select_mask, core_level_siblings; unsigned int die_select_mask, die_level_siblings; + unsigned int pkg_mask_width; bool die_level_present = false; int leaf; @@ -111,10 +112,10 @@ int detect_extended_topology(struct cpuinfo_x86 *c) core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); die_level_siblings = LEVEL_MAX_SIBLINGS(ebx); - die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); + pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); sub_index = 1; - do { + while (true) { cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx); /* @@ -132,8 +133,13 @@ int detect_extended_topology(struct cpuinfo_x86 *c) die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); } + if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE) + pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); + else + break; + sub_index++; - } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE); + } core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; die_select_mask = (~(-1 << die_plus_mask_width)) >> @@ -148,7 +154,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c) } c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, - die_plus_mask_width); + pkg_mask_width); /* * Reinit the apicid, now that we have extended initial_apicid. */ From c439cafce8cfbc50d3faa0d707577e27bfaa5fbd Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 14 Oct 2022 17:01:47 +0800 Subject: [PATCH 561/610] x86/topology: Fix duplicated core ID within a package commit 71eac7063698b7d7b8fafb1683ac24a034541141 upstream. Today, core ID is assumed to be unique within each package. But an AlderLake-N platform adds a Module level between core and package, Linux excludes the unknown modules bits from the core ID, resulting in duplicate core ID's. To keep core ID unique within a package, Linux must include all APIC-ID bits for known or unknown levels above the core and below the package in the core ID. It is important to understand that core ID's have always come directly from the APIC-ID encoding, which comes from the BIOS. Thus there is no guarantee that they start at 0, or that they are contiguous. As such, naively using them for array indexes can be problematic. [ dhansen: un-known -> unknown ] Fixes: 7745f03eb395 ("x86/topology: Add CPUID.1F multi-die/package support") Suggested-by: Len Brown Signed-off-by: Zhang Rui Signed-off-by: Dave Hansen Reviewed-by: Len Brown Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20221014090147.1836-5-rui.zhang@intel.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index f7592814e5d5..5e868b62a7c4 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -141,7 +141,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c) sub_index++; } - core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; + core_select_mask = (~(-1 << pkg_mask_width)) >> ht_mask_width; die_select_mask = (~(-1 << die_plus_mask_width)) >> core_plus_mask_width; From af67578d565cde111a9f69707a2f40addb83628c Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 11 Oct 2022 13:16:51 +0100 Subject: [PATCH 562/610] btrfs: fix processing of delayed data refs during backref walking [ Upstream commit 4fc7b57228243d09c0d878873bf24fa64a90fa01 ] When processing delayed data references during backref walking and we are using a share context (we are being called through fiemap), whenever we find a delayed data reference for an inode different from the one we are interested in, then we immediately exit and consider the data extent as shared. This is wrong, because: 1) This might be a DROP reference that will cancel out a reference in the extent tree; 2) Even if it's an ADD reference, it may be followed by a DROP reference that cancels it out. In either case we should not exit immediately. Fix this by never exiting when we find a delayed data reference for another inode - instead add the reference and if it does not cancel out other delayed reference, we will exit early when we call extent_is_shared() after processing all delayed references. If we find a drop reference, then signal the code that processes references from the extent tree (add_inline_refs() and add_keyed_refs()) to not exit immediately if it finds there a reference for another inode, since we have delayed drop references that may cancel it out. In this later case we exit once we don't have references in the rb trees that cancel out each other and have two references for different inodes. Example reproducer for case 1): $ cat test-1.sh #!/bin/bash DEV=/dev/sdj MNT=/mnt/sdj mkfs.btrfs -f $DEV mount $DEV $MNT xfs_io -f -c "pwrite 0 64K" $MNT/foo cp --reflink=always $MNT/foo $MNT/bar echo echo "fiemap after cloning:" xfs_io -c "fiemap -v" $MNT/foo rm -f $MNT/bar echo echo "fiemap after removing file bar:" xfs_io -c "fiemap -v" $MNT/foo umount $MNT Running it before this patch, the extent is still listed as shared, it has the flag 0x2000 (FIEMAP_EXTENT_SHARED) set: $ ./test-1.sh fiemap after cloning: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x2001 fiemap after removing file bar: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x2001 Example reproducer for case 2): $ cat test-2.sh #!/bin/bash DEV=/dev/sdj MNT=/mnt/sdj mkfs.btrfs -f $DEV mount $DEV $MNT xfs_io -f -c "pwrite 0 64K" $MNT/foo cp --reflink=always $MNT/foo $MNT/bar # Flush delayed references to the extent tree and commit current # transaction. sync echo echo "fiemap after cloning:" xfs_io -c "fiemap -v" $MNT/foo rm -f $MNT/bar echo echo "fiemap after removing file bar:" xfs_io -c "fiemap -v" $MNT/foo umount $MNT Running it before this patch, the extent is still listed as shared, it has the flag 0x2000 (FIEMAP_EXTENT_SHARED) set: $ ./test-2.sh fiemap after cloning: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x2001 fiemap after removing file bar: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x2001 After this patch, after deleting bar in both tests, the extent is not reported with the 0x2000 flag anymore, it gets only the flag 0x1 (which is FIEMAP_EXTENT_LAST): $ ./test-1.sh fiemap after cloning: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x2001 fiemap after removing file bar: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x1 $ ./test-2.sh fiemap after cloning: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x2001 fiemap after removing file bar: /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [0..127]: 26624..26751 128 0x1 These tests will later be converted to a test case for fstests. Fixes: dc046b10c8b7d4 ("Btrfs: make fiemap not blow when you have lots of snapshots") Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/backref.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 8b090c40daf7..f33bad9f5e29 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -138,6 +138,7 @@ struct share_check { u64 root_objectid; u64 inum; int share_count; + bool have_delayed_delete_refs; }; static inline int extent_is_shared(struct share_check *sc) @@ -882,13 +883,22 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info, key.offset = ref->offset; /* - * Found a inum that doesn't match our known inum, we - * know it's shared. + * If we have a share check context and a reference for + * another inode, we can't exit immediately. This is + * because even if this is a BTRFS_ADD_DELAYED_REF + * reference we may find next a BTRFS_DROP_DELAYED_REF + * which cancels out this ADD reference. + * + * If this is a DROP reference and there was no previous + * ADD reference, then we need to signal that when we + * process references from the extent tree (through + * add_inline_refs() and add_keyed_refs()), we should + * not exit early if we find a reference for another + * inode, because one of the delayed DROP references + * may cancel that reference in the extent tree. */ - if (sc && sc->inum && ref->objectid != sc->inum) { - ret = BACKREF_FOUND_SHARED; - goto out; - } + if (sc && count < 0) + sc->have_delayed_delete_refs = true; ret = add_indirect_ref(fs_info, preftrees, ref->root, &key, 0, node->bytenr, count, sc, @@ -918,7 +928,7 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info, } if (!ret) ret = extent_is_shared(sc); -out: + spin_unlock(&head->lock); return ret; } @@ -1021,7 +1031,8 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info, key.type = BTRFS_EXTENT_DATA_KEY; key.offset = btrfs_extent_data_ref_offset(leaf, dref); - if (sc && sc->inum && key.objectid != sc->inum) { + if (sc && sc->inum && key.objectid != sc->inum && + !sc->have_delayed_delete_refs) { ret = BACKREF_FOUND_SHARED; break; } @@ -1031,6 +1042,7 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info, ret = add_indirect_ref(fs_info, preftrees, root, &key, 0, bytenr, count, sc, GFP_NOFS); + break; } default: @@ -1120,7 +1132,8 @@ static int add_keyed_refs(struct btrfs_fs_info *fs_info, key.type = BTRFS_EXTENT_DATA_KEY; key.offset = btrfs_extent_data_ref_offset(leaf, dref); - if (sc && sc->inum && key.objectid != sc->inum) { + if (sc && sc->inum && key.objectid != sc->inum && + !sc->have_delayed_delete_refs) { ret = BACKREF_FOUND_SHARED; break; } @@ -1547,6 +1560,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr, .root_objectid = root->root_key.objectid, .inum = inum, .share_count = 0, + .have_delayed_delete_refs = false, }; ulist_init(roots); @@ -1581,6 +1595,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr, break; bytenr = node->val; shared.share_count = 0; + shared.have_delayed_delete_refs = false; cond_resched(); } From 6c5041a10324bdc8f81a1b762ebb972ffdb33bb9 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 11 Oct 2022 13:16:52 +0100 Subject: [PATCH 563/610] btrfs: fix processing of delayed tree block refs during backref walking [ Upstream commit 943553ef9b51db303ab2b955c1025261abfdf6fb ] During backref walking, when processing a delayed reference with a type of BTRFS_TREE_BLOCK_REF_KEY, we have two bugs there: 1) We are accessing the delayed references extent_op, and its key, without the protection of the delayed ref head's lock; 2) If there's no extent op for the delayed ref head, we end up with an uninitialized key in the stack, variable 'tmp_op_key', and then pass it to add_indirect_ref(), which adds the reference to the indirect refs rb tree. This is wrong, because indirect references should have a NULL key when we don't have access to the key, and in that case they should be added to the indirect_missing_keys rb tree and not to the indirect rb tree. This means that if have BTRFS_TREE_BLOCK_REF_KEY delayed ref resulting from freeing an extent buffer, therefore with a count of -1, it will not cancel out the corresponding reference we have in the extent tree (with a count of 1), since both references end up in different rb trees. When using fiemap, where we often need to check if extents are shared through shared subtrees resulting from snapshots, it means we can incorrectly report an extent as shared when it's no longer shared. However this is temporary because after the transaction is committed the extent is no longer reported as shared, as running the delayed reference results in deleting the tree block reference from the extent tree. Outside the fiemap context, the result is unpredictable, as the key was not initialized but it's used when navigating the rb trees to insert and search for references (prelim_ref_compare()), and we expect all references in the indirect rb tree to have valid keys. The following reproducer triggers the second bug: $ cat test.sh #!/bin/bash DEV=/dev/sdj MNT=/mnt/sdj mkfs.btrfs -f $DEV mount -o compress $DEV $MNT # With a compressed 128M file we get a tree height of 2 (level 1 root). xfs_io -f -c "pwrite -b 1M 0 128M" $MNT/foo btrfs subvolume snapshot $MNT $MNT/snap # Fiemap should output 0x2008 in the flags column. # 0x2000 means shared extent # 0x8 means encoded extent (because it's compressed) echo echo "fiemap after snapshot, range [120M, 120M + 128K):" xfs_io -c "fiemap -v 120M 128K" $MNT/foo echo # Overwrite one extent and fsync to flush delalloc and COW a new path # in the snapshot's tree. # # After this we have a BTRFS_DROP_DELAYED_REF delayed ref of type # BTRFS_TREE_BLOCK_REF_KEY with a count of -1 for every COWed extent # buffer in the path. # # In the extent tree we have inline references of type # BTRFS_TREE_BLOCK_REF_KEY, with a count of 1, for the same extent # buffers, so they should cancel each other, and the extent buffers in # the fs tree should no longer be considered as shared. # echo "Overwriting file range [120M, 120M + 128K)..." xfs_io -c "pwrite -b 128K 120M 128K" $MNT/snap/foo xfs_io -c "fsync" $MNT/snap/foo # Fiemap should output 0x8 in the flags column. The extent in the range # [120M, 120M + 128K) is no longer shared, it's now exclusive to the fs # tree. echo echo "fiemap after overwrite range [120M, 120M + 128K):" xfs_io -c "fiemap -v 120M 128K" $MNT/foo echo umount $MNT Running it before this patch: $ ./test.sh (...) wrote 134217728/134217728 bytes at offset 0 128 MiB, 128 ops; 0.1152 sec (1.085 GiB/sec and 1110.5809 ops/sec) Create a snapshot of '/mnt/sdj' in '/mnt/sdj/snap' fiemap after snapshot, range [120M, 120M + 128K): /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [245760..246015]: 34304..34559 256 0x2008 Overwriting file range [120M, 120M + 128K)... wrote 131072/131072 bytes at offset 125829120 128 KiB, 1 ops; 0.0001 sec (683.060 MiB/sec and 5464.4809 ops/sec) fiemap after overwrite range [120M, 120M + 128K): /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [245760..246015]: 34304..34559 256 0x2008 The extent in the range [120M, 120M + 128K) is still reported as shared (0x2000 bit set) after overwriting that range and flushing delalloc, which is not correct - an entire path was COWed in the snapshot's tree and the extent is now only referenced by the original fs tree. Running it after this patch: $ ./test.sh (...) wrote 134217728/134217728 bytes at offset 0 128 MiB, 128 ops; 0.1198 sec (1.043 GiB/sec and 1068.2067 ops/sec) Create a snapshot of '/mnt/sdj' in '/mnt/sdj/snap' fiemap after snapshot, range [120M, 120M + 128K): /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [245760..246015]: 34304..34559 256 0x2008 Overwriting file range [120M, 120M + 128K)... wrote 131072/131072 bytes at offset 125829120 128 KiB, 1 ops; 0.0001 sec (694.444 MiB/sec and 5555.5556 ops/sec) fiemap after overwrite range [120M, 120M + 128K): /mnt/sdj/foo: EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS 0: [245760..246015]: 34304..34559 256 0x8 Now the extent is not reported as shared anymore. So fix this by passing a NULL key pointer to add_indirect_ref() when processing a delayed reference for a tree block if there's no extent op for our delayed ref head with a defined key. Also access the extent op only after locking the delayed ref head's lock. The reproducer will be converted later to a test case for fstests. Fixes: 86d5f994425252 ("btrfs: convert prelimary reference tracking to use rbtrees") Fixes: a6dbceafb915e8 ("btrfs: Remove unused op_key var from add_delayed_refs") Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/backref.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index f33bad9f5e29..2e7c3e48bc9c 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -819,16 +819,11 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info, struct preftrees *preftrees, struct share_check *sc) { struct btrfs_delayed_ref_node *node; - struct btrfs_delayed_extent_op *extent_op = head->extent_op; struct btrfs_key key; - struct btrfs_key tmp_op_key; struct rb_node *n; int count; int ret = 0; - if (extent_op && extent_op->update_key) - btrfs_disk_key_to_cpu(&tmp_op_key, &extent_op->key); - spin_lock(&head->lock); for (n = rb_first_cached(&head->ref_tree); n; n = rb_next(n)) { node = rb_entry(n, struct btrfs_delayed_ref_node, @@ -854,10 +849,16 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info, case BTRFS_TREE_BLOCK_REF_KEY: { /* NORMAL INDIRECT METADATA backref */ struct btrfs_delayed_tree_ref *ref; + struct btrfs_key *key_ptr = NULL; + + if (head->extent_op && head->extent_op->update_key) { + btrfs_disk_key_to_cpu(&key, &head->extent_op->key); + key_ptr = &key; + } ref = btrfs_delayed_node_to_tree_ref(node); ret = add_indirect_ref(fs_info, preftrees, ref->root, - &tmp_op_key, ref->level + 1, + key_ptr, ref->level + 1, node->bytenr, count, sc, GFP_ATOMIC); break; From 40e5fceddfd5c227f8b64cdea4dbc8c3ffef3900 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 2 Sep 2022 16:41:11 +0200 Subject: [PATCH 564/610] drm/vc4: Add module dependency on hdmi-codec [ Upstream commit d1c0b7de4dfa5505cf7a1d6220aa72aace4435d0 ] The VC4 HDMI controller driver relies on the HDMI codec ASoC driver. In order to set it up properly, in vc4_hdmi_audio_init(), our HDMI driver will register a device matching the HDMI codec driver, and then register an ASoC card using that codec. However, if vc4 is compiled as a module, chances are that the hdmi-codec driver will be too. In such a case, the module loader will have a very narrow window to load the module between the device registration and the card registration. If it fails to load the module in time, the card registration will fail with EPROBE_DEFER, and we'll abort the audio initialisation, unregistering the HDMI codec device in the process. The next time the bind callback will be run, it's likely that we end up missing that window again, effectively preventing vc4 to probe entirely. In order to prevent this, we can create a soft dependency of the vc4 driver on the HDMI codec one so that we're sure the HDMI codec will be loaded before the VC4 module is, and thus we'll never end up in the previous situation. Fixes: 91e99e113929 ("drm/vc4: hdmi: Register HDMI codec") Reviewed-by: Javier Martinez Canillas Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20220902144111.3424560-1-maxime@cerno.tech Signed-off-by: Sasha Levin --- drivers/gpu/drm/vc4/vc4_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index ef8fa2850ed6..d216a1fd057c 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -397,6 +397,7 @@ module_init(vc4_drm_register); module_exit(vc4_drm_unregister); MODULE_ALIAS("platform:vc4-drm"); +MODULE_SOFTDEP("pre: snd-soc-hdmi-codec"); MODULE_DESCRIPTION("Broadcom VC4 DRM Driver"); MODULE_AUTHOR("Eric Anholt "); MODULE_LICENSE("GPL v2"); From 6161c364e378660f059194c81ccd855fd35ec997 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Mon, 10 Oct 2022 13:34:23 -0700 Subject: [PATCH 565/610] ACPI: extlog: Handle multiple records [ Upstream commit f6ec01da40e4139b41179f046044ee7c4f6370dc ] If there is no user space consumer of extlog_mem trace records, then Linux properly handles multiple error records in an ELOG block extlog_print() print_extlog_rcd() __print_extlog_rcd() cper_estatus_print() apei_estatus_for_each_section() But the other code path hard codes looking for a single record to output a trace record. Fix by using the same apei_estatus_for_each_section() iterator to step over all records. Fixes: 2dfb7d51a61d ("trace, RAS: Add eMCA trace event interface") Signed-off-by: Tony Luck Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpi_extlog.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index 72f1fb77abcd..e648158368a7 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -138,8 +139,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, int cpu = mce->extcpu; struct acpi_hest_generic_status *estatus, *tmp; struct acpi_hest_generic_data *gdata; - const guid_t *fru_id = &guid_null; - char *fru_text = ""; + const guid_t *fru_id; + char *fru_text; guid_t *sec_type; static u32 err_seq; @@ -160,17 +161,23 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, /* log event via trace */ err_seq++; - gdata = (struct acpi_hest_generic_data *)(tmp + 1); - if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) - fru_id = (guid_t *)gdata->fru_id; - if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) - fru_text = gdata->fru_text; - sec_type = (guid_t *)gdata->section_type; - if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { - struct cper_sec_mem_err *mem = (void *)(gdata + 1); - if (gdata->error_data_length >= sizeof(*mem)) - trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, - (u8)gdata->error_severity); + apei_estatus_for_each_section(tmp, gdata) { + if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) + fru_id = (guid_t *)gdata->fru_id; + else + fru_id = &guid_null; + if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) + fru_text = gdata->fru_text; + else + fru_text = ""; + sec_type = (guid_t *)gdata->section_type; + if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { + struct cper_sec_mem_err *mem = (void *)(gdata + 1); + + if (gdata->error_data_length >= sizeof(*mem)) + trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, + (u8)gdata->error_severity); + } } out: From b294cad6f02ef89fed5d14ca6af528d7f5217a3a Mon Sep 17 00:00:00 2001 From: Mark Tomlinson Date: Mon, 10 Oct 2022 15:46:13 +1300 Subject: [PATCH 566/610] tipc: Fix recognition of trial period [ Upstream commit 28be7ca4fcfd69a2d52aaa331adbf9dbe91f9e6e ] The trial period exists until jiffies is after addr_trial_end. But as jiffies will eventually overflow, just using time_after will eventually give incorrect results. As the node address is set once the trial period ends, this can be used to know that we are not in the trial period. Fixes: e415577f57f4 ("tipc: correct discovery message handling during address trial period") Signed-off-by: Mark Tomlinson Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/tipc/discover.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tipc/discover.c b/net/tipc/discover.c index da69e1abf68f..e8630707901e 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -148,8 +148,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d, { struct net *net = d->net; struct tipc_net *tn = tipc_net(net); - bool trial = time_before(jiffies, tn->addr_trial_end); u32 self = tipc_own_addr(net); + bool trial = time_before(jiffies, tn->addr_trial_end) && !self; if (mtyp == DSC_TRIAL_FAIL_MSG) { if (!trial) From dbc01c0a4e202a7e925dad1d4b7c1d6eb0c81154 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Wed, 12 Oct 2022 17:25:14 +0200 Subject: [PATCH 567/610] tipc: fix an information leak in tipc_topsrv_kern_subscr [ Upstream commit 777ecaabd614d47c482a5c9031579e66da13989a ] Use a 8-byte write to initialize sub.usr_handle in tipc_topsrv_kern_subscr(), otherwise four bytes remain uninitialized when issuing setsockopt(..., SOL_TIPC, ...). This resulted in an infoleak reported by KMSAN when the packet was received: ===================================================== BUG: KMSAN: kernel-infoleak in copyout+0xbc/0x100 lib/iov_iter.c:169 instrument_copy_to_user ./include/linux/instrumented.h:121 copyout+0xbc/0x100 lib/iov_iter.c:169 _copy_to_iter+0x5c0/0x20a0 lib/iov_iter.c:527 copy_to_iter ./include/linux/uio.h:176 simple_copy_to_iter+0x64/0xa0 net/core/datagram.c:513 __skb_datagram_iter+0x123/0xdc0 net/core/datagram.c:419 skb_copy_datagram_iter+0x58/0x200 net/core/datagram.c:527 skb_copy_datagram_msg ./include/linux/skbuff.h:3903 packet_recvmsg+0x521/0x1e70 net/packet/af_packet.c:3469 ____sys_recvmsg+0x2c4/0x810 net/socket.c:? ___sys_recvmsg+0x217/0x840 net/socket.c:2743 __sys_recvmsg net/socket.c:2773 __do_sys_recvmsg net/socket.c:2783 __se_sys_recvmsg net/socket.c:2780 __x64_sys_recvmsg+0x364/0x540 net/socket.c:2780 do_syscall_x64 arch/x86/entry/common.c:50 do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd arch/x86/entry/entry_64.S:120 ... Uninit was stored to memory at: tipc_sub_subscribe+0x42d/0xb50 net/tipc/subscr.c:156 tipc_conn_rcv_sub+0x246/0x620 net/tipc/topsrv.c:375 tipc_topsrv_kern_subscr+0x2e8/0x400 net/tipc/topsrv.c:579 tipc_group_create+0x4e7/0x7d0 net/tipc/group.c:190 tipc_sk_join+0x2a8/0x770 net/tipc/socket.c:3084 tipc_setsockopt+0xae5/0xe40 net/tipc/socket.c:3201 __sys_setsockopt+0x87f/0xdc0 net/socket.c:2252 __do_sys_setsockopt net/socket.c:2263 __se_sys_setsockopt net/socket.c:2260 __x64_sys_setsockopt+0xe0/0x160 net/socket.c:2260 do_syscall_x64 arch/x86/entry/common.c:50 do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd arch/x86/entry/entry_64.S:120 Local variable sub created at: tipc_topsrv_kern_subscr+0x57/0x400 net/tipc/topsrv.c:562 tipc_group_create+0x4e7/0x7d0 net/tipc/group.c:190 Bytes 84-87 of 88 are uninitialized Memory access of size 88 starts at ffff88801ed57cd0 Data copied to user address 0000000020000400 ... ===================================================== Signed-off-by: Alexander Potapenko Fixes: 026321c6d056a5 ("tipc: rename tipc_server to tipc_topsrv") Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/tipc/topsrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index 5522865deae9..14fd05fd6107 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c @@ -568,7 +568,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, sub.seq.upper = upper; sub.timeout = TIPC_WAIT_FOREVER; sub.filter = filter; - *(u32 *)&sub.usr_handle = port; + *(u64 *)&sub.usr_handle = (u64)port; con = tipc_conn_alloc(tipc_topsrv(net)); if (IS_ERR(con)) From 94a171c982b8a8137a00721c1e62bc2713435bca Mon Sep 17 00:00:00 2001 From: Jan Sokolowski Date: Wed, 12 Oct 2022 13:54:40 -0700 Subject: [PATCH 568/610] i40e: Fix DMA mappings leak [ Upstream commit aae425efdfd1b1d8452260a3cb49344ebf20b1f5 ] During reallocation of RX buffers, new DMA mappings are created for those buffers. steps for reproduction: while : do for ((i=0; i<=8160; i=i+32)) do ethtool -G enp130s0f0 rx $i tx $i sleep 0.5 ethtool -g enp130s0f0 done done This resulted in crash: i40e 0000:01:00.1: Unable to allocate memory for the Rx descriptor ring, size=65536 Driver BUG WARNING: CPU: 0 PID: 4300 at net/core/xdp.c:141 xdp_rxq_info_unreg+0x43/0x50 Call Trace: i40e_free_rx_resources+0x70/0x80 [i40e] i40e_set_ringparam+0x27c/0x800 [i40e] ethnl_set_rings+0x1b2/0x290 genl_family_rcv_msg_doit.isra.15+0x10f/0x150 genl_family_rcv_msg+0xb3/0x160 ? rings_fill_reply+0x1a0/0x1a0 genl_rcv_msg+0x47/0x90 ? genl_family_rcv_msg+0x160/0x160 netlink_rcv_skb+0x4c/0x120 genl_rcv+0x24/0x40 netlink_unicast+0x196/0x230 netlink_sendmsg+0x204/0x3d0 sock_sendmsg+0x4c/0x50 __sys_sendto+0xee/0x160 ? handle_mm_fault+0xbe/0x1e0 ? syscall_trace_enter+0x1d3/0x2c0 __x64_sys_sendto+0x24/0x30 do_syscall_64+0x5b/0x1a0 entry_SYSCALL_64_after_hwframe+0x65/0xca RIP: 0033:0x7f5eac8b035b Missing register, driver bug WARNING: CPU: 0 PID: 4300 at net/core/xdp.c:119 xdp_rxq_info_unreg_mem_model+0x69/0x140 Call Trace: xdp_rxq_info_unreg+0x1e/0x50 i40e_free_rx_resources+0x70/0x80 [i40e] i40e_set_ringparam+0x27c/0x800 [i40e] ethnl_set_rings+0x1b2/0x290 genl_family_rcv_msg_doit.isra.15+0x10f/0x150 genl_family_rcv_msg+0xb3/0x160 ? rings_fill_reply+0x1a0/0x1a0 genl_rcv_msg+0x47/0x90 ? genl_family_rcv_msg+0x160/0x160 netlink_rcv_skb+0x4c/0x120 genl_rcv+0x24/0x40 netlink_unicast+0x196/0x230 netlink_sendmsg+0x204/0x3d0 sock_sendmsg+0x4c/0x50 __sys_sendto+0xee/0x160 ? handle_mm_fault+0xbe/0x1e0 ? syscall_trace_enter+0x1d3/0x2c0 __x64_sys_sendto+0x24/0x30 do_syscall_64+0x5b/0x1a0 entry_SYSCALL_64_after_hwframe+0x65/0xca RIP: 0033:0x7f5eac8b035b This was caused because of new buffers with different RX ring count should substitute older ones, but those buffers were freed in i40e_configure_rx_ring and reallocated again with i40e_alloc_rx_bi, thus kfree on rx_bi caused leak of already mapped DMA. Fix this by reallocating ZC with rx_bi_zc struct when BPF program loads. Additionally reallocate back to rx_bi when BPF program unloads. If BPF program is loaded/unloaded and XSK pools are created, reallocate RX queues accordingly in XSP_SETUP_XSK_POOL handler. Fixes: be1222b585fd ("i40e: Separate kernel allocated rx_bi rings from AF_XDP rings") Signed-off-by: Jan Sokolowski Signed-off-by: Mateusz Palczewski Signed-off-by: Jacob Keller Tested-by: Chandan (A Contingent Worker at Intel) Tested-by: Gurucharan (A Contingent worker at Intel) Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../net/ethernet/intel/i40e/i40e_ethtool.c | 3 - drivers/net/ethernet/intel/i40e/i40e_main.c | 16 +++-- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 13 ++-- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 1 - drivers/net/ethernet/intel/i40e/i40e_xsk.c | 67 ++++++++++++++++--- drivers/net/ethernet/intel/i40e/i40e_xsk.h | 2 +- 6 files changed, 74 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 8e770c5e181e..11a17ebfceef 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -2081,9 +2081,6 @@ static int i40e_set_ringparam(struct net_device *netdev, */ rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS; err = i40e_setup_rx_descriptors(&rx_rings[i]); - if (err) - goto rx_unwind; - err = i40e_alloc_rx_bi(&rx_rings[i]); if (err) goto rx_unwind; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 5922520fdb01..ad6f6fe25057 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3421,12 +3421,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) if (ring->vsi->type == I40E_VSI_MAIN) xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); - kfree(ring->rx_bi); ring->xsk_pool = i40e_xsk_pool(ring); if (ring->xsk_pool) { - ret = i40e_alloc_rx_bi_zc(ring); - if (ret) - return ret; ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); /* For AF_XDP ZC, we disallow packets to span on @@ -3444,9 +3440,6 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) ring->queue_index); } else { - ret = i40e_alloc_rx_bi(ring); - if (ret) - return ret; ring->rx_buf_len = vsi->rx_buf_len; if (ring->vsi->type == I40E_VSI_MAIN) { ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, @@ -13161,6 +13154,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog, i40e_reset_and_rebuild(pf, true, true); } + if (!i40e_enabled_xdp_vsi(vsi) && prog) { + if (i40e_realloc_rx_bi_zc(vsi, true)) + return -ENOMEM; + } else if (i40e_enabled_xdp_vsi(vsi) && !prog) { + if (i40e_realloc_rx_bi_zc(vsi, false)) + return -ENOMEM; + } + for (i = 0; i < vsi->num_queue_pairs; i++) WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog); @@ -13393,6 +13394,7 @@ int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair) i40e_queue_pair_disable_irq(vsi, queue_pair); err = i40e_queue_pair_toggle_rings(vsi, queue_pair, false /* off */); + i40e_clean_rx_ring(vsi->rx_rings[queue_pair]); i40e_queue_pair_toggle_napi(vsi, queue_pair, false /* off */); i40e_queue_pair_clean_rings(vsi, queue_pair); i40e_queue_pair_reset_stats(vsi, queue_pair); diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 326fd25d055f..8f5aad9bbba3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1459,14 +1459,6 @@ err: return -ENOMEM; } -int i40e_alloc_rx_bi(struct i40e_ring *rx_ring) -{ - unsigned long sz = sizeof(*rx_ring->rx_bi) * rx_ring->count; - - rx_ring->rx_bi = kzalloc(sz, GFP_KERNEL); - return rx_ring->rx_bi ? 0 : -ENOMEM; -} - static void i40e_clear_rx_bi(struct i40e_ring *rx_ring) { memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count); @@ -1597,6 +1589,11 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; + rx_ring->rx_bi = + kcalloc(rx_ring->count, sizeof(*rx_ring->rx_bi), GFP_KERNEL); + if (!rx_ring->rx_bi) + return -ENOMEM; + return 0; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index f6d91fa1562e..f3b0b8151709 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -466,7 +466,6 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size); bool __i40e_chk_linearize(struct sk_buff *skb); int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, u32 flags); -int i40e_alloc_rx_bi(struct i40e_ring *rx_ring); /** * i40e_get_head - Retrieve head from head writeback diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c index 54c91dc459dd..7e50b8fff9b5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c +++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c @@ -10,14 +10,6 @@ #include "i40e_txrx_common.h" #include "i40e_xsk.h" -int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring) -{ - unsigned long sz = sizeof(*rx_ring->rx_bi_zc) * rx_ring->count; - - rx_ring->rx_bi_zc = kzalloc(sz, GFP_KERNEL); - return rx_ring->rx_bi_zc ? 0 : -ENOMEM; -} - void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring) { memset(rx_ring->rx_bi_zc, 0, @@ -29,6 +21,58 @@ static struct xdp_buff **i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx) return &rx_ring->rx_bi_zc[idx]; } +/** + * i40e_realloc_rx_xdp_bi - reallocate SW ring for either XSK or normal buffer + * @rx_ring: Current rx ring + * @pool_present: is pool for XSK present + * + * Try allocating memory and return ENOMEM, if failed to allocate. + * If allocation was successful, substitute buffer with allocated one. + * Returns 0 on success, negative on failure + */ +static int i40e_realloc_rx_xdp_bi(struct i40e_ring *rx_ring, bool pool_present) +{ + size_t elem_size = pool_present ? sizeof(*rx_ring->rx_bi_zc) : + sizeof(*rx_ring->rx_bi); + void *sw_ring = kcalloc(rx_ring->count, elem_size, GFP_KERNEL); + + if (!sw_ring) + return -ENOMEM; + + if (pool_present) { + kfree(rx_ring->rx_bi); + rx_ring->rx_bi = NULL; + rx_ring->rx_bi_zc = sw_ring; + } else { + kfree(rx_ring->rx_bi_zc); + rx_ring->rx_bi_zc = NULL; + rx_ring->rx_bi = sw_ring; + } + return 0; +} + +/** + * i40e_realloc_rx_bi_zc - reallocate rx SW rings + * @vsi: Current VSI + * @zc: is zero copy set + * + * Reallocate buffer for rx_rings that might be used by XSK. + * XDP requires more memory, than rx_buf provides. + * Returns 0 on success, negative on failure + */ +int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc) +{ + struct i40e_ring *rx_ring; + unsigned long q; + + for_each_set_bit(q, vsi->af_xdp_zc_qps, vsi->alloc_queue_pairs) { + rx_ring = vsi->rx_rings[q]; + if (i40e_realloc_rx_xdp_bi(rx_ring, zc)) + return -ENOMEM; + } + return 0; +} + /** * i40e_xsk_pool_enable - Enable/associate an AF_XDP buffer pool to a * certain ring/qid @@ -69,6 +113,10 @@ static int i40e_xsk_pool_enable(struct i40e_vsi *vsi, if (err) return err; + err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], true); + if (err) + return err; + err = i40e_queue_pair_enable(vsi, qid); if (err) return err; @@ -113,6 +161,9 @@ static int i40e_xsk_pool_disable(struct i40e_vsi *vsi, u16 qid) xsk_pool_dma_unmap(pool, I40E_RX_DMA_ATTR); if (if_running) { + err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], false); + if (err) + return err; err = i40e_queue_pair_enable(vsi, qid); if (err) return err; diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.h b/drivers/net/ethernet/intel/i40e/i40e_xsk.h index ea88f4597a07..75103c992269 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_xsk.h +++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.h @@ -33,7 +33,7 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget); bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring); int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags); -int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring); +int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc); void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring); #endif /* _I40E_XSK_H_ */ From 0f58940ca3c109caff818873a64a54a59350b765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Date: Sun, 9 Oct 2022 20:27:47 +0200 Subject: [PATCH 569/610] HID: magicmouse: Do not set BTN_MOUSE on double report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit bb5f0c855dcfc893ae5ed90e4c646bde9e4498bf ] Under certain conditions the Magic Trackpad can group 2 reports in a single packet. The packet is split and the raw event function is invoked recursively for each part. However, after processing each part, the BTN_MOUSE status is updated, sending multiple click events. [1] Return after processing double reports to avoid this issue. Link: https://gitlab.freedesktop.org/libinput/libinput/-/issues/811 # [1] Fixes: a462230e16ac ("HID: magicmouse: enable Magic Trackpad support") Reported-by: Nulo Signed-off-by: José Expósito Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20221009182747.90730-1-jose.exposito89@gmail.com Signed-off-by: Sasha Levin --- drivers/hid/hid-magicmouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index b8b08f0a8c54..c6b8da716002 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -478,7 +478,7 @@ static int magicmouse_raw_event(struct hid_device *hdev, magicmouse_raw_event(hdev, report, data + 2, data[1]); magicmouse_raw_event(hdev, report, data + 2 + data[1], size - 2 - data[1]); - break; + return 0; default: return 0; } From 0eb17faedce752e824a783f8a0a3d2e81b680b78 Mon Sep 17 00:00:00 2001 From: Jonathan Cooper Date: Thu, 13 Oct 2022 10:55:53 +0100 Subject: [PATCH 570/610] sfc: Change VF mac via PF as first preference if available. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a8aed7b35becfd21f22a77c7014029ea837b018f ] Changing a VF's mac address through the VF (rather than via the PF) fails with EPERM because the latter part of efx_ef10_set_mac_address attempts to change the vport mac address list as the VF. Even with this fixed it still fails with EBUSY because the vadaptor is still assigned on the VF - the vadaptor reassignment must be within a section where the VF has torn down its state. A major reason this has broken is because we have two functions that ostensibly do the same thing - have a PF and VF cooperate to change a VF mac address. Rather than do this, if we are changing the mac of a VF that has a link to the PF in the same VM then simply call sriov_set_vf_mac instead, which is a proven working function that does that. If there is no PF available, or that fails non-fatally, then attempt to change the VF's mac address as we would a PF, without updating the PF's data. Test case: Create a VF: echo 1 > /sys/class/net//device/sriov_numvfs Set the mac address of the VF directly: ip link set addr 00:11:22:33:44:55 Set the MAC address of the VF via the PF: ip link set vf 0 mac 00:11:22:33:44:66 Without this patch the last command will fail with ENOENT. Signed-off-by: Jonathan Cooper Reported-by: Íñigo Huguet Fixes: 910c8789a777 ("set the MAC address using MC_CMD_VADAPTOR_SET_MAC") Acked-by: Edward Cree Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/sfc/ef10.c | 58 ++++++++++++++------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 056c24ec1249..c316a9eb5be3 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -3271,6 +3271,30 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx) bool was_enabled = efx->port_enabled; int rc; +#ifdef CONFIG_SFC_SRIOV + /* If this function is a VF and we have access to the parent PF, + * then use the PF control path to attempt to change the VF MAC address. + */ + if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) { + struct efx_nic *efx_pf = pci_get_drvdata(efx->pci_dev->physfn); + struct efx_ef10_nic_data *nic_data = efx->nic_data; + u8 mac[ETH_ALEN]; + + /* net_dev->dev_addr can be zeroed by efx_net_stop in + * efx_ef10_sriov_set_vf_mac, so pass in a copy. + */ + ether_addr_copy(mac, efx->net_dev->dev_addr); + + rc = efx_ef10_sriov_set_vf_mac(efx_pf, nic_data->vf_index, mac); + if (!rc) + return 0; + + netif_dbg(efx, drv, efx->net_dev, + "Updating VF mac via PF failed (%d), setting directly\n", + rc); + } +#endif + efx_device_detach_sync(efx); efx_net_stop(efx->net_dev); @@ -3293,40 +3317,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx) efx_net_open(efx->net_dev); efx_device_attach_if_not_resetting(efx); -#ifdef CONFIG_SFC_SRIOV - if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) { - struct efx_ef10_nic_data *nic_data = efx->nic_data; - struct pci_dev *pci_dev_pf = efx->pci_dev->physfn; - - if (rc == -EPERM) { - struct efx_nic *efx_pf; - - /* Switch to PF and change MAC address on vport */ - efx_pf = pci_get_drvdata(pci_dev_pf); - - rc = efx_ef10_sriov_set_vf_mac(efx_pf, - nic_data->vf_index, - efx->net_dev->dev_addr); - } else if (!rc) { - struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf); - struct efx_ef10_nic_data *nic_data = efx_pf->nic_data; - unsigned int i; - - /* MAC address successfully changed by VF (with MAC - * spoofing) so update the parent PF if possible. - */ - for (i = 0; i < efx_pf->vf_count; ++i) { - struct ef10_vf *vf = nic_data->vf + i; - - if (vf->efx == efx) { - ether_addr_copy(vf->mac, - efx->net_dev->dev_addr); - return 0; - } - } - } - } else -#endif if (rc == -EPERM) { netif_err(efx, drv, efx->net_dev, "Cannot change MAC address; use sfboot to enable" From 5ce61305199474048409af7139bb21a2e7dc2c28 Mon Sep 17 00:00:00 2001 From: Xiaobo Liu Date: Fri, 14 Oct 2022 10:05:40 +0800 Subject: [PATCH 571/610] net/atm: fix proc_mpc_write incorrect return value [ Upstream commit d8bde3bf7f82dac5fc68a62c2816793a12cafa2a ] Then the input contains '\0' or '\n', proc_mpc_write has read them, so the return value needs +1. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Xiaobo Liu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/atm/mpoa_proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 829db9eba0cb..aaf64b953915 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -219,11 +219,12 @@ static ssize_t proc_mpc_write(struct file *file, const char __user *buff, if (!page) return -ENOMEM; - for (p = page, len = 0; len < nbytes; p++, len++) { + for (p = page, len = 0; len < nbytes; p++) { if (get_user(*p, buff++)) { free_page((unsigned long)page); return -EFAULT; } + len += 1; if (*p == '\0' || *p == '\n') break; } From 412db9b06d3cc7978c4d91d0c2d8f394926ce340 Mon Sep 17 00:00:00 2001 From: Harini Katakam Date: Fri, 14 Oct 2022 12:17:35 +0530 Subject: [PATCH 572/610] net: phy: dp83867: Extend RX strap quirk for SGMII mode [ Upstream commit 0c9efbd5c50c64ead434960a404c9c9a097b0403 ] When RX strap in HW is not set to MODE 3 or 4, bit 7 and 8 in CF4 register should be set. The former is already handled in dp83867_config_init; add the latter in SGMII specific initialization. Fixes: 2a10154abcb7 ("net: phy: dp83867: Add TI dp83867 phy") Signed-off-by: Harini Katakam Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/phy/dp83867.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index d097097c93c3..783e30451e30 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -791,6 +791,14 @@ static int dp83867_config_init(struct phy_device *phydev) else val &= ~DP83867_SGMII_TYPE; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val); + + /* This is a SW workaround for link instability if RX_CTRL is + * not strapped to mode 3 or 4 in HW. This is required for SGMII + * in addition to clearing bit 7, handled above. + */ + if (dp83867->rxctrl_strap_quirk) + phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, + BIT(8)); } val = phy_read(phydev, DP83867_CFG3); From b9122e0e0ea85997e481db5062f867c797cd229b Mon Sep 17 00:00:00 2001 From: Shenwei Wang Date: Fri, 14 Oct 2022 09:47:28 -0500 Subject: [PATCH 573/610] net: phylink: add mac_managed_pm in phylink_config structure [ Upstream commit 96de900ae78e7dbedc937fd91bafe2934579c65a ] The recent commit 'commit 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state")' requires the MAC driver explicitly tell the phy driver who is managing the PM, otherwise you will see warning during resume stage. Add a boolean property in the phylink_config structure so that the MAC driver can use it to tell the PHY driver if it wants to manage the PM. Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state") Signed-off-by: Shenwei Wang Acked-by: Florian Fainelli Reviewed-by: Russell King (Oracle) Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/phy/phylink.c | 3 +++ include/linux/phylink.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index fef1416dcee4..7afcf6310d59 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1050,6 +1050,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, if (phy_interrupt_is_valid(phy)) phy_request_interrupt(phy); + if (pl->config->mac_managed_pm) + phy->mac_managed_pm = true; + return 0; } diff --git a/include/linux/phylink.h b/include/linux/phylink.h index 237291196ce2..b306159c1fad 100644 --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -64,6 +64,7 @@ enum phylink_op_type { * @pcs_poll: MAC PCS cannot provide link change interrupt * @poll_fixed_state: if true, starts link_poll, * if MAC link is at %MLO_AN_FIXED mode. + * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM. * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND * @get_fixed_state: callback to execute to determine the fixed link state, * if MAC link is at %MLO_AN_FIXED mode. @@ -73,6 +74,7 @@ struct phylink_config { enum phylink_op_type type; bool pcs_poll; bool poll_fixed_state; + bool mac_managed_pm; bool ovr_an_inband; void (*get_fixed_state)(struct phylink_config *config, struct phylink_link_state *state); From 9749595feb33a1a2b848800192224ffeed5346b4 Mon Sep 17 00:00:00 2001 From: Rafael Mendonca Date: Fri, 16 Sep 2022 00:59:07 -0300 Subject: [PATCH 574/610] scsi: lpfc: Fix memory leak in lpfc_create_port() [ Upstream commit dc8e483f684a24cc06e1d5fa958b54db58855093 ] Commit 5e633302ace1 ("scsi: lpfc: vmid: Add support for VMID in mailbox command") introduced allocations for the VMID resources in lpfc_create_port() after the call to scsi_host_alloc(). Upon failure on the VMID allocations, the new code would branch to the 'out' label, which returns NULL without unwinding anything, thus skipping the call to scsi_host_put(). Fix the problem by creating a separate label 'out_free_vmid' to unwind the VMID resources and make the 'out_put_shost' label call only scsi_host_put(), as was done before the introduction of allocations for VMID. Fixes: 5e633302ace1 ("scsi: lpfc: vmid: Add support for VMID in mailbox command") Signed-off-by: Rafael Mendonca Link: https://lore.kernel.org/r/20220916035908.712799-1-rafaelmendsr@gmail.com Reviewed-by: James Smart Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/lpfc/lpfc_init.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 33e33fff8986..48043e1ba485 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4666,7 +4666,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) rc = lpfc_vmid_res_alloc(phba, vport); if (rc) - goto out; + goto out_put_shost; /* Initialize all internally managed lists. */ INIT_LIST_HEAD(&vport->fc_nodes); @@ -4684,16 +4684,17 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); if (error) - goto out_put_shost; + goto out_free_vmid; spin_lock_irq(&phba->port_list_lock); list_add_tail(&vport->listentry, &phba->port_list); spin_unlock_irq(&phba->port_list_lock); return vport; -out_put_shost: +out_free_vmid: kfree(vport->vmid); bitmap_free(vport->vmid_priority_range); +out_put_shost: scsi_host_put(shost); out: return NULL; From a8df9d0428c7b2e4f0c7ab8da3803f3fdddfce4d Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 14 Oct 2022 11:26:25 -0700 Subject: [PATCH 575/610] udp: Update reuse->has_conns under reuseport_lock. [ Upstream commit 69421bf98482d089e50799f45e48b25ce4a8d154 ] When we call connect() for a UDP socket in a reuseport group, we have to update sk->sk_reuseport_cb->has_conns to 1. Otherwise, the kernel could select a unconnected socket wrongly for packets sent to the connected socket. However, the current way to set has_conns is illegal and possible to trigger that problem. reuseport_has_conns() changes has_conns under rcu_read_lock(), which upgrades the RCU reader to the updater. Then, it must do the update under the updater's lock, reuseport_lock, but it doesn't for now. For this reason, there is a race below where we fail to set has_conns resulting in the wrong socket selection. To avoid the race, let's split the reader and updater with proper locking. cpu1 cpu2 +----+ +----+ __ip[46]_datagram_connect() reuseport_grow() . . |- reuseport_has_conns(sk, true) |- more_reuse = __reuseport_alloc(more_socks_size) | . | | |- rcu_read_lock() | |- reuse = rcu_dereference(sk->sk_reuseport_cb) | | | | | /* reuse->has_conns == 0 here */ | | |- more_reuse->has_conns = reuse->has_conns | |- reuse->has_conns = 1 | /* more_reuse->has_conns SHOULD BE 1 HERE */ | | | | | |- rcu_assign_pointer(reuse->socks[i]->sk_reuseport_cb, | | | more_reuse) | `- rcu_read_unlock() `- kfree_rcu(reuse, rcu) | |- sk->sk_state = TCP_ESTABLISHED Note the likely(reuse) in reuseport_has_conns_set() is always true, but we put the test there for ease of review. [0] For the record, usually, sk_reuseport_cb is changed under lock_sock(). The only exception is reuseport_grow() & TCP reqsk migration case. 1) shutdown() TCP listener, which is moved into the latter part of reuse->socks[] to migrate reqsk. 2) New listen() overflows reuse->socks[] and call reuseport_grow(). 3) reuse->max_socks overflows u16 with the new listener. 4) reuseport_grow() pops the old shutdown()ed listener from the array and update its sk->sk_reuseport_cb as NULL without lock_sock(). shutdown()ed TCP sk->sk_reuseport_cb can be changed without lock_sock(), but, reuseport_has_conns_set() is called only for UDP under lock_sock(), so likely(reuse) never be false in reuseport_has_conns_set(). [0]: https://lore.kernel.org/netdev/CANn89iLja=eQHbsM_Ta2sQF0tOGU8vAGrh_izRuuHjuO1ouUag@mail.gmail.com/ Fixes: acdcecc61285 ("udp: correct reuseport selection with connected sockets") Signed-off-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20221014182625.89913-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- include/net/sock_reuseport.h | 11 +++++------ net/core/sock_reuseport.c | 16 ++++++++++++++++ net/ipv4/datagram.c | 2 +- net/ipv4/udp.c | 2 +- net/ipv6/datagram.c | 2 +- net/ipv6/udp.c | 2 +- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h index 473b0b0fa4ab..efc9085c6892 100644 --- a/include/net/sock_reuseport.h +++ b/include/net/sock_reuseport.h @@ -43,21 +43,20 @@ struct sock *reuseport_migrate_sock(struct sock *sk, extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog); extern int reuseport_detach_prog(struct sock *sk); -static inline bool reuseport_has_conns(struct sock *sk, bool set) +static inline bool reuseport_has_conns(struct sock *sk) { struct sock_reuseport *reuse; bool ret = false; rcu_read_lock(); reuse = rcu_dereference(sk->sk_reuseport_cb); - if (reuse) { - if (set) - reuse->has_conns = 1; - ret = reuse->has_conns; - } + if (reuse && reuse->has_conns) + ret = true; rcu_read_unlock(); return ret; } +void reuseport_has_conns_set(struct sock *sk); + #endif /* _SOCK_REUSEPORT_H */ diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c index 5daa1fa54249..fb90e1e00773 100644 --- a/net/core/sock_reuseport.c +++ b/net/core/sock_reuseport.c @@ -21,6 +21,22 @@ static DEFINE_IDA(reuseport_ida); static int reuseport_resurrect(struct sock *sk, struct sock_reuseport *old_reuse, struct sock_reuseport *reuse, bool bind_inany); +void reuseport_has_conns_set(struct sock *sk) +{ + struct sock_reuseport *reuse; + + if (!rcu_access_pointer(sk->sk_reuseport_cb)) + return; + + spin_lock_bh(&reuseport_lock); + reuse = rcu_dereference_protected(sk->sk_reuseport_cb, + lockdep_is_held(&reuseport_lock)); + if (likely(reuse)) + reuse->has_conns = 1; + spin_unlock_bh(&reuseport_lock); +} +EXPORT_SYMBOL(reuseport_has_conns_set); + static int reuseport_sock_index(struct sock *sk, const struct sock_reuseport *reuse, bool closed) diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 4a8550c49202..112c6e892d30 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c @@ -70,7 +70,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len } inet->inet_daddr = fl4->daddr; inet->inet_dport = usin->sin_port; - reuseport_has_conns(sk, true); + reuseport_has_conns_set(sk); sk->sk_state = TCP_ESTABLISHED; sk_set_txhash(sk); inet->inet_id = prandom_u32(); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 75d1977ecc07..79d5425bed07 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -446,7 +446,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); /* Fall back to scoring if group has connections */ - if (result && !reuseport_has_conns(sk, false)) + if (result && !reuseport_has_conns(sk)) return result; result = result ? : sk; diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 206f66310a88..f4559e5bc84b 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -256,7 +256,7 @@ ipv4_connected: goto out; } - reuseport_has_conns(sk, true); + reuseport_has_conns_set(sk); sk->sk_state = TCP_ESTABLISHED; sk_set_txhash(sk); out: diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 07726a51a3f0..19b6c4da0f42 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -180,7 +180,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); /* Fall back to scoring if group has connections */ - if (result && !reuseport_has_conns(sk, false)) + if (result && !reuseport_has_conns(sk)) return result; result = result ? : sk; From 593d877c39aa9f3fe1a4b5b022492886d7d700ec Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 17 Oct 2022 22:45:21 +0800 Subject: [PATCH 576/610] cifs: Fix xid leak in cifs_create() [ Upstream commit fee0fb1f15054bb6a0ede452acb42da5bef4d587 ] If the cifs already shutdown, we should free the xid before return, otherwise, the xid will be leaked. Fixes: 087f757b0129 ("cifs: add shutdown support") Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6e8e7cc26ae2..83c929dd6ed5 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -538,8 +538,10 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode, cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n", inode, direntry, direntry); - if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) - return -EIO; + if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) { + rc = -EIO; + goto out_free_xid; + } tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); rc = PTR_ERR(tlink); From 27cfd3afaab000a455194338db3b7f2031fde9d0 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 17 Oct 2022 22:45:22 +0800 Subject: [PATCH 577/610] cifs: Fix xid leak in cifs_copy_file_range() [ Upstream commit 9a97df404a402fe1174d2d1119f87ff2a0ca2fe9 ] If the file is used by swap, before return -EOPNOTSUPP, should free the xid, otherwise, the xid will be leaked. Fixes: 4e8aea30f775 ("smb3: enable swap on SMB3 mounts") Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/cifsfs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8ec55bbd705d..668dd6a86295 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1263,8 +1263,11 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, ssize_t rc; struct cifsFileInfo *cfile = dst_file->private_data; - if (cfile->swapfile) - return -EOPNOTSUPP; + if (cfile->swapfile) { + rc = -EOPNOTSUPP; + free_xid(xid); + return rc; + } rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff, len, flags); From 8905d13b9ede4caa88c577faed832d6c7383f4fb Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 17 Oct 2022 22:45:23 +0800 Subject: [PATCH 578/610] cifs: Fix xid leak in cifs_flock() [ Upstream commit 575e079c782b9862ec2626403922d041a42e6ed6 ] If not flock, before return -ENOLCK, should free the xid, otherwise, the xid will be leaked. Fixes: d0677992d2af ("cifs: add support for flock") Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/file.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ffec3a2f995d..aa422348824a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1806,11 +1806,13 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl) struct cifsFileInfo *cfile; __u32 type; - rc = -EACCES; xid = get_xid(); - if (!(fl->fl_flags & FL_FLOCK)) - return -ENOLCK; + if (!(fl->fl_flags & FL_FLOCK)) { + rc = -ENOLCK; + free_xid(xid); + return rc; + } cfile = (struct cifsFileInfo *)file->private_data; tcon = tlink_tcon(cfile->tlink); @@ -1829,8 +1831,9 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl) * if no lock or unlock then nothing to do since we do not * know what it is */ + rc = -EOPNOTSUPP; free_xid(xid); - return -EOPNOTSUPP; + return rc; } rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock, From 847301f0ee1c29f34cc48547ce1071990f24969c Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Mon, 17 Oct 2022 22:45:24 +0800 Subject: [PATCH 579/610] cifs: Fix xid leak in cifs_ses_add_channel() [ Upstream commit e909d054bdea75ef1ec48c18c5936affdaecbb2c ] Before return, should free the xid, otherwise, the xid will be leaked. Fixes: d70e9fa55884 ("cifs: try opening channels after mounting") Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/sess.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 5500ea783784..0fbd0f78f361 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -320,6 +320,7 @@ out: if (rc && chan->server) cifs_put_tcp_session(chan->server, 0); + free_xid(xid); return rc; } From e326df21da252d2ebc50ceba204a5540c602afad Mon Sep 17 00:00:00 2001 From: Genjian Zhang Date: Thu, 29 Sep 2022 16:20:36 +0800 Subject: [PATCH 580/610] dm: remove unnecessary assignment statement in alloc_dev() [ Upstream commit 99f4f5bcb975527508eb7a5e3e34bdb91d576746 ] Fixes: 74fe6ba923949 ("dm: convert to blk_alloc_disk/blk_cleanup_disk") Signed-off-by: Genjian Zhang 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 41d2e1285c07..9dd2c2da075d 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1797,7 +1797,6 @@ static struct mapped_device *alloc_dev(int minor) md->disk->first_minor = minor; md->disk->minors = 1; md->disk->fops = &dm_blk_dops; - md->disk->queue = md->queue; md->disk->private_data = md; sprintf(md->disk->disk_name, "dm-%d", minor); From 35ece858660eae13ee0242496a1956c39d29418e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 17 Oct 2022 16:59:28 +0000 Subject: [PATCH 581/610] net: hsr: avoid possible NULL deref in skb_clone() [ Upstream commit d8b57135fd9ffe9a5b445350a686442a531c5339 ] syzbot got a crash [1] in skb_clone(), caused by a bug in hsr_get_untagged_frame(). When/if create_stripped_skb_hsr() returns NULL, we must not attempt to call skb_clone(). While we are at it, replace a WARN_ONCE() by netdev_warn_once(). [1] general protection fault, probably for non-canonical address 0xdffffc000000000f: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000078-0x000000000000007f] CPU: 1 PID: 754 Comm: syz-executor.0 Not tainted 6.0.0-syzkaller-02734-g0326074ff465 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/22/2022 RIP: 0010:skb_clone+0x108/0x3c0 net/core/skbuff.c:1641 Code: 93 02 00 00 49 83 7c 24 28 00 0f 85 e9 00 00 00 e8 5d 4a 29 fa 4c 8d 75 7e 48 b8 00 00 00 00 00 fc ff df 4c 89 f2 48 c1 ea 03 <0f> b6 04 02 4c 89 f2 83 e2 07 38 d0 7f 08 84 c0 0f 85 9e 01 00 00 RSP: 0018:ffffc90003ccf4e0 EFLAGS: 00010207 RAX: dffffc0000000000 RBX: ffffc90003ccf5f8 RCX: ffffc9000c24b000 RDX: 000000000000000f RSI: ffffffff8751cb13 RDI: 0000000000000000 RBP: 0000000000000000 R08: 00000000000000f0 R09: 0000000000000140 R10: fffffbfff181d972 R11: 0000000000000000 R12: ffff888161fc3640 R13: 0000000000000a20 R14: 000000000000007e R15: ffffffff8dc5f620 FS: 00007feb621e4700(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007feb621e3ff8 CR3: 00000001643a9000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: hsr_get_untagged_frame+0x4e/0x610 net/hsr/hsr_forward.c:164 hsr_forward_do net/hsr/hsr_forward.c:461 [inline] hsr_forward_skb+0xcca/0x1d50 net/hsr/hsr_forward.c:623 hsr_handle_frame+0x588/0x7c0 net/hsr/hsr_slave.c:69 __netif_receive_skb_core+0x9fe/0x38f0 net/core/dev.c:5379 __netif_receive_skb_one_core+0xae/0x180 net/core/dev.c:5483 __netif_receive_skb+0x1f/0x1c0 net/core/dev.c:5599 netif_receive_skb_internal net/core/dev.c:5685 [inline] netif_receive_skb+0x12f/0x8d0 net/core/dev.c:5744 tun_rx_batched+0x4ab/0x7a0 drivers/net/tun.c:1544 tun_get_user+0x2686/0x3a00 drivers/net/tun.c:1995 tun_chr_write_iter+0xdb/0x200 drivers/net/tun.c:2025 call_write_iter include/linux/fs.h:2187 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x9e9/0xdd0 fs/read_write.c:584 ksys_write+0x127/0x250 fs/read_write.c:637 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: f266a683a480 ("net/hsr: Better frame dispatch") Reported-by: syzbot Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/r/20221017165928.2150130-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/hsr/hsr_forward.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index ceb8afb2a62f..13f81c246f5f 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -108,15 +108,15 @@ struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, struct hsr_port *port) { if (!frame->skb_std) { - if (frame->skb_hsr) { + if (frame->skb_hsr) frame->skb_std = create_stripped_skb_hsr(frame->skb_hsr, frame); - } else { - /* Unexpected */ - WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", - __FILE__, __LINE__, port->dev->name); + else + netdev_warn_once(port->dev, + "Unexpected frame received in hsr_get_untagged_frame()\n"); + + if (!frame->skb_std) return NULL; - } } return skb_clone(frame->skb_std, GFP_ATOMIC); From efa9dd7e679eac06fba75f1d36b17161b48c02b7 Mon Sep 17 00:00:00 2001 From: Brett Creeley Date: Mon, 17 Oct 2022 16:31:23 -0700 Subject: [PATCH 582/610] ionic: catch NULL pointer issue on reconfig [ Upstream commit aa1d7e1267c12e07d979aa34c613716a89029db2 ] It's possible that the driver will dereference a qcq that doesn't exist when calling ionic_reconfigure_queues(), which causes a page fault BUG. If a reduction in the number of queues is followed by a different reconfig such as changing the ring size, the driver can hit a NULL pointer when trying to clean up non-existent queues. Fix this by checking to make sure both the qcqs array and qcq entry exists bofore trying to use and free the entry. Fixes: 101b40a0171f ("ionic: change queue count with no reset") Signed-off-by: Brett Creeley Signed-off-by: Shannon Nelson Link: https://lore.kernel.org/r/20221017233123.15869-1-snelson@pensando.io Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index c713a3ee6571..886c997a3ad1 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -2880,11 +2880,15 @@ err_out: * than the full array, but leave the qcq shells in place */ for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) { - lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; - ionic_qcq_free(lif, lif->txqcqs[i]); + if (lif->txqcqs && lif->txqcqs[i]) { + lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; + ionic_qcq_free(lif, lif->txqcqs[i]); + } - lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; - ionic_qcq_free(lif, lif->rxqcqs[i]); + if (lif->rxqcqs && lif->rxqcqs[i]) { + lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; + ionic_qcq_free(lif, lif->rxqcqs[i]); + } } if (err) From d77f6908f9cec12857075f138419b8cea359121d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 17 Oct 2022 14:12:58 +0200 Subject: [PATCH 583/610] netfilter: nf_tables: relax NFTA_SET_ELEM_KEY_END set flags requirements [ Upstream commit 96df8360dbb435cc69f7c3c8db44bf8b1c24cd7b ] Otherwise EINVAL is bogusly reported to userspace when deleting a set element. NFTA_SET_ELEM_KEY_END does not need to be set in case of: - insertion: if not present, start key is used as end key. - deletion: only start key needs to be specified, end key is ignored. Hence, relax the sanity check. Fixes: 88cccd908d51 ("netfilter: nf_tables: NFTA_SET_ELEM_KEY_END requires concat and interval flags") Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_tables_api.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 460ad341d160..f7a5b8414423 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5720,8 +5720,9 @@ static bool nft_setelem_valid_key_end(const struct nft_set *set, (NFT_SET_CONCAT | NFT_SET_INTERVAL)) { if (flags & NFT_SET_ELEM_INTERVAL_END) return false; - if (!nla[NFTA_SET_ELEM_KEY_END] && - !(flags & NFT_SET_ELEM_CATCHALL)) + + if (nla[NFTA_SET_ELEM_KEY_END] && + flags & NFT_SET_ELEM_CATCHALL) return false; } else { if (nla[NFTA_SET_ELEM_KEY_END]) From 66c56b2328393622f70e4e9960a4d62e1be25348 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 18 Oct 2022 16:55:55 +0200 Subject: [PATCH 584/610] nvme-hwmon: consistently ignore errors from nvme_hwmon_init [ Upstream commit 6b8cf94005187952f794c0c4ed3920a1e8accfa3 ] An NVMe controller works perfectly fine even when the hwmon initialization fails. Stop returning errors that do not come from a controller reset from nvme_hwmon_init to handle this case consistently. Signed-off-by: Christoph Hellwig Reviewed-by: Guenter Roeck Reviewed-by: Serge Semin Stable-dep-of: c94b7f9bab22 ("nvme-hwmon: kmalloc the NVME SMART log buffer") Signed-off-by: Sasha Levin --- drivers/nvme/host/core.c | 6 +++++- drivers/nvme/host/hwmon.c | 13 ++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 3527a0667568..92fe67bd2457 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3088,8 +3088,12 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) return ret; if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) { + /* + * Do not return errors unless we are in a controller reset, + * the controller works perfectly fine without hwmon. + */ ret = nvme_hwmon_init(ctrl); - if (ret < 0) + if (ret == -EINTR) return ret; } diff --git a/drivers/nvme/host/hwmon.c b/drivers/nvme/host/hwmon.c index 0a586d712920..23918bb7bdca 100644 --- a/drivers/nvme/host/hwmon.c +++ b/drivers/nvme/host/hwmon.c @@ -230,7 +230,7 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl) data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) - return 0; + return -ENOMEM; data->ctrl = ctrl; mutex_init(&data->read_lock); @@ -238,8 +238,7 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl) err = nvme_hwmon_get_smart_log(data); if (err) { dev_warn(dev, "Failed to read smart log (error %d)\n", err); - kfree(data); - return err; + goto err_free_data; } hwmon = hwmon_device_register_with_info(dev, "nvme", @@ -247,11 +246,15 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl) NULL); if (IS_ERR(hwmon)) { dev_warn(dev, "Failed to instantiate hwmon device\n"); - kfree(data); - return PTR_ERR(hwmon); + err = PTR_ERR(hwmon); + goto err_free_data; } ctrl->hwmon_device = hwmon; return 0; + +err_free_data: + kfree(data); + return err; } void nvme_hwmon_exit(struct nvme_ctrl *ctrl) From 2f2b84b0208848c5a17e9f52a6489d27bf7cb5b6 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Tue, 18 Oct 2022 17:33:52 +0200 Subject: [PATCH 585/610] nvme-hwmon: kmalloc the NVME SMART log buffer [ Upstream commit c94b7f9bab22ac504f9153767676e659988575ad ] Recent commit 52fde2c07da6 ("nvme: set dma alignment to dword") has caused a regression on our platform. It turned out that the nvme_get_log() method invocation caused the nvme_hwmon_data structure instance corruption. In particular the nvme_hwmon_data.ctrl pointer was overwritten either with zeros or with garbage. After some research we discovered that the problem happened even before the actual NVME DMA execution, but during the buffer mapping. Since our platform is DMA-noncoherent, the mapping implied the cache-line invalidations or write-backs depending on the DMA-direction parameter. In case of the NVME SMART log getting the DMA was performed from-device-to-memory, thus the cache-invalidation was activated during the buffer mapping. Since the log-buffer isn't cache-line aligned, the cache-invalidation caused the neighbour data to be discarded. The neighbouring data turned to be the data surrounding the buffer in the framework of the nvme_hwmon_data structure. In order to fix that we need to make sure that the whole log-buffer is defined within the cache-line-aligned memory region so the cache-invalidation procedure wouldn't involve the adjacent data. One of the option to guarantee that is to kmalloc the DMA-buffer [1]. Seeing the rest of the NVME core driver prefer that method it has been chosen to fix this problem too. Note after a deeper researches we found out that the denoted commit wasn't a root cause of the problem. It just revealed the invalidity by activating the DMA-based NVME SMART log getting performed in the framework of the NVME hwmon driver. The problem was here since the initial commit of the driver. [1] Documentation/core-api/dma-api-howto.rst Fixes: 400b6a7b13a3 ("nvme: Add hardware monitoring support") Signed-off-by: Serge Semin Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/hwmon.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/nvme/host/hwmon.c b/drivers/nvme/host/hwmon.c index 23918bb7bdca..9e6e56c20ec9 100644 --- a/drivers/nvme/host/hwmon.c +++ b/drivers/nvme/host/hwmon.c @@ -12,7 +12,7 @@ struct nvme_hwmon_data { struct nvme_ctrl *ctrl; - struct nvme_smart_log log; + struct nvme_smart_log *log; struct mutex read_lock; }; @@ -60,14 +60,14 @@ static int nvme_set_temp_thresh(struct nvme_ctrl *ctrl, int sensor, bool under, static int nvme_hwmon_get_smart_log(struct nvme_hwmon_data *data) { return nvme_get_log(data->ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0, - NVME_CSI_NVM, &data->log, sizeof(data->log), 0); + NVME_CSI_NVM, data->log, sizeof(*data->log), 0); } static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { struct nvme_hwmon_data *data = dev_get_drvdata(dev); - struct nvme_smart_log *log = &data->log; + struct nvme_smart_log *log = data->log; int temp; int err; @@ -163,7 +163,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data, case hwmon_temp_max: case hwmon_temp_min: if ((!channel && data->ctrl->wctemp) || - (channel && data->log.temp_sensor[channel - 1])) { + (channel && data->log->temp_sensor[channel - 1])) { if (data->ctrl->quirks & NVME_QUIRK_NO_TEMP_THRESH_CHANGE) return 0444; @@ -176,7 +176,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data, break; case hwmon_temp_input: case hwmon_temp_label: - if (!channel || data->log.temp_sensor[channel - 1]) + if (!channel || data->log->temp_sensor[channel - 1]) return 0444; break; default: @@ -232,13 +232,19 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl) if (!data) return -ENOMEM; + data->log = kzalloc(sizeof(*data->log), GFP_KERNEL); + if (!data->log) { + err = -ENOMEM; + goto err_free_data; + } + data->ctrl = ctrl; mutex_init(&data->read_lock); err = nvme_hwmon_get_smart_log(data); if (err) { dev_warn(dev, "Failed to read smart log (error %d)\n", err); - goto err_free_data; + goto err_free_log; } hwmon = hwmon_device_register_with_info(dev, "nvme", @@ -247,11 +253,13 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl) if (IS_ERR(hwmon)) { dev_warn(dev, "Failed to instantiate hwmon device\n"); err = PTR_ERR(hwmon); - goto err_free_data; + goto err_free_log; } ctrl->hwmon_device = hwmon; return 0; +err_free_log: + kfree(data->log); err_free_data: kfree(data); return err; @@ -265,6 +273,7 @@ void nvme_hwmon_exit(struct nvme_ctrl *ctrl) hwmon_device_unregister(ctrl->hwmon_device); ctrl->hwmon_device = NULL; + kfree(data->log); kfree(data); } } From 5efed7578dd44d2d8c256081d1dd1ed845e46491 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Wed, 28 Sep 2022 09:39:10 +0300 Subject: [PATCH 586/610] nvmet: fix workqueue MEM_RECLAIM flushing dependency [ Upstream commit ddd2b8de9f85b388925e7dc46b3890fc1a0d8d24 ] The keep alive timer needs to stay on nvmet_wq, and not modified to reschedule on the system_wq. This fixes a warning: ------------[ cut here ]------------ workqueue: WQ_MEM_RECLAIM nvmet-wq:nvmet_rdma_release_queue_work [nvmet_rdma] is flushing !WQ_MEM_RECLAIM events:nvmet_keep_alive_timer [nvmet] WARNING: CPU: 3 PID: 1086 at kernel/workqueue.c:2628 check_flush_dependency+0x16c/0x1e0 Reported-by: Yi Zhang Fixes: 8832cf922151 ("nvmet: use a private workqueue instead of the system workqueue") Signed-off-by: Sagi Grimberg Reviewed-by: Chaitanya Kulkarni Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/target/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 0a0c1d956c73..87a347248c38 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1168,7 +1168,7 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl) * reset the keep alive timer when the controller is enabled. */ if (ctrl->kato) - mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ); + mod_delayed_work(nvmet_wq, &ctrl->ka_work, ctrl->kato * HZ); } static void nvmet_clear_ctrl(struct nvmet_ctrl *ctrl) From 154f4c06d9dbec1a14e91286c70b6305810302e0 Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Tue, 18 Oct 2022 14:31:59 +0800 Subject: [PATCH 587/610] net: sched: cake: fix null pointer access issue when cake_init() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 51f9a8921ceacd7bf0d3f47fa867a64988ba1dcb ] When the default qdisc is cake, if the qdisc of dev_queue fails to be inited during mqprio_init(), cake_reset() is invoked to clear resources. In this case, the tins is NULL, and it will cause gpf issue. The process is as follows: qdisc_create_dflt() cake_init() q->tins = kvcalloc(...) --->failed, q->tins is NULL ... qdisc_put() ... cake_reset() ... cake_dequeue_one() b = &q->tins[...] --->q->tins is NULL The following is the Call Trace information: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:cake_dequeue_one+0xc9/0x3c0 Call Trace: cake_reset+0xb1/0x140 qdisc_reset+0xed/0x6f0 qdisc_destroy+0x82/0x4c0 qdisc_put+0x9e/0xb0 qdisc_create_dflt+0x2c3/0x4a0 mqprio_init+0xa71/0x1760 qdisc_create+0x3eb/0x1000 tc_modify_qdisc+0x408/0x1720 rtnetlink_rcv_msg+0x38e/0xac0 netlink_rcv_skb+0x12d/0x3a0 netlink_unicast+0x4a2/0x740 netlink_sendmsg+0x826/0xcc0 sock_sendmsg+0xc5/0x100 ____sys_sendmsg+0x583/0x690 ___sys_sendmsg+0xe8/0x160 __sys_sendmsg+0xbf/0x160 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x7f89e5122d04 Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc") Signed-off-by: Zhengchao Shao Acked-by: Toke Høiland-Jørgensen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/sch_cake.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index 857aaebd49f4..6f6e74ce927f 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -2224,8 +2224,12 @@ retry: static void cake_reset(struct Qdisc *sch) { + struct cake_sched_data *q = qdisc_priv(sch); u32 c; + if (!q->tins) + return; + for (c = 0; c < CAKE_MAX_TINS; c++) cake_clear_tin(sch, c); } From 34f2a4eedc8e4a748a4dce88c561fdb839557c97 Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Wed, 24 Aug 2022 08:52:31 +0800 Subject: [PATCH 588/610] net: sched: delete duplicate cleanup of backlog and qlen [ Upstream commit c19d893fbf3f2f8fa864ae39652c7fee939edde2 ] qdisc_reset() is clearing qdisc->q.qlen and qdisc->qstats.backlog _after_ calling qdisc->ops->reset. There is no need to clear them again in the specific reset function. Signed-off-by: Zhengchao Shao Link: https://lore.kernel.org/r/20220824005231.345727-1-shaozhengchao@huawei.com Signed-off-by: Paolo Abeni Stable-dep-of: 2a3fc78210b9 ("net: sched: sfb: fix null pointer access issue when sfb_init() fails") Signed-off-by: Sasha Levin --- include/net/sch_generic.h | 1 - net/sched/sch_atm.c | 1 - net/sched/sch_cbq.c | 1 - net/sched/sch_choke.c | 2 -- net/sched/sch_drr.c | 2 -- net/sched/sch_dsmark.c | 2 -- net/sched/sch_etf.c | 3 --- net/sched/sch_ets.c | 2 -- net/sched/sch_fq_codel.c | 2 -- net/sched/sch_fq_pie.c | 3 --- net/sched/sch_hfsc.c | 2 -- net/sched/sch_htb.c | 2 -- net/sched/sch_multiq.c | 1 - net/sched/sch_prio.c | 2 -- net/sched/sch_qfq.c | 2 -- net/sched/sch_red.c | 2 -- net/sched/sch_sfb.c | 2 -- net/sched/sch_skbprio.c | 3 --- net/sched/sch_taprio.c | 2 -- net/sched/sch_tbf.c | 2 -- net/sched/sch_teql.c | 1 - 21 files changed, 40 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 1958d1260fe9..891b44d80c98 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1177,7 +1177,6 @@ static inline void __qdisc_reset_queue(struct qdisc_skb_head *qh) static inline void qdisc_reset_queue(struct Qdisc *sch) { __qdisc_reset_queue(&sch->q); - sch->qstats.backlog = 0; } static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new, diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 7d8518176b45..70fe1c5e44ad 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -576,7 +576,6 @@ static void atm_tc_reset(struct Qdisc *sch) pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p); list_for_each_entry(flow, &p->flows, list) qdisc_reset(flow->q); - sch->q.qlen = 0; } static void atm_tc_destroy(struct Qdisc *sch) diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index e0da15530f0e..fd7e10567371 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1053,7 +1053,6 @@ cbq_reset(struct Qdisc *sch) cl->cpriority = cl->priority; } } - sch->q.qlen = 0; } diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 2adbd945bf15..25d2daaa8122 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -315,8 +315,6 @@ static void choke_reset(struct Qdisc *sch) rtnl_qdisc_drop(skb, sch); } - sch->q.qlen = 0; - sch->qstats.backlog = 0; if (q->tab) memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); q->head = q->tail = 0; diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 642cd179b7a7..80a88e208d2b 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -444,8 +444,6 @@ static void drr_reset_qdisc(struct Qdisc *sch) qdisc_reset(cl->qdisc); } } - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static void drr_destroy_qdisc(struct Qdisc *sch) diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 4c100d105269..7da6dc38a382 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -409,8 +409,6 @@ static void dsmark_reset(struct Qdisc *sch) pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); if (p->q) qdisc_reset(p->q); - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static void dsmark_destroy(struct Qdisc *sch) diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c index c48f91075b5c..d96103b0e2bf 100644 --- a/net/sched/sch_etf.c +++ b/net/sched/sch_etf.c @@ -445,9 +445,6 @@ static void etf_reset(struct Qdisc *sch) timesortedlist_clear(sch); __qdisc_reset_queue(&sch->q); - sch->qstats.backlog = 0; - sch->q.qlen = 0; - q->last = 0; } diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c index 44fa2532a87c..175e07b3d25c 100644 --- a/net/sched/sch_ets.c +++ b/net/sched/sch_ets.c @@ -722,8 +722,6 @@ static void ets_qdisc_reset(struct Qdisc *sch) } for (band = 0; band < q->nbands; band++) qdisc_reset(q->classes[band].qdisc); - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static void ets_qdisc_destroy(struct Qdisc *sch) diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index bb0cd6d3d2c2..efda894bbb78 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -347,8 +347,6 @@ static void fq_codel_reset(struct Qdisc *sch) codel_vars_init(&flow->cvars); } memset(q->backlogs, 0, q->flows_cnt * sizeof(u32)); - sch->q.qlen = 0; - sch->qstats.backlog = 0; q->memory_usage = 0; } diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c index d6aba6edd16e..35c35465226b 100644 --- a/net/sched/sch_fq_pie.c +++ b/net/sched/sch_fq_pie.c @@ -521,9 +521,6 @@ static void fq_pie_reset(struct Qdisc *sch) INIT_LIST_HEAD(&flow->flowchain); pie_vars_init(&flow->vars); } - - sch->q.qlen = 0; - sch->qstats.backlog = 0; } static void fq_pie_destroy(struct Qdisc *sch) diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index b7ac30cca035..c802a027b4f3 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1485,8 +1485,6 @@ hfsc_reset_qdisc(struct Qdisc *sch) } q->eligible = RB_ROOT; qdisc_watchdog_cancel(&q->watchdog); - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static void diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 5cbc32fee867..caabdaa2f30f 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1008,8 +1008,6 @@ static void htb_reset(struct Qdisc *sch) } qdisc_watchdog_cancel(&q->watchdog); __qdisc_reset_queue(&q->direct_queue); - sch->q.qlen = 0; - sch->qstats.backlog = 0; memset(q->hlevel, 0, sizeof(q->hlevel)); memset(q->row_mask, 0, sizeof(q->row_mask)); } diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index e282e7382117..8b99f07aa3a7 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -152,7 +152,6 @@ multiq_reset(struct Qdisc *sch) for (band = 0; band < q->bands; band++) qdisc_reset(q->queues[band]); - sch->q.qlen = 0; q->curband = 0; } diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 03fdf31ccb6a..2e0b1e7f5466 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -135,8 +135,6 @@ prio_reset(struct Qdisc *sch) for (prio = 0; prio < q->bands; prio++) qdisc_reset(q->queues[prio]); - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index aea435b0aeb3..50e51c1322fc 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -1459,8 +1459,6 @@ static void qfq_reset_qdisc(struct Qdisc *sch) qdisc_reset(cl->qdisc); } } - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static void qfq_destroy_qdisc(struct Qdisc *sch) diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 40adf1f07a82..f1e013e3f04a 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -176,8 +176,6 @@ static void red_reset(struct Qdisc *sch) struct red_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); - sch->qstats.backlog = 0; - sch->q.qlen = 0; red_restart(&q->vars); } diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 2829455211f8..1be8d04d69dc 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -456,8 +456,6 @@ static void sfb_reset(struct Qdisc *sch) struct sfb_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); - sch->qstats.backlog = 0; - sch->q.qlen = 0; q->slot = 0; q->double_buffering = false; sfb_zero_all_buckets(q); diff --git a/net/sched/sch_skbprio.c b/net/sched/sch_skbprio.c index 7a5e4c454715..df72fb83d9c7 100644 --- a/net/sched/sch_skbprio.c +++ b/net/sched/sch_skbprio.c @@ -213,9 +213,6 @@ static void skbprio_reset(struct Qdisc *sch) struct skbprio_sched_data *q = qdisc_priv(sch); int prio; - sch->qstats.backlog = 0; - sch->q.qlen = 0; - for (prio = 0; prio < SKBPRIO_MAX_PRIORITY; prio++) __skb_queue_purge(&q->qdiscs[prio]); diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index ae7ca68f2cf9..bd10a8eeb82d 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1637,8 +1637,6 @@ static void taprio_reset(struct Qdisc *sch) if (q->qdiscs[i]) qdisc_reset(q->qdiscs[i]); } - sch->qstats.backlog = 0; - sch->q.qlen = 0; } static void taprio_destroy(struct Qdisc *sch) diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 6eb17004a9e4..7461e5c67d50 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -316,8 +316,6 @@ static void tbf_reset(struct Qdisc *sch) struct tbf_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); - sch->qstats.backlog = 0; - sch->q.qlen = 0; q->t_c = ktime_get_ns(); q->tokens = q->buffer; q->ptokens = q->mtu; diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 6af6b95bdb67..79aaab51cbf5 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -124,7 +124,6 @@ teql_reset(struct Qdisc *sch) struct teql_sched_data *dat = qdisc_priv(sch); skb_queue_purge(&dat->q); - sch->q.qlen = 0; } static void From c2e1e59d59fafe297779ceae1fe0e6fbebc3e745 Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Tue, 18 Oct 2022 14:32:01 +0800 Subject: [PATCH 589/610] net: sched: sfb: fix null pointer access issue when sfb_init() fails [ Upstream commit 2a3fc78210b9f0e85372a2435368962009f480fc ] When the default qdisc is sfb, if the qdisc of dev_queue fails to be inited during mqprio_init(), sfb_reset() is invoked to clear resources. In this case, the q->qdisc is NULL, and it will cause gpf issue. The process is as follows: qdisc_create_dflt() sfb_init() tcf_block_get() --->failed, q->qdisc is NULL ... qdisc_put() ... sfb_reset() qdisc_reset(q->qdisc) --->q->qdisc is NULL ops = qdisc->ops The following is the Call Trace information: general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f] RIP: 0010:qdisc_reset+0x2b/0x6f0 Call Trace: sfb_reset+0x37/0xd0 qdisc_reset+0xed/0x6f0 qdisc_destroy+0x82/0x4c0 qdisc_put+0x9e/0xb0 qdisc_create_dflt+0x2c3/0x4a0 mqprio_init+0xa71/0x1760 qdisc_create+0x3eb/0x1000 tc_modify_qdisc+0x408/0x1720 rtnetlink_rcv_msg+0x38e/0xac0 netlink_rcv_skb+0x12d/0x3a0 netlink_unicast+0x4a2/0x740 netlink_sendmsg+0x826/0xcc0 sock_sendmsg+0xc5/0x100 ____sys_sendmsg+0x583/0x690 ___sys_sendmsg+0xe8/0x160 __sys_sendmsg+0xbf/0x160 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x7f2164122d04 Fixes: e13e02a3c68d ("net_sched: SFB flow scheduler") Signed-off-by: Zhengchao Shao Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/sch_sfb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 1be8d04d69dc..0490eb5b98de 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -455,7 +455,8 @@ static void sfb_reset(struct Qdisc *sch) { struct sfb_sched_data *q = qdisc_priv(sch); - qdisc_reset(q->qdisc); + if (likely(q->qdisc)) + qdisc_reset(q->qdisc); q->slot = 0; q->double_buffering = false; sfb_zero_all_buckets(q); From d2fc83a6b55ea775d9300f7099f9e1d25f305676 Mon Sep 17 00:00:00 2001 From: Pieter Jansen van Vuuren Date: Tue, 18 Oct 2022 10:28:41 +0100 Subject: [PATCH 590/610] sfc: include vport_id in filter spec hash and equal() [ Upstream commit c2bf23e4a5af37a4d77901d9ff14c50a269f143d ] Filters on different vports are qualified by different implicit MACs and/or VLANs, so shouldn't be considered equal even if their other match fields are identical. Fixes: 7c460d9be610 ("sfc: Extend and abstract efx_filter_spec to cover Huntington/EF10") Co-developed-by: Edward Cree Signed-off-by: Edward Cree Signed-off-by: Pieter Jansen van Vuuren Reviewed-by: Martin Habets Link: https://lore.kernel.org/r/20221018092841.32206-1-pieter.jansen-van-vuuren@amd.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/sfc/filter.h | 3 ++- drivers/net/ethernet/sfc/rx_common.c | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h index 40b2af8bfb81..2ac3c8f1b04b 100644 --- a/drivers/net/ethernet/sfc/filter.h +++ b/drivers/net/ethernet/sfc/filter.h @@ -157,7 +157,8 @@ struct efx_filter_spec { u32 flags:6; u32 dmaq_id:12; u32 rss_context; - __be16 outer_vid __aligned(4); /* allow jhash2() of match values */ + u32 vport_id; + __be16 outer_vid; __be16 inner_vid; u8 loc_mac[ETH_ALEN]; u8 rem_mac[ETH_ALEN]; diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c index b925de9b4302..a804c754cd7d 100644 --- a/drivers/net/ethernet/sfc/rx_common.c +++ b/drivers/net/ethernet/sfc/rx_common.c @@ -676,17 +676,17 @@ bool efx_filter_spec_equal(const struct efx_filter_spec *left, (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX))) return false; - return memcmp(&left->outer_vid, &right->outer_vid, + return memcmp(&left->vport_id, &right->vport_id, sizeof(struct efx_filter_spec) - - offsetof(struct efx_filter_spec, outer_vid)) == 0; + offsetof(struct efx_filter_spec, vport_id)) == 0; } u32 efx_filter_spec_hash(const struct efx_filter_spec *spec) { - BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3); - return jhash2((const u32 *)&spec->outer_vid, + BUILD_BUG_ON(offsetof(struct efx_filter_spec, vport_id) & 3); + return jhash2((const u32 *)&spec->vport_id, (sizeof(struct efx_filter_spec) - - offsetof(struct efx_filter_spec, outer_vid)) / 4, + offsetof(struct efx_filter_spec, vport_id)) / 4, 0); } From 50c31fa952309536c6e4461ff815ddccc8dff9d5 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 18 Oct 2022 21:16:07 +0800 Subject: [PATCH 591/610] wwan_hwsim: fix possible memory leak in wwan_hwsim_dev_new() [ Upstream commit 258ad2fe5ede773625adfda88b173f4123e59f45 ] Inject fault while probing module, if device_register() fails, but the refcount of kobject is not decreased to 0, the name allocated in dev_set_name() is leaked. Fix this by calling put_device(), so that name can be freed in callback function kobject_cleanup(). unreferenced object 0xffff88810152ad20 (size 8): comm "modprobe", pid 252, jiffies 4294849206 (age 22.713s) hex dump (first 8 bytes): 68 77 73 69 6d 30 00 ff hwsim0.. backtrace: [<000000009c3504ed>] __kmalloc_node_track_caller+0x44/0x1b0 [<00000000c0228a5e>] kvasprintf+0xb5/0x140 [<00000000cff8c21f>] kvasprintf_const+0x55/0x180 [<0000000055a1e073>] kobject_set_name_vargs+0x56/0x150 [<000000000a80b139>] dev_set_name+0xab/0xe0 Fixes: f36a111a74e7 ("wwan_hwsim: WWAN device simulator") Signed-off-by: Yang Yingliang Reviewed-by: Loic Poulain Acked-by: Sergey Ryazanov Link: https://lore.kernel.org/r/20221018131607.1901641-1-yangyingliang@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/wwan/wwan_hwsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wwan/wwan_hwsim.c b/drivers/net/wwan/wwan_hwsim.c index 5b62cf3b3c42..a4230a7376df 100644 --- a/drivers/net/wwan/wwan_hwsim.c +++ b/drivers/net/wwan/wwan_hwsim.c @@ -310,7 +310,7 @@ err_unreg_dev: return ERR_PTR(err); err_free_dev: - kfree(dev); + put_device(&dev->dev); return ERR_PTR(err); } From 91f8f5342bee726ed5692583d58f69e7cc9ae60e Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 18 Oct 2022 20:24:51 +0800 Subject: [PATCH 592/610] net: hns: fix possible memory leak in hnae_ae_register() [ Upstream commit ff2f5ec5d009844ec28f171123f9e58750cef4bf ] Inject fault while probing module, if device_register() fails, but the refcount of kobject is not decreased to 0, the name allocated in dev_set_name() is leaked. Fix this by calling put_device(), so that name can be freed in callback function kobject_cleanup(). unreferenced object 0xffff00c01aba2100 (size 128): comm "systemd-udevd", pid 1259, jiffies 4294903284 (age 294.152s) hex dump (first 32 bytes): 68 6e 61 65 30 00 00 00 18 21 ba 1a c0 00 ff ff hnae0....!...... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<0000000034783f26>] slab_post_alloc_hook+0xa0/0x3e0 [<00000000748188f2>] __kmem_cache_alloc_node+0x164/0x2b0 [<00000000ab0743e8>] __kmalloc_node_track_caller+0x6c/0x390 [<000000006c0ffb13>] kvasprintf+0x8c/0x118 [<00000000fa27bfe1>] kvasprintf_const+0x60/0xc8 [<0000000083e10ed7>] kobject_set_name_vargs+0x3c/0xc0 [<000000000b87affc>] dev_set_name+0x7c/0xa0 [<000000003fd8fe26>] hnae_ae_register+0xcc/0x190 [hnae] [<00000000fe97edc9>] hns_dsaf_ae_init+0x9c/0x108 [hns_dsaf] [<00000000c36ff1eb>] hns_dsaf_probe+0x548/0x748 [hns_dsaf] Fixes: 6fe6611ff275 ("net: add Hisilicon Network Subsystem hnae framework support") Signed-off-by: Yang Yingliang Reviewed-by: Leon Romanovsky Link: https://lore.kernel.org/r/20221018122451.1749171-1-yangyingliang@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/hisilicon/hns/hnae.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index 00fafc0f8512..430eccea8e5e 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -419,8 +419,10 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner) hdev->cls_dev.release = hnae_release; (void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id); ret = device_register(&hdev->cls_dev); - if (ret) + if (ret) { + put_device(&hdev->cls_dev); return ret; + } __module_get(THIS_MODULE); From ce1234573d183db1ebcab524668ca2d85543bf80 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 18 Oct 2022 20:32:58 +0000 Subject: [PATCH 593/610] net: sched: fix race condition in qdisc_graft() [ Upstream commit ebda44da44f6f309d302522b049f43d6f829f7aa ] We had one syzbot report [1] in syzbot queue for a while. I was waiting for more occurrences and/or a repro but Dmitry Vyukov spotted the issue right away. qdisc_graft() drops reference to qdisc in notify_and_destroy while it's still assigned to dev->qdisc Indeed, RCU rules are clear when replacing a data structure. The visible pointer (dev->qdisc in this case) must be updated to the new object _before_ RCU grace period is started (qdisc_put(old) in this case). [1] BUG: KASAN: use-after-free in __tcf_qdisc_find.part.0+0xa3a/0xac0 net/sched/cls_api.c:1066 Read of size 4 at addr ffff88802065e038 by task syz-executor.4/21027 CPU: 0 PID: 21027 Comm: syz-executor.4 Not tainted 6.0.0-rc3-syzkaller-00363-g7726d4c3e60b #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/26/2022 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:317 [inline] print_report.cold+0x2ba/0x719 mm/kasan/report.c:433 kasan_report+0xb1/0x1e0 mm/kasan/report.c:495 __tcf_qdisc_find.part.0+0xa3a/0xac0 net/sched/cls_api.c:1066 __tcf_qdisc_find net/sched/cls_api.c:1051 [inline] tc_new_tfilter+0x34f/0x2200 net/sched/cls_api.c:2018 rtnetlink_rcv_msg+0x955/0xca0 net/core/rtnetlink.c:6081 netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2501 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] netlink_unicast+0x543/0x7f0 net/netlink/af_netlink.c:1345 netlink_sendmsg+0x917/0xe10 net/netlink/af_netlink.c:1921 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734 ____sys_sendmsg+0x6eb/0x810 net/socket.c:2482 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2536 __sys_sendmsg+0xf3/0x1c0 net/socket.c:2565 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f5efaa89279 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f5efbc31168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f5efab9bf80 RCX: 00007f5efaa89279 RDX: 0000000000000000 RSI: 0000000020000140 RDI: 0000000000000005 RBP: 00007f5efaae32e9 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f5efb0cfb1f R14: 00007f5efbc31300 R15: 0000000000022000 Allocated by task 21027: kasan_save_stack+0x1e/0x40 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 mm/kasan/common.c:475 [inline] __kasan_kmalloc+0xa9/0xd0 mm/kasan/common.c:525 kmalloc_node include/linux/slab.h:623 [inline] kzalloc_node include/linux/slab.h:744 [inline] qdisc_alloc+0xb0/0xc50 net/sched/sch_generic.c:938 qdisc_create_dflt+0x71/0x4a0 net/sched/sch_generic.c:997 attach_one_default_qdisc net/sched/sch_generic.c:1152 [inline] netdev_for_each_tx_queue include/linux/netdevice.h:2437 [inline] attach_default_qdiscs net/sched/sch_generic.c:1170 [inline] dev_activate+0x760/0xcd0 net/sched/sch_generic.c:1229 __dev_open+0x393/0x4d0 net/core/dev.c:1441 __dev_change_flags+0x583/0x750 net/core/dev.c:8556 rtnl_configure_link+0xee/0x240 net/core/rtnetlink.c:3189 rtnl_newlink_create net/core/rtnetlink.c:3371 [inline] __rtnl_newlink+0x10b8/0x17e0 net/core/rtnetlink.c:3580 rtnl_newlink+0x64/0xa0 net/core/rtnetlink.c:3593 rtnetlink_rcv_msg+0x43a/0xca0 net/core/rtnetlink.c:6090 netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2501 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] netlink_unicast+0x543/0x7f0 net/netlink/af_netlink.c:1345 netlink_sendmsg+0x917/0xe10 net/netlink/af_netlink.c:1921 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734 ____sys_sendmsg+0x6eb/0x810 net/socket.c:2482 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2536 __sys_sendmsg+0xf3/0x1c0 net/socket.c:2565 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Freed by task 21020: kasan_save_stack+0x1e/0x40 mm/kasan/common.c:38 kasan_set_track+0x21/0x30 mm/kasan/common.c:45 kasan_set_free_info+0x20/0x30 mm/kasan/generic.c:370 ____kasan_slab_free mm/kasan/common.c:367 [inline] ____kasan_slab_free+0x166/0x1c0 mm/kasan/common.c:329 kasan_slab_free include/linux/kasan.h:200 [inline] slab_free_hook mm/slub.c:1754 [inline] slab_free_freelist_hook+0x8b/0x1c0 mm/slub.c:1780 slab_free mm/slub.c:3534 [inline] kfree+0xe2/0x580 mm/slub.c:4562 rcu_do_batch kernel/rcu/tree.c:2245 [inline] rcu_core+0x7b5/0x1890 kernel/rcu/tree.c:2505 __do_softirq+0x1d3/0x9c6 kernel/softirq.c:571 Last potentially related work creation: kasan_save_stack+0x1e/0x40 mm/kasan/common.c:38 __kasan_record_aux_stack+0xbe/0xd0 mm/kasan/generic.c:348 call_rcu+0x99/0x790 kernel/rcu/tree.c:2793 qdisc_put+0xcd/0xe0 net/sched/sch_generic.c:1083 notify_and_destroy net/sched/sch_api.c:1012 [inline] qdisc_graft+0xeb1/0x1270 net/sched/sch_api.c:1084 tc_modify_qdisc+0xbb7/0x1a00 net/sched/sch_api.c:1671 rtnetlink_rcv_msg+0x43a/0xca0 net/core/rtnetlink.c:6090 netlink_rcv_skb+0x153/0x420 net/netlink/af_netlink.c:2501 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] netlink_unicast+0x543/0x7f0 net/netlink/af_netlink.c:1345 netlink_sendmsg+0x917/0xe10 net/netlink/af_netlink.c:1921 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734 ____sys_sendmsg+0x6eb/0x810 net/socket.c:2482 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2536 __sys_sendmsg+0xf3/0x1c0 net/socket.c:2565 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Second to last potentially related work creation: kasan_save_stack+0x1e/0x40 mm/kasan/common.c:38 __kasan_record_aux_stack+0xbe/0xd0 mm/kasan/generic.c:348 kvfree_call_rcu+0x74/0x940 kernel/rcu/tree.c:3322 neigh_destroy+0x431/0x630 net/core/neighbour.c:912 neigh_release include/net/neighbour.h:454 [inline] neigh_cleanup_and_release+0x1f8/0x330 net/core/neighbour.c:103 neigh_del net/core/neighbour.c:225 [inline] neigh_remove_one+0x37d/0x460 net/core/neighbour.c:246 neigh_forced_gc net/core/neighbour.c:276 [inline] neigh_alloc net/core/neighbour.c:447 [inline] ___neigh_create+0x18b5/0x29a0 net/core/neighbour.c:642 ip6_finish_output2+0xfb8/0x1520 net/ipv6/ip6_output.c:125 __ip6_finish_output net/ipv6/ip6_output.c:195 [inline] ip6_finish_output+0x690/0x1160 net/ipv6/ip6_output.c:206 NF_HOOK_COND include/linux/netfilter.h:296 [inline] ip6_output+0x1ed/0x540 net/ipv6/ip6_output.c:227 dst_output include/net/dst.h:451 [inline] NF_HOOK include/linux/netfilter.h:307 [inline] NF_HOOK include/linux/netfilter.h:301 [inline] mld_sendpack+0xa09/0xe70 net/ipv6/mcast.c:1820 mld_send_cr net/ipv6/mcast.c:2121 [inline] mld_ifc_work+0x71c/0xdc0 net/ipv6/mcast.c:2653 process_one_work+0x991/0x1610 kernel/workqueue.c:2289 worker_thread+0x665/0x1080 kernel/workqueue.c:2436 kthread+0x2e4/0x3a0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306 The buggy address belongs to the object at ffff88802065e000 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 56 bytes inside of 1024-byte region [ffff88802065e000, ffff88802065e400) The buggy address belongs to the physical page: page:ffffea0000819600 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x20658 head:ffffea0000819600 order:3 compound_mapcount:0 compound_pincount:0 flags: 0xfff00000010200(slab|head|node=0|zone=1|lastcpupid=0x7ff) raw: 00fff00000010200 0000000000000000 dead000000000001 ffff888011841dc0 raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 3523, tgid 3523 (sshd), ts 41495190986, free_ts 41417713212 prep_new_page mm/page_alloc.c:2532 [inline] get_page_from_freelist+0x109b/0x2ce0 mm/page_alloc.c:4283 __alloc_pages+0x1c7/0x510 mm/page_alloc.c:5515 alloc_pages+0x1a6/0x270 mm/mempolicy.c:2270 alloc_slab_page mm/slub.c:1824 [inline] allocate_slab+0x27e/0x3d0 mm/slub.c:1969 new_slab mm/slub.c:2029 [inline] ___slab_alloc+0x7f1/0xe10 mm/slub.c:3031 __slab_alloc.constprop.0+0x4d/0xa0 mm/slub.c:3118 slab_alloc_node mm/slub.c:3209 [inline] __kmalloc_node_track_caller+0x2f2/0x380 mm/slub.c:4955 kmalloc_reserve net/core/skbuff.c:358 [inline] __alloc_skb+0xd9/0x2f0 net/core/skbuff.c:430 alloc_skb_fclone include/linux/skbuff.h:1307 [inline] tcp_stream_alloc_skb+0x38/0x580 net/ipv4/tcp.c:861 tcp_sendmsg_locked+0xc36/0x2f80 net/ipv4/tcp.c:1325 tcp_sendmsg+0x2b/0x40 net/ipv4/tcp.c:1483 inet_sendmsg+0x99/0xe0 net/ipv4/af_inet.c:819 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734 sock_write_iter+0x291/0x3d0 net/socket.c:1108 call_write_iter include/linux/fs.h:2187 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x9e9/0xdd0 fs/read_write.c:578 ksys_write+0x1e8/0x250 fs/read_write.c:631 page last free stack trace: reset_page_owner include/linux/page_owner.h:24 [inline] free_pages_prepare mm/page_alloc.c:1449 [inline] free_pcp_prepare+0x5e4/0xd20 mm/page_alloc.c:1499 free_unref_page_prepare mm/page_alloc.c:3380 [inline] free_unref_page+0x19/0x4d0 mm/page_alloc.c:3476 __unfreeze_partials+0x17c/0x1a0 mm/slub.c:2548 qlink_free mm/kasan/quarantine.c:168 [inline] qlist_free_all+0x6a/0x170 mm/kasan/quarantine.c:187 kasan_quarantine_reduce+0x180/0x200 mm/kasan/quarantine.c:294 __kasan_slab_alloc+0xa2/0xc0 mm/kasan/common.c:447 kasan_slab_alloc include/linux/kasan.h:224 [inline] slab_post_alloc_hook mm/slab.h:727 [inline] slab_alloc_node mm/slub.c:3243 [inline] slab_alloc mm/slub.c:3251 [inline] __kmem_cache_alloc_lru mm/slub.c:3258 [inline] kmem_cache_alloc+0x267/0x3b0 mm/slub.c:3268 kmem_cache_zalloc include/linux/slab.h:723 [inline] alloc_buffer_head+0x20/0x140 fs/buffer.c:2974 alloc_page_buffers+0x280/0x790 fs/buffer.c:829 create_empty_buffers+0x2c/0xee0 fs/buffer.c:1558 ext4_block_write_begin+0x1004/0x1530 fs/ext4/inode.c:1074 ext4_da_write_begin+0x422/0xae0 fs/ext4/inode.c:2996 generic_perform_write+0x246/0x560 mm/filemap.c:3738 ext4_buffered_write_iter+0x15b/0x460 fs/ext4/file.c:270 ext4_file_write_iter+0x44a/0x1660 fs/ext4/file.c:679 call_write_iter include/linux/fs.h:2187 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x9e9/0xdd0 fs/read_write.c:578 Fixes: af356afa010f ("net_sched: reintroduce dev->qdisc for use by sch_api") Reported-by: syzbot Diagnosed-by: Dmitry Vyukov Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/r/20221018203258.2793282-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_api.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 0fb387c9d706..5ab20c764aa5 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1081,12 +1081,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, skip: if (!ingress) { - notify_and_destroy(net, skb, n, classid, - rtnl_dereference(dev->qdisc), new); + old = rtnl_dereference(dev->qdisc); if (new && !new->ops->attach) qdisc_refcount_inc(new); rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc); + notify_and_destroy(net, skb, n, classid, old, new); + if (new && new->ops->attach) new->ops->attach(new); } else { From 209740fd132e48cd1ed31abd720d362f48074606 Mon Sep 17 00:00:00 2001 From: Felix Riemann Date: Tue, 18 Oct 2022 12:47:54 +0200 Subject: [PATCH 594/610] net: phy: dp83822: disable MDI crossover status change interrupt [ Upstream commit 7f378c03aa4952507521174fb0da7b24a9ad0be6 ] If the cable is disconnected the PHY seems to toggle between MDI and MDI-X modes. With the MDI crossover status interrupt active this causes roughly 10 interrupts per second. As the crossover status isn't checked by the driver, the interrupt can be disabled to reduce the interrupt load. Fixes: 87461f7a58ab ("net: phy: DP83822 initial driver submission") Signed-off-by: Felix Riemann Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20221018104755.30025-1-svc.sw.rte.linux@sma.de Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/phy/dp83822.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index a792dd6d2ec3..0b511abb5422 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -253,8 +253,7 @@ static int dp83822_config_intr(struct phy_device *phydev) DP83822_EEE_ERROR_CHANGE_INT_EN); if (!dp83822->fx_enabled) - misr_status |= DP83822_MDI_XOVER_INT_EN | - DP83822_ANEG_ERR_INT_EN | + misr_status |= DP83822_ANEG_ERR_INT_EN | DP83822_WOL_PKT_INT_EN; err = phy_write(phydev, MII_DP83822_MISR2, misr_status); From 5c95d0c9d0eb74c7668522feb989a527b1eb1d02 Mon Sep 17 00:00:00 2001 From: Charlotte Tan Date: Wed, 19 Oct 2022 08:44:46 +0800 Subject: [PATCH 595/610] iommu/vt-d: Allow NVS regions in arch_rmrr_sanity_check() [ Upstream commit 5566e68d829f5d87670d5984c1c2ccb4c518405f ] arch_rmrr_sanity_check() warns if the RMRR is not covered by an ACPI Reserved region, but it seems like it should accept an NVS region as well. The ACPI spec https://uefi.org/specs/ACPI/6.5/15_System_Address_Map_Interfaces.html uses similar wording for "Reserved" and "NVS" region types; for NVS regions it says "This range of addresses is in use or reserved by the system and must not be used by the operating system." There is an old comment on this mailing list that also suggests NVS regions should pass the arch_rmrr_sanity_check() test: The warnings come from arch_rmrr_sanity_check() since it checks whether the region is E820_TYPE_RESERVED. However, if the purpose of the check is to detect RMRR has regions that may be used by OS as free memory, isn't E820_TYPE_NVS safe, too? This patch overlaps with another proposed patch that would add the region type to the log since sometimes the bug reporter sees this log on the console but doesn't know to include the kernel log: https://lore.kernel.org/lkml/20220611204859.234975-3-atomlin@redhat.com/ Here's an example of the "Firmware Bug" apparent false positive (wrapped for line length): DMAR: [Firmware Bug]: No firmware reserved region can cover this RMRR [0x000000006f760000-0x000000006f762fff], contact BIOS vendor for fixes DMAR: [Firmware Bug]: Your BIOS is broken; bad RMRR [0x000000006f760000-0x000000006f762fff] This is the snippet from the e820 table: BIOS-e820: [mem 0x0000000068bff000-0x000000006ebfefff] reserved BIOS-e820: [mem 0x000000006ebff000-0x000000006f9fefff] ACPI NVS BIOS-e820: [mem 0x000000006f9ff000-0x000000006fffefff] ACPI data Fixes: f036c7fa0ab6 ("iommu/vt-d: Check VT-d RMRR region in BIOS is reported as reserved") Cc: Will Mortensen Link: https://lore.kernel.org/linux-iommu/64a5843d-850d-e58c-4fc2-0a0eeeb656dc@nec.com/ Link: https://bugzilla.kernel.org/show_bug.cgi?id=216443 Signed-off-by: Charlotte Tan Reviewed-by: Aaron Tomlin Link: https://lore.kernel.org/r/20220929044449.32515-1-charlotte@extrahop.com Signed-off-by: Lu Baolu Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- arch/x86/include/asm/iommu.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index bf1ed2ddc74b..7a983119bc40 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -17,8 +17,10 @@ arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr) { u64 start = rmrr->base_address; u64 end = rmrr->end_address + 1; + int entry_type; - if (e820__mapped_all(start, end, E820_TYPE_RESERVED)) + entry_type = e820__get_entry_type(start, end); + if (entry_type == E820_TYPE_RESERVED || entry_type == E820_TYPE_NVS) return 0; pr_err(FW_BUG "No firmware reserved region can cover this RMRR [%#018Lx-%#018Lx], contact BIOS vendor for fixes\n", From 0365d6af75f9f2696e94a0fef24a2c8464c037c8 Mon Sep 17 00:00:00 2001 From: Jerry Snitselaar Date: Wed, 19 Oct 2022 08:44:47 +0800 Subject: [PATCH 596/610] iommu/vt-d: Clean up si_domain in the init_dmars() error path [ Upstream commit 620bf9f981365c18cc2766c53d92bf8131c63f32 ] A splat from kmem_cache_destroy() was seen with a kernel prior to commit ee2653bbe89d ("iommu/vt-d: Remove domain and devinfo mempool") when there was a failure in init_dmars(), because the iommu_domain cache still had objects. While the mempool code is now gone, there still is a leak of the si_domain memory if init_dmars() fails. So clean up si_domain in the init_dmars() error path. Cc: Lu Baolu Cc: Joerg Roedel Cc: Will Deacon Cc: Robin Murphy Fixes: 86080ccc223a ("iommu/vt-d: Allocate si_domain in init_dmars()") Signed-off-by: Jerry Snitselaar Link: https://lore.kernel.org/r/20221010144842.308890-1-jsnitsel@redhat.com Signed-off-by: Lu Baolu Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/intel/iommu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 71a932017772..b0a975e0a8cb 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2761,6 +2761,7 @@ static int __init si_domain_init(int hw) if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { domain_exit(si_domain); + si_domain = NULL; return -EFAULT; } @@ -3397,6 +3398,10 @@ free_iommu: disable_dmar_iommu(iommu); free_dmar_iommu(iommu); } + if (si_domain) { + domain_exit(si_domain); + si_domain = NULL; + } kfree(g_iommus); From ea7be82fd7e1f5de72208bce93fbbe6de6c13dec Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 15 Aug 2022 15:43:19 -0400 Subject: [PATCH 597/610] fs: dlm: fix invalid derefence of sb_lvbptr [ Upstream commit 7175e131ebba47afef47e6ac4d5bab474d1e6e49 ] I experience issues when putting a lkbsb on the stack and have sb_lvbptr field to a dangled pointer while not using DLM_LKF_VALBLK. It will crash with the following kernel message, the dangled pointer is here 0xdeadbeef as example: [ 102.749317] BUG: unable to handle page fault for address: 00000000deadbeef [ 102.749320] #PF: supervisor read access in kernel mode [ 102.749323] #PF: error_code(0x0000) - not-present page [ 102.749325] PGD 0 P4D 0 [ 102.749332] Oops: 0000 [#1] PREEMPT SMP PTI [ 102.749336] CPU: 0 PID: 1567 Comm: lock_torture_wr Tainted: G W 5.19.0-rc3+ #1565 [ 102.749343] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-2.module+el8.7.0+15506+033991b0 04/01/2014 [ 102.749344] RIP: 0010:memcpy_erms+0x6/0x10 [ 102.749353] Code: cc cc cc cc eb 1e 0f 1f 00 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 a4 c3 0f 1f 80 00 00 00 00 48 89 f8 48 83 fa 20 72 7e 40 38 fe [ 102.749355] RSP: 0018:ffff97a58145fd08 EFLAGS: 00010202 [ 102.749358] RAX: ffff901778b77070 RBX: 0000000000000000 RCX: 0000000000000040 [ 102.749360] RDX: 0000000000000040 RSI: 00000000deadbeef RDI: ffff901778b77070 [ 102.749362] RBP: ffff97a58145fd10 R08: ffff901760b67a70 R09: 0000000000000001 [ 102.749364] R10: ffff9017008e2cb8 R11: 0000000000000001 R12: ffff901760b67a70 [ 102.749366] R13: ffff901760b78f00 R14: 0000000000000003 R15: 0000000000000001 [ 102.749368] FS: 0000000000000000(0000) GS:ffff901876e00000(0000) knlGS:0000000000000000 [ 102.749372] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 102.749374] CR2: 00000000deadbeef CR3: 000000017c49a004 CR4: 0000000000770ef0 [ 102.749376] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 102.749378] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 102.749379] PKRU: 55555554 [ 102.749381] Call Trace: [ 102.749382] [ 102.749383] ? send_args+0xb2/0xd0 [ 102.749389] send_common+0xb7/0xd0 [ 102.749395] _unlock_lock+0x2c/0x90 [ 102.749400] unlock_lock.isra.56+0x62/0xa0 [ 102.749405] dlm_unlock+0x21e/0x330 [ 102.749411] ? lock_torture_stats+0x80/0x80 [dlm_locktorture] [ 102.749416] torture_unlock+0x5a/0x90 [dlm_locktorture] [ 102.749419] ? preempt_count_sub+0xba/0x100 [ 102.749427] lock_torture_writer+0xbd/0x150 [dlm_locktorture] [ 102.786186] kthread+0x10a/0x130 [ 102.786581] ? kthread_complete_and_exit+0x20/0x20 [ 102.787156] ret_from_fork+0x22/0x30 [ 102.787588] [ 102.787855] Modules linked in: dlm_locktorture torture rpcsec_gss_krb5 intel_rapl_msr intel_rapl_common kvm_intel iTCO_wdt iTCO_vendor_support kvm vmw_vsock_virtio_transport qxl irqbypass vmw_vsock_virtio_transport_common drm_ttm_helper crc32_pclmul joydev crc32c_intel ttm vsock virtio_scsi virtio_balloon snd_pcm drm_kms_helper virtio_console snd_timer snd drm soundcore syscopyarea i2c_i801 sysfillrect sysimgblt i2c_smbus pcspkr fb_sys_fops lpc_ich serio_raw [ 102.792536] CR2: 00000000deadbeef [ 102.792930] ---[ end trace 0000000000000000 ]--- This patch fixes the issue by checking also on DLM_LKF_VALBLK on exflags is set when copying the lvbptr array instead of if it's just null which fixes for me the issue. I think this patch can fix other dlm users as well, depending how they handle the init, freeing memory handling of sb_lvbptr and don't set DLM_LKF_VALBLK for some dlm_lock() calls. It might a there could be a hidden issue all the time. However with checking on DLM_LKF_VALBLK the user always need to provide a sb_lvbptr non-null value. There might be more intelligent handling between per ls lvblen, DLM_LKF_VALBLK and non-null to report the user the way how DLM API is used is wrong but can be added for later, this will only fix the current behaviour. Cc: stable@vger.kernel.org Signed-off-by: Alexander Aring Signed-off-by: David Teigland Signed-off-by: Sasha Levin --- fs/dlm/lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index bcc7127c4c0a..862cb7a353c1 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -3632,7 +3632,7 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb, case DLM_MSG_REQUEST_REPLY: case DLM_MSG_CONVERT_REPLY: case DLM_MSG_GRANT: - if (!lkb->lkb_lvbptr) + if (!lkb->lkb_lvbptr || !(lkb->lkb_exflags & DLM_LKF_VALBLK)) break; memcpy(ms->m_extra, lkb->lkb_lvbptr, r->res_ls->ls_lvblen); break; From 8754fa5dbc6ef47ca81c2493a157a4dcfe2d6069 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 15 Sep 2022 15:20:53 -0700 Subject: [PATCH 598/610] arm64: mte: move register initialization to C [ Upstream commit 973b9e37330656dec719ede508e4dc40e5c2d80c ] If FEAT_MTE2 is disabled via the arm64.nomte command line argument on a CPU that claims to support FEAT_MTE2, the kernel will use Tagged Normal in the MAIR. If we interpret arm64.nomte to mean that the CPU does not in fact implement FEAT_MTE2, setting the system register like this may lead to UNSPECIFIED behavior. Fix it by arranging for MAIR to be set in the C function cpu_enable_mte which is called based on the sanitized version of the system register. There is no need for the rest of the MTE-related system register initialization to happen from assembly, with the exception of TCR_EL1, which must be set to include at least TBI1 because the secondary CPUs access KASan-allocated data structures early. Therefore, make the TCR_EL1 initialization unconditional and move the rest of the initialization to cpu_enable_mte so that we no longer have a dependency on the unsanitized ID register value. Co-developed-by: Evgenii Stepanov Signed-off-by: Peter Collingbourne Signed-off-by: Evgenii Stepanov Suggested-by: Catalin Marinas Reported-by: kernel test robot Fixes: 3b714d24ef17 ("arm64: mte: CPU feature detection and initial sysreg configuration") Cc: # 5.10.x Link: https://lore.kernel.org/r/20220915222053.3484231-1-eugenis@google.com Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/include/asm/mte.h | 5 ++++ arch/arm64/kernel/cpufeature.c | 3 +- arch/arm64/kernel/mte.c | 51 ++++++++++++++++++++++++++++++++++ arch/arm64/kernel/suspend.c | 2 ++ arch/arm64/mm/proc.S | 46 ++++-------------------------- 5 files changed, 65 insertions(+), 42 deletions(-) diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h index 02511650cffe..3e368ca66623 100644 --- a/arch/arm64/include/asm/mte.h +++ b/arch/arm64/include/asm/mte.h @@ -40,7 +40,9 @@ void mte_sync_tags(pte_t old_pte, pte_t pte); void mte_copy_page_tags(void *kto, const void *kfrom); void mte_thread_init_user(void); void mte_thread_switch(struct task_struct *next); +void mte_cpu_setup(void); void mte_suspend_enter(void); +void mte_suspend_exit(void); long set_mte_ctrl(struct task_struct *task, unsigned long arg); long get_mte_ctrl(struct task_struct *task); int mte_ptrace_copy_tags(struct task_struct *child, long request, @@ -69,6 +71,9 @@ static inline void mte_thread_switch(struct task_struct *next) static inline void mte_suspend_enter(void) { } +static inline void mte_suspend_exit(void) +{ +} static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg) { return 0; diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 13e3cb1acbdf..d4ee345ff429 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1903,7 +1903,8 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) { sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0); - isb(); + + mte_cpu_setup(); /* * Clear the tags in the zero page. This needs to be done via the diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 7c1c82c8115c..dacca0684ea3 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -213,6 +213,49 @@ void mte_thread_switch(struct task_struct *next) mte_check_tfsr_el1(); } +void mte_cpu_setup(void) +{ + u64 rgsr; + + /* + * CnP must be enabled only after the MAIR_EL1 register has been set + * up. Inconsistent MAIR_EL1 between CPUs sharing the same TLB may + * lead to the wrong memory type being used for a brief window during + * CPU power-up. + * + * CnP is not a boot feature so MTE gets enabled before CnP, but let's + * make sure that is the case. + */ + BUG_ON(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT); + BUG_ON(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT); + + /* Normal Tagged memory type at the corresponding MAIR index */ + sysreg_clear_set(mair_el1, + MAIR_ATTRIDX(MAIR_ATTR_MASK, MT_NORMAL_TAGGED), + MAIR_ATTRIDX(MAIR_ATTR_NORMAL_TAGGED, + MT_NORMAL_TAGGED)); + + write_sysreg_s(KERNEL_GCR_EL1, SYS_GCR_EL1); + + /* + * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then + * RGSR_EL1.SEED must be non-zero for IRG to produce + * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we + * must initialize it. + */ + rgsr = (read_sysreg(CNTVCT_EL0) & SYS_RGSR_EL1_SEED_MASK) << + SYS_RGSR_EL1_SEED_SHIFT; + if (rgsr == 0) + rgsr = 1 << SYS_RGSR_EL1_SEED_SHIFT; + write_sysreg_s(rgsr, SYS_RGSR_EL1); + + /* clear any pending tag check faults in TFSR*_EL1 */ + write_sysreg_s(0, SYS_TFSR_EL1); + write_sysreg_s(0, SYS_TFSRE0_EL1); + + local_flush_tlb_all(); +} + void mte_suspend_enter(void) { if (!system_supports_mte()) @@ -229,6 +272,14 @@ void mte_suspend_enter(void) mte_check_tfsr_el1(); } +void mte_suspend_exit(void) +{ + if (!system_supports_mte()) + return; + + mte_cpu_setup(); +} + long set_mte_ctrl(struct task_struct *task, unsigned long arg) { u64 mte_ctrl = (~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) & diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 19ee7c33769d..d473ec204fef 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -43,6 +43,8 @@ void notrace __cpu_suspend_exit(void) { unsigned int cpu = smp_processor_id(); + mte_suspend_exit(); + /* * We are resuming from reset with the idmap active in TTBR0_EL1. * We must uninstall the idmap and restore the expected MMU diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 50bbed947bec..1a9684b11474 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -47,17 +47,19 @@ #ifdef CONFIG_KASAN_HW_TAGS #define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1 -#else +#elif defined(CONFIG_ARM64_MTE) /* * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on * TBI being enabled at EL1. */ #define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1 +#else +#define TCR_MTE_FLAGS 0 #endif /* * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and - * changed during __cpu_setup to Normal Tagged if the system supports MTE. + * changed during mte_cpu_setup to Normal Tagged if the system supports MTE. */ #define MAIR_EL1_SET \ (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) | \ @@ -421,46 +423,8 @@ SYM_FUNC_START(__cpu_setup) mov_q mair, MAIR_EL1_SET mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ - TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS + TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS -#ifdef CONFIG_ARM64_MTE - /* - * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported - * (ID_AA64PFR1_EL1[11:8] > 1). - */ - mrs x10, ID_AA64PFR1_EL1 - ubfx x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4 - cmp x10, #ID_AA64PFR1_MTE - b.lt 1f - - /* Normal Tagged memory type at the corresponding MAIR index */ - mov x10, #MAIR_ATTR_NORMAL_TAGGED - bfi mair, x10, #(8 * MT_NORMAL_TAGGED), #8 - - mov x10, #KERNEL_GCR_EL1 - msr_s SYS_GCR_EL1, x10 - - /* - * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then - * RGSR_EL1.SEED must be non-zero for IRG to produce - * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we - * must initialize it. - */ - mrs x10, CNTVCT_EL0 - ands x10, x10, #SYS_RGSR_EL1_SEED_MASK - csinc x10, x10, xzr, ne - lsl x10, x10, #SYS_RGSR_EL1_SEED_SHIFT - msr_s SYS_RGSR_EL1, x10 - - /* clear any pending tag check faults in TFSR*_EL1 */ - msr_s SYS_TFSR_EL1, xzr - msr_s SYS_TFSRE0_EL1, xzr - - /* set the TCR_EL1 bits */ - mov_q x10, TCR_MTE_FLAGS - orr tcr, tcr, x10 -1: -#endif tcr_clear_errata_bits tcr, x9, x5 #ifdef CONFIG_ARM64_VA_BITS_52 From 3c8cfcaa2d9a2424005261bbcb5283831c38a05a Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Mon, 16 May 2022 16:22:09 +0900 Subject: [PATCH 599/610] ksmbd: handle smb2 query dir request for OutputBufferLength that is too small [ Upstream commit 65ca7a3ffff811d6c0d4342d467c381257d566d4 ] We found the issue that ksmbd return STATUS_NO_MORE_FILES response even though there are still dentries that needs to be read while file read/write test using framtest utils. windows client send smb2 query dir request included OutputBufferLength(128) that is too small to contain even one entry. This patch make ksmbd immediately returns OutputBufferLength of response as zero to client. Signed-off-by: Namjae Jeon Reviewed-by: Hyunchul Lee Signed-off-by: Steve French Stable-dep-of: 88541cb414b7 ("ksmbd: fix incorrect handling of iterate_dir") Signed-off-by: Sasha Levin --- fs/ksmbd/smb2pdu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index bec9a84572c0..ef0aef78eba6 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -3962,6 +3962,12 @@ int smb2_query_dir(struct ksmbd_work *work) set_ctx_actor(&dir_fp->readdir_data.ctx, __query_dir); rc = iterate_dir(dir_fp->filp, &dir_fp->readdir_data.ctx); + /* + * req->OutputBufferLength is too small to contain even one entry. + * In this case, it immediately returns OutputBufferLength 0 to client. + */ + if (!d_info.out_buf_len && !d_info.num_entry) + goto no_buf_len; if (rc == 0) restart_ctx(&dir_fp->readdir_data.ctx); if (rc == -ENOSPC) @@ -3988,10 +3994,12 @@ int smb2_query_dir(struct ksmbd_work *work) rsp->Buffer[0] = 0; inc_rfc1001_len(rsp_org, 9); } else { +no_buf_len: ((struct file_directory_info *) ((char *)rsp->Buffer + d_info.last_entry_offset)) ->NextEntryOffset = 0; - d_info.data_count -= d_info.last_entry_off_align; + if (d_info.data_count >= d_info.last_entry_off_align) + d_info.data_count -= d_info.last_entry_off_align; rsp->StructureSize = cpu_to_le16(9); rsp->OutputBufferOffset = cpu_to_le16(72); From 20bc6d23f7f67c1122349080e00f490024d8f37a Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Fri, 9 Sep 2022 17:43:53 +0900 Subject: [PATCH 600/610] ksmbd: fix incorrect handling of iterate_dir [ Upstream commit 88541cb414b7a2450c45fc9c131b37b5753b7679 ] if iterate_dir() returns non-negative value, caller has to treat it as normal and check there is any error while populating dentry information. ksmbd doesn't have to do anything because ksmbd already checks too small OutputBufferLength to store one file information. And because ctx->pos is set to file->f_pos when iterative_dir is called, remove restart_ctx(). And if iterate_dir() return -EIO, which mean directory entry is corrupted, return STATUS_FILE_CORRUPT_ERROR error response. This patch fixes some failure of SMB2_QUERY_DIRECTORY, which happens when ntfs3 is local filesystem. Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org Signed-off-by: Hyunchul Lee Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/ksmbd/smb2pdu.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index ef0aef78eba6..65c85ca71ebe 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -3803,11 +3803,6 @@ static int __query_dir(struct dir_context *ctx, const char *name, int namlen, return 0; } -static void restart_ctx(struct dir_context *ctx) -{ - ctx->pos = 0; -} - static int verify_info_level(int info_level) { switch (info_level) { @@ -3921,7 +3916,6 @@ int smb2_query_dir(struct ksmbd_work *work) if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) { ksmbd_debug(SMB, "Restart directory scan\n"); generic_file_llseek(dir_fp->filp, 0, SEEK_SET); - restart_ctx(&dir_fp->readdir_data.ctx); } memset(&d_info, 0, sizeof(struct ksmbd_dir_info)); @@ -3968,11 +3962,9 @@ int smb2_query_dir(struct ksmbd_work *work) */ if (!d_info.out_buf_len && !d_info.num_entry) goto no_buf_len; - if (rc == 0) - restart_ctx(&dir_fp->readdir_data.ctx); - if (rc == -ENOSPC) + if (rc > 0 || rc == -ENOSPC) rc = 0; - if (rc) + else if (rc) goto err_out; d_info.wptr = d_info.rptr; @@ -4029,6 +4021,8 @@ err_out2: rsp->hdr.Status = STATUS_NO_MEMORY; else if (rc == -EFAULT) rsp->hdr.Status = STATUS_INVALID_INFO_CLASS; + else if (rc == -EIO) + rsp->hdr.Status = STATUS_FILE_CORRUPT_ERROR; if (!rsp->hdr.Status) rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR; From 57252e7bd491bdbf4aa7d1c2c1e9d1dc500b0e8a Mon Sep 17 00:00:00 2001 From: sunliming Date: Thu, 2 Jun 2022 22:06:13 +0800 Subject: [PATCH 601/610] tracing: Simplify conditional compilation code in tracing_set_tracer() [ Upstream commit f4b0d318097e45cbac5e14976f8bb56aa2cef504 ] Two conditional compilation directives "#ifdef CONFIG_TRACER_MAX_TRACE" are used consecutively, and no other code in between. Simplify conditional the compilation code and only use one "#ifdef CONFIG_TRACER_MAX_TRACE". Link: https://lkml.kernel.org/r/20220602140613.545069-1-sunliming@kylinos.cn Signed-off-by: sunliming Signed-off-by: Steven Rostedt (Google) Stable-dep-of: a541a9559bb0 ("tracing: Do not free snapshot if tracer is on cmdline") Signed-off-by: Sasha Levin --- kernel/trace/trace.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0dc17fd96102..21795777587b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6416,9 +6416,7 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) synchronize_rcu(); free_snapshot(tr); } -#endif -#ifdef CONFIG_TRACER_MAX_TRACE if (t->use_max_tr && !had_max_tr) { ret = tracing_alloc_snapshot_instance(tr); if (ret < 0) From 7aeda81191fdd59e3e0375670ccc2c6856ba8b92 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Wed, 5 Oct 2022 11:37:57 -0400 Subject: [PATCH 602/610] tracing: Do not free snapshot if tracer is on cmdline [ Upstream commit a541a9559bb0a8ecc434de01d3e4826c32e8bb53 ] The ftrace_boot_snapshot and alloc_snapshot cmdline options allocate the snapshot buffer at boot up for use later. The ftrace_boot_snapshot in particular requires the snapshot to be allocated because it will take a snapshot at the end of boot up allowing to see the traces that happened during boot so that it's not lost when user space takes over. When a tracer is registered (started) there's a path that checks if it requires the snapshot buffer or not, and if it does not and it was allocated it will do a synchronization and free the snapshot buffer. This is only required if the previous tracer was using it for "max latency" snapshots, as it needs to make sure all max snapshots are complete before freeing. But this is only needed if the previous tracer was using the snapshot buffer for latency (like irqoff tracer and friends). But it does not make sense to free it, if the previous tracer was not using it, and the snapshot was allocated by the cmdline parameters. This basically takes away the point of allocating it in the first place! Note, the allocated snapshot worked fine for just trace events, but fails when a tracer is enabled on the cmdline. Further investigation, this goes back even further and it does not require a tracer on the cmdline to fail. Simply enable snapshots and then enable a tracer, and it will remove the snapshot. Link: https://lkml.kernel.org/r/20221005113757.041df7fe@gandalf.local.home Cc: Masami Hiramatsu Cc: Andrew Morton Cc: stable@vger.kernel.org Fixes: 45ad21ca5530 ("tracing: Have trace_array keep track if snapshot buffer is allocated") Reported-by: Ross Zwisler Tested-by: Ross Zwisler Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin --- kernel/trace/trace.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 21795777587b..24a5ea9a2cc0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6399,12 +6399,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) if (tr->current_trace->reset) tr->current_trace->reset(tr); +#ifdef CONFIG_TRACER_MAX_TRACE + had_max_tr = tr->current_trace->use_max_tr; + /* Current trace needs to be nop_trace before synchronize_rcu */ tr->current_trace = &nop_trace; -#ifdef CONFIG_TRACER_MAX_TRACE - had_max_tr = tr->allocated_snapshot; - if (had_max_tr && !t->use_max_tr) { /* * We need to make sure that the update_max_tr sees that @@ -6417,11 +6417,13 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) free_snapshot(tr); } - if (t->use_max_tr && !had_max_tr) { + if (t->use_max_tr && !tr->allocated_snapshot) { ret = tracing_alloc_snapshot_instance(tr); if (ret < 0) goto out; } +#else + tr->current_trace = &nop_trace; #endif if (t->init) { From 9d912a3853684aae9605d1602fbc8102f4f1176b Mon Sep 17 00:00:00 2001 From: Prathamesh Shete Date: Thu, 6 Oct 2022 18:36:22 +0530 Subject: [PATCH 603/610] mmc: sdhci-tegra: Use actual clock rate for SW tuning correction [ Upstream commit b78870e7f41534cc719c295d1f8809aca93aeeab ] Ensure tegra_host member "curr_clk_rate" holds the actual clock rate instead of requested clock rate for proper use during tuning correction algorithm. Actual clk rate may not be the same as the requested clk frequency depending on the parent clock source set. Tuning correction algorithm depends on certain parameters which are sensitive to current clk rate. If the host clk is selected instead of the actual clock rate, tuning correction algorithm may end up applying invalid correction, which could result in errors Fixes: ea8fc5953e8b ("mmc: tegra: update hw tuning process") Signed-off-by: Aniruddha TVS Rao Signed-off-by: Prathamesh Shete Acked-by: Adrian Hunter Acked-by: Thierry Reding Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20221006130622.22900-4-pshete@nvidia.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 9762ffab2e23..829a8bf7c77d 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -762,7 +762,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) */ host_clk = tegra_host->ddr_signaling ? clock * 2 : clock; clk_set_rate(pltfm_host->clk, host_clk); - tegra_host->curr_clk_rate = host_clk; + tegra_host->curr_clk_rate = clk_get_rate(pltfm_host->clk); if (tegra_host->ddr_signaling) host->max_clk = host_clk; else From 289b56715ba66e75dbab0b46efc5a3abbf21a4ce Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 4 Oct 2022 14:12:35 -0500 Subject: [PATCH 604/610] perf: Skip and warn on unknown format 'configN' attrs [ Upstream commit e552b7be12ed62357df84392efa525ecb01910fb ] If the kernel exposes a new perf_event_attr field in a format attr, perf will return an error stating the specified PMU can't be found. For example, a format attr with 'config3:0-63' causes an error as config3 is unknown to perf. This causes a compatibility issue between a newer kernel with older perf tool. Before this change with a kernel adding 'config3' I get: $ perf record -e arm_spe// -- true event syntax error: 'arm_spe//' \___ Cannot find PMU `arm_spe'. Missing kernel support? Run 'perf list' for a list of valid events Usage: perf record [] [] or: perf record [] -- [] -e, --event event selector. use 'perf list' to list available events After this change, I get: $ perf record -e arm_spe// -- true WARNING: 'arm_spe_0' format 'inv_event_filter' requires 'perf_event_attr::config3' which is not supported by this version of perf! [ perf record: Woken up 2 times to write data ] [ perf record: Captured and wrote 0.091 MB perf.data ] To support unknown configN formats, rework the YACC implementation to pass any config[0-9]+ format to perf_pmu__new_format() to handle with a warning. Reviewed-by: Namhyung Kim Signed-off-by: Rob Herring Tested-by: Leo Yan Cc: Alexander Shishkin Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220914-arm-perf-tool-spe1-2-v2-v4-1-83c098e6212e@kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/parse-events.c | 3 +++ tools/perf/util/pmu.c | 17 +++++++++++++++++ tools/perf/util/pmu.h | 2 ++ tools/perf/util/pmu.l | 2 -- tools/perf/util/pmu.y | 15 ++++----------- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b93a36ffeb9e..7e4939640196 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -373,6 +373,9 @@ __add_event(struct list_head *list, int *idx, struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) : cpu_list ? perf_cpu_map__new(cpu_list) : NULL; + if (pmu) + perf_pmu__warn_invalid_formats(pmu); + if (pmu && attr->type == PERF_TYPE_RAW) perf_pmu__warn_invalid_config(pmu, attr->config, name); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index bdabd62170d2..26c0b88cef4c 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1048,6 +1048,23 @@ err: return NULL; } +void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu) +{ + struct perf_pmu_format *format; + + /* fake pmu doesn't have format list */ + if (pmu == &perf_pmu__fake) + return; + + list_for_each_entry(format, &pmu->format, list) + if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END) { + pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config%d'" + "which is not supported by this version of perf!\n", + pmu->name, format->name, format->value); + return; + } +} + static struct perf_pmu *pmu_find(const char *name) { struct perf_pmu *pmu; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 394898b07fd9..822d914b07cc 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -17,6 +17,7 @@ enum { PERF_PMU_FORMAT_VALUE_CONFIG, PERF_PMU_FORMAT_VALUE_CONFIG1, PERF_PMU_FORMAT_VALUE_CONFIG2, + PERF_PMU_FORMAT_VALUE_CONFIG_END, }; #define PERF_PMU_FORMAT_BITS 64 @@ -135,6 +136,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu); void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, char *name); +void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu); bool perf_pmu__has_hybrid(void); int perf_pmu__match(char *pattern, char *name, char *tok); diff --git a/tools/perf/util/pmu.l b/tools/perf/util/pmu.l index a15d9fbd7c0e..58b4926cfaca 100644 --- a/tools/perf/util/pmu.l +++ b/tools/perf/util/pmu.l @@ -27,8 +27,6 @@ num_dec [0-9]+ {num_dec} { return value(10); } config { return PP_CONFIG; } -config1 { return PP_CONFIG1; } -config2 { return PP_CONFIG2; } - { return '-'; } : { return ':'; } , { return ','; } diff --git a/tools/perf/util/pmu.y b/tools/perf/util/pmu.y index bfd7e8509869..283efe059819 100644 --- a/tools/perf/util/pmu.y +++ b/tools/perf/util/pmu.y @@ -20,7 +20,7 @@ do { \ %} -%token PP_CONFIG PP_CONFIG1 PP_CONFIG2 +%token PP_CONFIG %token PP_VALUE PP_ERROR %type PP_VALUE %type bit_term @@ -47,18 +47,11 @@ PP_CONFIG ':' bits $3)); } | -PP_CONFIG1 ':' bits +PP_CONFIG PP_VALUE ':' bits { ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG1, - $3)); -} -| -PP_CONFIG2 ':' bits -{ - ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG2, - $3)); + $2, + $4)); } bits: From 0983205085faca1f39df64d7c416fcf95e763baa Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Wed, 26 Oct 2022 17:22:46 +0200 Subject: [PATCH 605/610] ACPI: video: Force backlight native for more TongFang devices commit 3dbc80a3e4c55c4a5b89ef207bed7b7de36157b4 upstream. This commit is very different from the upstream commit! It fixes the same issue by adding more quirks, rather then the general fix from the 6.1 kernel, because the general fix from the 6.1 kernel is part of a larger refactoring of the backlight code which is not suitable for the stable series. As described in "ACPI: video: Drop NL5x?U, PF4NU1F and PF5?U?? acpi_backlight=native quirks" (10212754a0d2) the upstream commit "ACPI: video: Make backlight class device registration a separate step (v2)" (3dbc80a3e4c5) makes these quirks unnecessary. However as mentioned in this bugtracker ticket https://bugzilla.kernel.org/show_bug.cgi?id=215683#c17 the upstream fix is part of a larger patchset that is overall too complex for stable. The TongFang GKxNRxx, GMxNGxx, GMxZGxx, and GMxRGxx / TUXEDO Stellaris/Polaris Gen 1-4, have the same problem as the Clevo NL5xRU and NL5xNU / TUXEDO Aura 15 Gen1 and Gen2: They have a working native and video interface for screen backlight. However the default detection mechanism first registers the video interface before unregistering it again and switching to the native interface during boot. This results in a dangling SBIOS request for backlight change for some reason, causing the backlight to switch to ~2% once per boot on the first power cord connect or disconnect event. Setting the native interface explicitly circumvents this buggy behaviour by avoiding the unregistering process. Reviewed-by: Hans de Goede Signed-off-by: Werner Sembach Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/video_detect.c | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index e39d59ad6496..b13713199ad9 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -500,6 +500,70 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"), }, }, + /* + * More Tongfang devices with the same issue as the Clevo NL5xRU and + * NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description above. + */ + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GKxNRxx"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GMxNGxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxNGxx"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GMxZGxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxZGxx"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GMxRGxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"), + }, + }, /* * Desktops which falsely report a backlight and which our heuristics * for this do not catch. From 117825e9bbb113e0321ac470b5fe17629e785686 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 29 Sep 2022 08:20:10 -0700 Subject: [PATCH 606/610] x86/Kconfig: Drop check for -mabi=ms for CONFIG_EFI_STUB commit 33806e7cb8d50379f55c3e8f335e91e1b359dc7b upstream. A recent change in LLVM made CONFIG_EFI_STUB unselectable because it no longer pretends to support -mabi=ms, breaking the dependency in Kconfig. Lack of CONFIG_EFI_STUB can prevent kernels from booting via EFI in certain circumstances. This check was added by 8f24f8c2fc82 ("efi/libstub: Annotate firmware routines as __efiapi") to ensure that __attribute__((ms_abi)) was available, as -mabi=ms is not actually used in any cflags. According to the GCC documentation, this attribute has been supported since GCC 4.4.7. The kernel currently requires GCC 5.1 so this check is not necessary; even when that change landed in 5.6, the kernel required GCC 4.9 so it was unnecessary then as well. Clang supports __attribute__((ms_abi)) for all versions that are supported for building the kernel so no additional check is needed. Remove the 'depends on' line altogether to allow CONFIG_EFI_STUB to be selected when CONFIG_EFI is enabled, regardless of compiler. Fixes: 8f24f8c2fc82 ("efi/libstub: Annotate firmware routines as __efiapi") Signed-off-by: Nathan Chancellor Signed-off-by: Borislav Petkov Reviewed-by: Nick Desaulniers Acked-by: Ard Biesheuvel Cc: stable@vger.kernel.org Link: https://github.com/llvm/llvm-project/commit/d1ad006a8f64bdc17f618deffa9e7c91d82c444d [nathan: Fix conflict due to lack of c6dbd3e5e69c in older trees] Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 57f5e881791a..0f2234cd8453 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1926,7 +1926,6 @@ config EFI config EFI_STUB bool "EFI stub support" depends on EFI && !X86_USE_3DNOW - depends on $(cc-option,-mabi=ms) || X86_32 select RELOCATABLE help This kernel feature allows a bzImage to be loaded directly From 0ee2f0567a56298e442464efd84d1f649068106e Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 24 Oct 2022 13:34:14 -0700 Subject: [PATCH 607/610] Makefile.debug: re-enable debug info for .S files This is _not_ an upstream commit and just for 5.15.y only. It is based on commit 32ef9e5054ec0321b9336058c58ec749e9c6b0fe upstream. Alexey reported that the fraction of unknown filename instances in kallsyms grew from ~0.3% to ~10% recently; Bill and Greg tracked it down to assembler defined symbols, which regressed as a result of: commit b8a9092330da ("Kbuild: do not emit debug info for assembly with LLVM_IAS=1") In that commit, I allude to restoring debug info for assembler defined symbols in a follow up patch, but it seems I forgot to do so in commit a66049e2cf0e ("Kbuild: make DWARF version a choice") Fixes: b8a9092330da ("Kbuild: do not emit debug info for assembly with LLVM_IAS=1") Signed-off-by: Nick Desaulniers Signed-off-by: Greg Kroah-Hartman --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e3d63d529e0d..6cbd4890cfa2 100644 --- a/Makefile +++ b/Makefile @@ -870,7 +870,9 @@ else DEBUG_CFLAGS += -g endif -ifndef CONFIG_AS_IS_LLVM +ifdef CONFIG_AS_IS_LLVM +KBUILD_AFLAGS += -g +else KBUILD_AFLAGS += -Wa,-gdwarf-2 endif From b9d8cbe90a0f27f2ec4f6f32e7faf86282eb4d7d Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Wed, 28 Sep 2022 12:57:44 +0300 Subject: [PATCH 608/610] mmc: core: Add SD card quirk for broken discard commit 07d2872bf4c864eb83d034263c155746a2fb7a3b upstream. Some SD-cards from Sandisk that are SDA-6.0 compliant reports they supports discard, while they actually don't. This might cause mk2fs to fail while trying to format the card and revert it to a read-only mode. To fix this problem, let's add a card quirk (MMC_QUIRK_BROKEN_SD_DISCARD) to indicate that we shall fall-back to use the legacy erase command instead. Signed-off-by: Avri Altman Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220928095744.16455-1-avri.altman@wdc.com [Ulf: Updated the commit message] Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/core/block.c | 7 ++++++- drivers/mmc/core/card.h | 6 ++++++ drivers/mmc/core/quirks.h | 6 ++++++ include/linux/mmc/card.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 3222a9d0c245..b2533be3a453 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1107,6 +1107,11 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) nr = blk_rq_sectors(req); do { + unsigned int erase_arg = card->erase_arg; + + if (mmc_card_broken_sd_discard(card)) + erase_arg = SD_ERASE_ARG; + err = 0; if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -1117,7 +1122,7 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) card->ext_csd.generic_cmd6_time); } if (!err) - err = mmc_erase(card, from, nr, card->erase_arg); + err = mmc_erase(card, from, nr, erase_arg); } while (err == -EIO && !mmc_blk_reset(md, card->host, type)); if (err) status = BLK_STS_IOERR; diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index 7bd392d55cfa..5c6986131faf 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h @@ -70,6 +70,7 @@ struct mmc_fixup { #define EXT_CSD_REV_ANY (-1u) #define CID_MANFID_SANDISK 0x2 +#define CID_MANFID_SANDISK_SD 0x3 #define CID_MANFID_ATP 0x9 #define CID_MANFID_TOSHIBA 0x11 #define CID_MANFID_MICRON 0x13 @@ -222,4 +223,9 @@ static inline int mmc_card_broken_hpi(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_HPI; } +static inline int mmc_card_broken_sd_discard(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD; +} + #endif diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index d68e6e513a4f..c8c0f50a2076 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -99,6 +99,12 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_TRIM_BROKEN), + /* + * Some SD cards reports discard support while they don't + */ + MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd, + MMC_QUIRK_BROKEN_SD_DISCARD), + END_FIXUP }; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 37f975875102..12c7f2d3e210 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -292,6 +292,7 @@ struct mmc_card { #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */ #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ +#define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */ bool reenable_cmdq; /* Re-enable Command Queue */ From 33fc9e26b7cb39f0d4219c875a2451802249c225 Mon Sep 17 00:00:00 2001 From: Seth Jenkins Date: Thu, 27 Oct 2022 11:36:52 -0400 Subject: [PATCH 609/610] mm: /proc/pid/smaps_rollup: fix no vma's null-deref Commit 258f669e7e88 ("mm: /proc/pid/smaps_rollup: convert to single value seq_file") introduced a null-deref if there are no vma's in the task in show_smaps_rollup. Fixes: 258f669e7e88 ("mm: /proc/pid/smaps_rollup: convert to single value seq_file") Signed-off-by: Seth Jenkins Reviewed-by: Alexey Dobriyan Tested-by: Alexey Dobriyan Signed-off-by: Greg Kroah-Hartman --- fs/proc/task_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index d9c07eecd787..c3b76746cce8 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -951,7 +951,7 @@ static int show_smaps_rollup(struct seq_file *m, void *v) vma = vma->vm_next; } - show_vma_header_prefix(m, priv->mm->mmap->vm_start, + show_vma_header_prefix(m, priv->mm->mmap ? priv->mm->mmap->vm_start : 0, last_vma_end, 0, 0, 0, 0); seq_pad(m, ' '); seq_puts(m, "[rollup]\n"); From 4f5365f77018349d64386b202b37e8b737236556 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 29 Oct 2022 10:12:58 +0200 Subject: [PATCH 610/610] Linux 5.15.76 Link: https://lore.kernel.org/r/20221027165054.917467648@linuxfoundation.org Tested-by: Bagas Sanjaya =20 Tested-by: Linux Kernel Functional Testing Tested-by: Sudip Mukherjee Tested-by: Jon Hunter Link: https://lore.kernel.org/r/20221028120302.594918388@linuxfoundation.org Tested-by: Sudip Mukherjee Tested-by: Ron Economos Tested-by: Florian Fainelli Tested-by: Guenter Roeck Tested-by: Bagas Sanjaya =20 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 6cbd4890cfa2..e7293e7a7ee9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 15 -SUBLEVEL = 75 +SUBLEVEL = 76 EXTRAVERSION = NAME = Trick or Treat