From: Sasha Levin Date: Sun, 1 Dec 2024 12:06:16 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v4.19.325~121 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=49e4bcef9d2fb0de15bed2787122056dfcae1e9b;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch b/queue-5.10/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch new file mode 100644 index 00000000000..a9f8852b371 --- /dev/null +++ b/queue-5.10/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch @@ -0,0 +1,46 @@ +From 5d84a31fc46f4427bdb51099c286e689f3d9ca21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Aug 2024 13:12:39 +0300 +Subject: acpi/arm64: Adjust error handling procedure in + gtdt_parse_timer_block() + +From: Aleksandr Mishin + +[ Upstream commit 1a9de2f6fda69d5f105dd8af776856a66abdaa64 ] + +In case of error in gtdt_parse_timer_block() invalid 'gtdt_frame' +will be used in 'do {} while (i-- >= 0 && gtdt_frame--);' statement block +because do{} block will be executed even if 'i == 0'. + +Adjust error handling procedure by replacing 'i-- >= 0' with 'i-- > 0'. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: a712c3ed9b8a ("acpi/arm64: Add memory-mapped timer support in GTDT driver") +Signed-off-by: Aleksandr Mishin +Acked-by: Hanjun Guo +Acked-by: Sudeep Holla +Acked-by: Aleksandr Mishin +Link: https://lore.kernel.org/r/20240827101239.22020-1-amishin@t-argos.ru +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + drivers/acpi/arm64/gtdt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c +index c0e77c1c8e09d..eb6c2d3603874 100644 +--- a/drivers/acpi/arm64/gtdt.c ++++ b/drivers/acpi/arm64/gtdt.c +@@ -283,7 +283,7 @@ static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block, + if (frame->virt_irq > 0) + acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt); + frame->virt_irq = 0; +- } while (i-- >= 0 && gtdt_frame--); ++ } while (i-- > 0 && gtdt_frame--); + + return -EINVAL; + } +-- +2.43.0 + diff --git a/queue-5.10/alsa-6fire-release-resources-at-card-release.patch b/queue-5.10/alsa-6fire-release-resources-at-card-release.patch new file mode 100644 index 00000000000..ce3fec01231 --- /dev/null +++ b/queue-5.10/alsa-6fire-release-resources-at-card-release.patch @@ -0,0 +1,78 @@ +From 8ab1a1a376065713766365f428f797ec3426540e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2024 12:10:39 +0100 +Subject: ALSA: 6fire: Release resources at card release + +From: Takashi Iwai + +[ Upstream commit a0810c3d6dd2d29a9b92604d682eacd2902ce947 ] + +The current 6fire code tries to release the resources right after the +call of usb6fire_chip_abort(). But at this moment, the card object +might be still in use (as we're calling snd_card_free_when_closed()). + +For avoid potential UAFs, move the release of resources to the card's +private_free instead of the manual call of usb6fire_chip_destroy() at +the USB disconnect callback. + +Fixes: c6d43ba816d1 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB") +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20241113111042.15058-6-tiwai@suse.de +Signed-off-by: Sasha Levin +--- + sound/usb/6fire/chip.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c +index 08c6e6a52eb98..ad6f89845a5c2 100644 +--- a/sound/usb/6fire/chip.c ++++ b/sound/usb/6fire/chip.c +@@ -62,8 +62,10 @@ static void usb6fire_chip_abort(struct sfire_chip *chip) + } + } + +-static void usb6fire_chip_destroy(struct sfire_chip *chip) ++static void usb6fire_card_free(struct snd_card *card) + { ++ struct sfire_chip *chip = card->private_data; ++ + if (chip) { + if (chip->pcm) + usb6fire_pcm_destroy(chip); +@@ -73,8 +75,6 @@ static void usb6fire_chip_destroy(struct sfire_chip *chip) + usb6fire_comm_destroy(chip); + if (chip->control) + usb6fire_control_destroy(chip); +- if (chip->card) +- snd_card_free(chip->card); + } + } + +@@ -137,6 +137,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf, + chip->regidx = regidx; + chip->intf_count = 1; + chip->card = card; ++ card->private_free = usb6fire_card_free; + + ret = usb6fire_comm_init(chip); + if (ret < 0) +@@ -163,7 +164,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf, + return 0; + + destroy_chip: +- usb6fire_chip_destroy(chip); ++ snd_card_free(card); + return ret; + } + +@@ -182,7 +183,6 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf) + + chip->shutdown = true; + usb6fire_chip_abort(chip); +- usb6fire_chip_destroy(chip); + } + } + } +-- +2.43.0 + diff --git a/queue-5.10/alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch b/queue-5.10/alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch new file mode 100644 index 00000000000..e415ece0ca8 --- /dev/null +++ b/queue-5.10/alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch @@ -0,0 +1,168 @@ +From 452ff0c016d0a2518317507748c575665ceec7bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2024 12:10:38 +0100 +Subject: ALSA: caiaq: Use snd_card_free_when_closed() at disconnection + +From: Takashi Iwai + +[ Upstream commit b04dcbb7f7b1908806b7dc22671cdbe78ff2b82c ] + +The USB disconnect callback is supposed to be short and not too-long +waiting. OTOH, the current code uses snd_card_free() at +disconnection, but this waits for the close of all used fds, hence it +can take long. It eventually blocks the upper layer USB ioctls, which +may trigger a soft lockup. + +An easy workaround is to replace snd_card_free() with +snd_card_free_when_closed(). This variant returns immediately while +the release of resources is done asynchronously by the card device +release at the last close. + +This patch also splits the code to the disconnect and the free phases; +the former is called immediately at the USB disconnect callback while +the latter is called from the card destructor. + +Fixes: 523f1dce3743 ("[ALSA] Add Native Instrument usb audio device support") +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20241113111042.15058-5-tiwai@suse.de +Signed-off-by: Sasha Levin +--- + sound/usb/caiaq/audio.c | 10 ++++++++-- + sound/usb/caiaq/audio.h | 1 + + sound/usb/caiaq/device.c | 19 +++++++++++++++---- + sound/usb/caiaq/input.c | 12 +++++++++--- + sound/usb/caiaq/input.h | 1 + + 5 files changed, 34 insertions(+), 9 deletions(-) + +diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c +index 3b6bb2cbe886b..1308415b55ed8 100644 +--- a/sound/usb/caiaq/audio.c ++++ b/sound/usb/caiaq/audio.c +@@ -869,14 +869,20 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) + return 0; + } + +-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev) ++void snd_usb_caiaq_audio_disconnect(struct snd_usb_caiaqdev *cdev) + { + struct device *dev = caiaqdev_to_dev(cdev); + + dev_dbg(dev, "%s(%p)\n", __func__, cdev); + stream_stop(cdev); ++} ++ ++void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev) ++{ ++ struct device *dev = caiaqdev_to_dev(cdev); ++ ++ dev_dbg(dev, "%s(%p)\n", __func__, cdev); + free_urbs(cdev->data_urbs_in); + free_urbs(cdev->data_urbs_out); + kfree(cdev->data_cb_info); + } +- +diff --git a/sound/usb/caiaq/audio.h b/sound/usb/caiaq/audio.h +index 869bf6264d6a0..07f5d064456cf 100644 +--- a/sound/usb/caiaq/audio.h ++++ b/sound/usb/caiaq/audio.h +@@ -3,6 +3,7 @@ + #define CAIAQ_AUDIO_H + + int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev); ++void snd_usb_caiaq_audio_disconnect(struct snd_usb_caiaqdev *cdev); + void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev); + + #endif /* CAIAQ_AUDIO_H */ +diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c +index 2af3b7eb0a88c..482d4915e0a70 100644 +--- a/sound/usb/caiaq/device.c ++++ b/sound/usb/caiaq/device.c +@@ -390,6 +390,17 @@ static void setup_card(struct snd_usb_caiaqdev *cdev) + dev_err(dev, "Unable to set up control system (ret=%d)\n", ret); + } + ++static void card_free(struct snd_card *card) ++{ ++ struct snd_usb_caiaqdev *cdev = caiaqdev(card); ++ ++#ifdef CONFIG_SND_USB_CAIAQ_INPUT ++ snd_usb_caiaq_input_free(cdev); ++#endif ++ snd_usb_caiaq_audio_free(cdev); ++ usb_reset_device(cdev->chip.dev); ++} ++ + static int create_card(struct usb_device *usb_dev, + struct usb_interface *intf, + struct snd_card **cardp) +@@ -503,6 +514,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev) + cdev->vendor_name, cdev->product_name, usbpath); + + setup_card(cdev); ++ card->private_free = card_free; + return 0; + + err_kill_urb: +@@ -548,15 +560,14 @@ static void snd_disconnect(struct usb_interface *intf) + snd_card_disconnect(card); + + #ifdef CONFIG_SND_USB_CAIAQ_INPUT +- snd_usb_caiaq_input_free(cdev); ++ snd_usb_caiaq_input_disconnect(cdev); + #endif +- snd_usb_caiaq_audio_free(cdev); ++ snd_usb_caiaq_audio_disconnect(cdev); + + usb_kill_urb(&cdev->ep1_in_urb); + usb_kill_urb(&cdev->midi_out_urb); + +- snd_card_free(card); +- usb_reset_device(interface_to_usbdev(intf)); ++ snd_card_free_when_closed(card); + } + + +diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c +index 84f26dce7f5d0..a9130891bb696 100644 +--- a/sound/usb/caiaq/input.c ++++ b/sound/usb/caiaq/input.c +@@ -829,15 +829,21 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev) + return ret; + } + +-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev) ++void snd_usb_caiaq_input_disconnect(struct snd_usb_caiaqdev *cdev) + { + if (!cdev || !cdev->input_dev) + return; + + usb_kill_urb(cdev->ep4_in_urb); ++ input_unregister_device(cdev->input_dev); ++} ++ ++void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev) ++{ ++ if (!cdev || !cdev->input_dev) ++ return; ++ + usb_free_urb(cdev->ep4_in_urb); + cdev->ep4_in_urb = NULL; +- +- input_unregister_device(cdev->input_dev); + cdev->input_dev = NULL; + } +diff --git a/sound/usb/caiaq/input.h b/sound/usb/caiaq/input.h +index c42891e7be884..fbe267f85d025 100644 +--- a/sound/usb/caiaq/input.h ++++ b/sound/usb/caiaq/input.h +@@ -4,6 +4,7 @@ + + void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev, char *buf, unsigned int len); + int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev); ++void snd_usb_caiaq_input_disconnect(struct snd_usb_caiaqdev *cdev); + void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev); + + #endif +-- +2.43.0 + diff --git a/queue-5.10/alsa-hda-realtek-add-type-for-alc287.patch b/queue-5.10/alsa-hda-realtek-add-type-for-alc287.patch new file mode 100644 index 00000000000..9e4494c0305 --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-add-type-for-alc287.patch @@ -0,0 +1,64 @@ +From bfa5e782c9b957136586fff0522bb84a3914c031 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Jul 2021 09:09:37 +0800 +Subject: ALSA: hda/realtek - Add type for ALC287 + +From: Kailang Yang + +[ Upstream commit 99cee034c28947fc122799b0b7714e01b047f3f3 ] + +Add independent type for ALC287. + +Signed-off-by: Kailang Yang +Link: https://lore.kernel.org/r/2b7539c3e96f41a4ab458d53ea5f5784@realtek.com +Signed-off-by: Takashi Iwai +Stable-dep-of: cc3d0b5dd989 ("ALSA: hda/realtek: Update ALC256 depop procedure") +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index e9b7bf94aa3a8..b1dbb0b4c8158 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3168,6 +3168,7 @@ enum { + ALC269_TYPE_ALC257, + ALC269_TYPE_ALC215, + ALC269_TYPE_ALC225, ++ ALC269_TYPE_ALC287, + ALC269_TYPE_ALC294, + ALC269_TYPE_ALC300, + ALC269_TYPE_ALC623, +@@ -3204,6 +3205,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) + case ALC269_TYPE_ALC257: + case ALC269_TYPE_ALC215: + case ALC269_TYPE_ALC225: ++ case ALC269_TYPE_ALC287: + case ALC269_TYPE_ALC294: + case ALC269_TYPE_ALC300: + case ALC269_TYPE_ALC623: +@@ -10250,7 +10252,6 @@ static int patch_alc269(struct hda_codec *codec) + case 0x10ec0215: + case 0x10ec0245: + case 0x10ec0285: +- case 0x10ec0287: + case 0x10ec0289: + spec->codec_variant = ALC269_TYPE_ALC215; + spec->shutup = alc225_shutup; +@@ -10265,6 +10266,12 @@ static int patch_alc269(struct hda_codec *codec) + spec->init_hook = alc225_init; + spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */ + break; ++ case 0x10ec0287: ++ spec->codec_variant = ALC269_TYPE_ALC287; ++ spec->shutup = alc225_shutup; ++ spec->init_hook = alc225_init; ++ spec->gen.mixer_nid = 0; /* no loopback on ALC287 */ ++ break; + case 0x10ec0234: + case 0x10ec0274: + case 0x10ec0294: +-- +2.43.0 + diff --git a/queue-5.10/alsa-hda-realtek-update-alc256-depop-procedure.patch b/queue-5.10/alsa-hda-realtek-update-alc256-depop-procedure.patch new file mode 100644 index 00000000000..a2725bb51b2 --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-update-alc256-depop-procedure.patch @@ -0,0 +1,102 @@ +From 07ee559bf2b987dc9741b61d5036d61852782a8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Nov 2024 15:21:09 +0800 +Subject: ALSA: hda/realtek: Update ALC256 depop procedure + +From: Kailang Yang + +[ Upstream commit cc3d0b5dd989d3238d456f9fd385946379a9c13d ] + +Old procedure has a chance to meet Headphone no output. + +Fixes: 4a219ef8f370 ("ALSA: hda/realtek - Add ALC256 HP depop function") +Signed-off-by: Kailang Yang +Link: https://lore.kernel.org/463c5f93715d4714967041a0a8cec28e@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 42 ++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 23 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index b1dbb0b4c8158..eec99b9cd7692 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3596,25 +3596,22 @@ static void alc256_init(struct hda_codec *codec) + + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); + +- if (hp_pin_sense) ++ if (hp_pin_sense) { + msleep(2); ++ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ + +- alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ +- +- snd_hda_codec_write(codec, hp_pin, 0, +- AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); +- +- if (hp_pin_sense || spec->ultra_low_power) +- msleep(85); +- +- snd_hda_codec_write(codec, hp_pin, 0, ++ snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + +- if (hp_pin_sense || spec->ultra_low_power) +- msleep(100); ++ msleep(75); ++ ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + ++ msleep(75); ++ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ ++ } + alc_update_coef_idx(codec, 0x46, 3 << 12, 0); +- alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */ + alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15); + /* +@@ -3638,29 +3635,28 @@ static void alc256_shutup(struct hda_codec *codec) + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); + +- if (hp_pin_sense) ++ if (hp_pin_sense) { + msleep(2); + +- snd_hda_codec_write(codec, hp_pin, 0, ++ snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + +- if (hp_pin_sense || spec->ultra_low_power) +- msleep(85); ++ msleep(75); + + /* 3k pull low control for Headset jack. */ + /* NOTE: call this before clearing the pin, otherwise codec stalls */ + /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly + * when booting with headset plugged. So skip setting it for the codec alc257 + */ +- if (spec->en_3kpull_low) +- alc_update_coef_idx(codec, 0x46, 0, 3 << 12); ++ if (spec->en_3kpull_low) ++ alc_update_coef_idx(codec, 0x46, 0, 3 << 12); + +- if (!spec->no_shutup_pins) +- snd_hda_codec_write(codec, hp_pin, 0, ++ if (!spec->no_shutup_pins) ++ snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + +- if (hp_pin_sense || spec->ultra_low_power) +- msleep(100); ++ msleep(75); ++ } + + alc_auto_setup_eapd(codec, false); + alc_shutup_pins(codec); +-- +2.43.0 + diff --git a/queue-5.10/alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch b/queue-5.10/alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch new file mode 100644 index 00000000000..7bc8469815f --- /dev/null +++ b/queue-5.10/alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch @@ -0,0 +1,50 @@ +From e4ea1588ecfb97e4717f974e39c6a38ed32f977b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2024 12:10:36 +0100 +Subject: ALSA: us122l: Use snd_card_free_when_closed() at disconnection + +From: Takashi Iwai + +[ Upstream commit b7df09bb348016943f56b09dcaafe221e3f73947 ] + +The USB disconnect callback is supposed to be short and not too-long +waiting. OTOH, the current code uses snd_card_free() at +disconnection, but this waits for the close of all used fds, hence it +can take long. It eventually blocks the upper layer USB ioctls, which +may trigger a soft lockup. + +An easy workaround is to replace snd_card_free() with +snd_card_free_when_closed(). This variant returns immediately while +the release of resources is done asynchronously by the card device +release at the last close. + +The loop of us122l->mmap_count check is dropped as well. The check is +useless for the asynchronous operation with *_when_closed(). + +Fixes: 030a07e44129 ("ALSA: Add USB US122L driver") +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20241113111042.15058-3-tiwai@suse.de +Signed-off-by: Sasha Levin +--- + sound/usb/usx2y/us122l.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c +index 0b0a87a631a06..bccb47d38c6dc 100644 +--- a/sound/usb/usx2y/us122l.c ++++ b/sound/usb/usx2y/us122l.c +@@ -617,10 +617,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf) + usb_put_intf(usb_ifnum_to_if(us122l->dev, 1)); + usb_put_dev(us122l->dev); + +- while (atomic_read(&us122l->mmap_count)) +- msleep(500); +- +- snd_card_free(card); ++ snd_card_free_when_closed(card); + } + + static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message) +-- +2.43.0 + diff --git a/queue-5.10/alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch b/queue-5.10/alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch new file mode 100644 index 00000000000..9ac33b4a23e --- /dev/null +++ b/queue-5.10/alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch @@ -0,0 +1,167 @@ +From 759895f8bb6fd488aa135c3f7d1a1224c384a46d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 May 2021 15:15:44 +0200 +Subject: ALSA: usx2y: Cleanup probe and disconnect callbacks + +From: Takashi Iwai + +[ Upstream commit 2ac7a12ead2be2e31bd5e796455bef31e8516845 ] + +Minor code refactoring by merging the superfluous function calls. +The functions were split in the past for covering pre-history USB +driver code, but this is utterly useless. + +Link: https://lore.kernel.org/r/20210517131545.27252-11-tiwai@suse.de +Signed-off-by: Takashi Iwai +Stable-dep-of: dafb28f02be4 ("ALSA: usx2y: Use snd_card_free_when_closed() at disconnection") +Signed-off-by: Sasha Levin +--- + sound/usb/usx2y/usbusx2y.c | 107 ++++++++++++++----------------------- + 1 file changed, 40 insertions(+), 67 deletions(-) + +diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c +index 373c600ba3fec..9d5a33c4ff2f3 100644 +--- a/sound/usb/usx2y/usbusx2y.c ++++ b/sound/usb/usx2y/usbusx2y.c +@@ -149,7 +149,6 @@ MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); + + static int snd_usx2y_card_used[SNDRV_CARDS]; + +-static void usx2y_usb_disconnect(struct usb_device *usb_device, void *ptr); + static void snd_usx2y_card_private_free(struct snd_card *card); + + /* +@@ -363,66 +362,6 @@ static int usx2y_create_card(struct usb_device *device, + return 0; + } + +-static int usx2y_usb_probe(struct usb_device *device, +- struct usb_interface *intf, +- const struct usb_device_id *device_id, +- struct snd_card **cardp) +-{ +- int err; +- struct snd_card *card; +- +- *cardp = NULL; +- if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || +- (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && +- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && +- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) +- return -EINVAL; +- +- err = usx2y_create_card(device, intf, &card); +- if (err < 0) +- return err; +- err = usx2y_hwdep_new(card, device); +- if (err < 0) +- goto error; +- err = snd_card_register(card); +- if (err < 0) +- goto error; +- *cardp = card; +- return 0; +- +- error: +- snd_card_free(card); +- return err; +-} +- +-/* +- * new 2.5 USB kernel API +- */ +-static int snd_usx2y_probe(struct usb_interface *intf, const struct usb_device_id *id) +-{ +- struct snd_card *card; +- int err; +- +- err = usx2y_usb_probe(interface_to_usbdev(intf), intf, id, &card); +- if (err < 0) +- return err; +- dev_set_drvdata(&intf->dev, card); +- return 0; +-} +- +-static void snd_usx2y_disconnect(struct usb_interface *intf) +-{ +- usx2y_usb_disconnect(interface_to_usbdev(intf), +- usb_get_intfdata(intf)); +-} +- +-static struct usb_driver snd_usx2y_usb_driver = { +- .name = "snd-usb-usx2y", +- .probe = snd_usx2y_probe, +- .disconnect = snd_usx2y_disconnect, +- .id_table = snd_usx2y_usb_id_table, +-}; +- + static void snd_usx2y_card_private_free(struct snd_card *card) + { + struct usx2ydev *usx2y = usx2y(card); +@@ -436,18 +375,15 @@ static void snd_usx2y_card_private_free(struct snd_card *card) + snd_usx2y_card_used[usx2y->card_index] = 0; + } + +-/* +- * Frees the device. +- */ +-static void usx2y_usb_disconnect(struct usb_device *device, void *ptr) ++static void snd_usx2y_disconnect(struct usb_interface *intf) + { + struct snd_card *card; + struct usx2ydev *usx2y; + struct list_head *p; + +- if (!ptr) ++ card = usb_get_intfdata(intf); ++ if (!card) + return; +- card = ptr; + usx2y = usx2y(card); + usx2y->chip_status = USX2Y_STAT_CHIP_HUP; + usx2y_unlinkseq(&usx2y->as04); +@@ -463,4 +399,41 @@ static void usx2y_usb_disconnect(struct usb_device *device, void *ptr) + snd_card_free(card); + } + ++static int snd_usx2y_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *device = interface_to_usbdev(intf); ++ struct snd_card *card; ++ int err; ++ ++ if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || ++ (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && ++ le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && ++ le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428)) ++ return -EINVAL; ++ ++ err = usx2y_create_card(device, intf, &card); ++ if (err < 0) ++ return err; ++ err = usx2y_hwdep_new(card, device); ++ if (err < 0) ++ goto error; ++ err = snd_card_register(card); ++ if (err < 0) ++ goto error; ++ ++ dev_set_drvdata(&intf->dev, card); ++ return 0; ++ ++ error: ++ snd_card_free(card); ++ return err; ++} ++ ++static struct usb_driver snd_usx2y_usb_driver = { ++ .name = "snd-usb-usx2y", ++ .probe = snd_usx2y_probe, ++ .disconnect = snd_usx2y_disconnect, ++ .id_table = snd_usx2y_usb_id_table, ++}; + module_usb_driver(snd_usx2y_usb_driver); +-- +2.43.0 + diff --git a/queue-5.10/alsa-usx2y-coding-style-fixes.patch b/queue-5.10/alsa-usx2y-coding-style-fixes.patch new file mode 100644 index 00000000000..cd224f10f27 --- /dev/null +++ b/queue-5.10/alsa-usx2y-coding-style-fixes.patch @@ -0,0 +1,1719 @@ +From 7500224b4d11492fe8f8eea79b20490c4cabff53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 May 2021 15:15:37 +0200 +Subject: ALSA: usx2y: Coding style fixes + +From: Takashi Iwai + +[ Upstream commit a829dd5b3840fd9a24608ed73eb21ba239ae5334 ] + +This patch fixes various trivial coding-style issues in usx2y code, +such as: +* the assginments in if condition +* comparison order with constants +* NULL / zero checks +* unsigned -> unsigned int +* addition of braces in control blocks +* debug print with function names +* move local variables in block into function head +* reduction of too nested indentations + +No functional changes. + +Link: https://lore.kernel.org/r/20210517131545.27252-4-tiwai@suse.de +Signed-off-by: Takashi Iwai +Stable-dep-of: dafb28f02be4 ("ALSA: usx2y: Use snd_card_free_when_closed() at disconnection") +Signed-off-by: Sasha Levin +--- + sound/usb/usx2y/us122l.c | 25 ++-- + sound/usb/usx2y/us122l.h | 2 +- + sound/usb/usx2y/usX2Yhwdep.c | 38 ++--- + sound/usb/usx2y/usb_stream.c | 32 +++-- + sound/usb/usx2y/usb_stream.h | 23 ++-- + sound/usb/usx2y/usbusx2y.c | 122 ++++++++-------- + sound/usb/usx2y/usbusx2y.h | 2 +- + sound/usb/usx2y/usbusx2yaudio.c | 220 +++++++++++++++-------------- + sound/usb/usx2y/usx2yhwdeppcm.c | 237 +++++++++++++++++--------------- + 9 files changed, 381 insertions(+), 320 deletions(-) + +diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c +index 53e7eb4480b30..0b0a87a631a06 100644 +--- a/sound/usb/usx2y/us122l.c ++++ b/sound/usb/usx2y/us122l.c +@@ -114,9 +114,9 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf) + goto unlock; + + offset = vmf->pgoff << PAGE_SHIFT; +- if (offset < PAGE_ALIGN(s->read_size)) ++ if (offset < PAGE_ALIGN(s->read_size)) { + vaddr = (char *)s + offset; +- else { ++ } else { + offset -= PAGE_ALIGN(s->read_size); + if (offset >= PAGE_ALIGN(s->write_size)) + goto unlock; +@@ -238,7 +238,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw, + struct file *file, poll_table *wait) + { + struct us122l *us122l = hw->private_data; +- unsigned *polled; ++ unsigned int *polled; + __poll_t mask; + + poll_wait(file, &us122l->sk.sleep, wait); +@@ -255,8 +255,9 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw, + if (*polled != s->periods_done) { + *polled = s->periods_done; + mask = EPOLLIN | EPOLLOUT | EPOLLWRNORM; +- } else ++ } else { + mask = 0; ++ } + } + mutex_unlock(&us122l->mutex); + } +@@ -294,11 +295,11 @@ static int us122l_set_sample_rate(struct usb_device *dev, int rate) + } + + static bool us122l_start(struct us122l *us122l, +- unsigned rate, unsigned period_frames) ++ unsigned int rate, unsigned int period_frames) + { + struct list_head *p; + int err; +- unsigned use_packsize = 0; ++ unsigned int use_packsize = 0; + bool success = false; + + if (us122l->dev->speed == USB_SPEED_HIGH) { +@@ -331,7 +332,7 @@ static bool us122l_start(struct us122l *us122l, + err = usb_stream_start(&us122l->sk); + if (err < 0) { + us122l_stop(us122l); +- snd_printk(KERN_ERR "us122l_start error %i\n", err); ++ snd_printk(KERN_ERR "%s error %i\n", __func__, err); + goto out; + } + list_for_each(p, &us122l->midi_list) +@@ -342,12 +343,12 @@ static bool us122l_start(struct us122l *us122l, + } + + static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, +- unsigned cmd, unsigned long arg) ++ unsigned int cmd, unsigned long arg) + { + struct usb_stream_config cfg; + struct us122l *us122l = hw->private_data; + struct usb_stream *s; +- unsigned min_period_frames; ++ unsigned int min_period_frames; + int err = 0; + bool high_speed; + +@@ -388,9 +389,9 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + + mutex_lock(&us122l->mutex); + s = us122l->sk.s; +- if (!us122l->master) ++ if (!us122l->master) { + us122l->master = file; +- else if (us122l->master != file) { ++ } else if (us122l->master != file) { + if (!s || memcmp(&cfg, &s->cfg, sizeof(cfg))) { + err = -EIO; + goto unlock; +@@ -490,7 +491,7 @@ static void snd_us122l_free(struct snd_card *card) + struct us122l *us122l = US122L(card); + int index = us122l->card_index; + +- if (index >= 0 && index < SNDRV_CARDS) ++ if (index >= 0 && index < SNDRV_CARDS) + snd_us122l_card_used[index] = 0; + } + +diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h +index 34bea99d343ca..c32ae5e981e90 100644 +--- a/sound/usb/usx2y/us122l.h ++++ b/sound/usb/usx2y/us122l.h +@@ -11,7 +11,7 @@ struct us122l { + + struct mutex mutex; + struct file *first; +- unsigned second_periods_polled; ++ unsigned int second_periods_polled; + struct file *master; + struct file *slave; + struct list_head midi_list; +diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c +index 90246518dbddb..2d4e943be2dad 100644 +--- a/sound/usb/usx2y/usX2Yhwdep.c ++++ b/sound/usb/usx2y/usX2Yhwdep.c +@@ -85,7 +85,7 @@ static __poll_t snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll + + poll_wait(file, &us428->us428ctls_wait_queue_head, wait); + +- if (shm != NULL && shm->ctl_snapshot_last != shm->ctl_snapshot_red) ++ if (shm && shm->ctl_snapshot_last != shm->ctl_snapshot_red) + mask |= EPOLLIN; + + return mask; +@@ -114,7 +114,7 @@ static int snd_usx2y_hwdep_dsp_status(struct snd_hwdep *hw, + id = USX2Y_TYPE_428; + break; + } +- if (0 > id) ++ if (id < 0) + return -ENODEV; + strcpy(info->id, type_ids[id]); + info->num_dsps = 2; // 0: Prepad Data, 1: FPGA Code +@@ -158,7 +158,7 @@ static int usx2y_create_usbmidi(struct snd_card *card) + le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? + &quirk_2 : &quirk_1; + +- snd_printdd("usx2y_create_usbmidi\n"); ++ snd_printdd("%s\n", __func__); + return snd_usbmidi_create(card, iface, &usx2y(card)->midi_list, quirk); + } + +@@ -166,20 +166,21 @@ static int usx2y_create_alsa_devices(struct snd_card *card) + { + int err; + +- do { +- if ((err = usx2y_create_usbmidi(card)) < 0) { +- snd_printk(KERN_ERR "usx2y_create_alsa_devices: usx2y_create_usbmidi error %i\n", err); +- break; +- } +- if ((err = usx2y_audio_create(card)) < 0) +- break; +- if ((err = usx2y_hwdep_pcm_new(card)) < 0) +- break; +- if ((err = snd_card_register(card)) < 0) +- break; +- } while (0); +- +- return err; ++ err = usx2y_create_usbmidi(card); ++ if (err < 0) { ++ snd_printk(KERN_ERR "%s: usx2y_create_usbmidi error %i\n", __func__, err); ++ return err; ++ } ++ err = usx2y_audio_create(card); ++ if (err < 0) ++ return err; ++ err = usx2y_hwdep_pcm_new(card); ++ if (err < 0) ++ return err; ++ err = snd_card_register(card); ++ if (err < 0) ++ return err; ++ return 0; + } + + static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw, +@@ -233,7 +234,8 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device) + int err; + struct snd_hwdep *hw; + +- if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0) ++ err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw); ++ if (err < 0) + return err; + + hw->iface = SNDRV_HWDEP_IFACE_USX2Y; +diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c +index 5726466c53257..9d0e44793896f 100644 +--- a/sound/usb/usx2y/usb_stream.c ++++ b/sound/usb/usx2y/usb_stream.c +@@ -10,7 +10,7 @@ + + /* setup */ + +-static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk) ++static unsigned int usb_stream_next_packet_size(struct usb_stream_kernel *sk) + { + struct usb_stream *s = sk->s; + +@@ -44,9 +44,10 @@ static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb) + lb, s->period_size); + } + +-static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, +- struct urb **urbs, char *transfer, +- struct usb_device *dev, int pipe) ++static int init_pipe_urbs(struct usb_stream_kernel *sk, ++ unsigned int use_packsize, ++ struct urb **urbs, char *transfer, ++ struct usb_device *dev, int pipe) + { + int u, p; + int maxpacket = use_packsize ? +@@ -82,8 +83,8 @@ static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, + return 0; + } + +-static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, +- struct usb_device *dev, int in_pipe, int out_pipe) ++static int init_urbs(struct usb_stream_kernel *sk, unsigned int use_packsize, ++ struct usb_device *dev, int in_pipe, int out_pipe) + { + struct usb_stream *s = sk->s; + char *indata = +@@ -112,7 +113,7 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, + * convert a sampling rate into our full speed format (fs/1000 in Q16.16) + * this will overflow at approx 524 kHz + */ +-static inline unsigned get_usb_full_speed_rate(unsigned rate) ++static inline unsigned int get_usb_full_speed_rate(unsigned int rate) + { + return ((rate << 13) + 62) / 125; + } +@@ -121,7 +122,7 @@ static inline unsigned get_usb_full_speed_rate(unsigned rate) + * convert a sampling rate into USB high speed format (fs/8000 in Q16.16) + * this will overflow at approx 4 MHz + */ +-static inline unsigned get_usb_high_speed_rate(unsigned rate) ++static inline unsigned int get_usb_high_speed_rate(unsigned int rate) + { + return ((rate << 10) + 62) / 125; + } +@@ -129,7 +130,7 @@ static inline unsigned get_usb_high_speed_rate(unsigned rate) + void usb_stream_free(struct usb_stream_kernel *sk) + { + struct usb_stream *s; +- unsigned u; ++ unsigned int u; + + for (u = 0; u < USB_STREAM_NURBS; ++u) { + usb_free_urb(sk->inurb[u]); +@@ -153,9 +154,12 @@ void usb_stream_free(struct usb_stream_kernel *sk) + + struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, + struct usb_device *dev, +- unsigned in_endpoint, unsigned out_endpoint, +- unsigned sample_rate, unsigned use_packsize, +- unsigned period_frames, unsigned frame_size) ++ unsigned int in_endpoint, ++ unsigned int out_endpoint, ++ unsigned int sample_rate, ++ unsigned int use_packsize, ++ unsigned int period_frames, ++ unsigned int frame_size) + { + int packets, max_packsize; + int in_pipe, out_pipe; +@@ -531,7 +535,7 @@ static void stream_start(struct usb_stream_kernel *sk, + if (s->state >= usb_stream_sync1) { + int l, p, max_diff, max_diff_0; + int urb_size = 0; +- unsigned frames_per_packet, min_frames = 0; ++ unsigned int frames_per_packet, min_frames = 0; + + frames_per_packet = (s->period_size - s->idle_insize); + frames_per_packet <<= 8; +@@ -573,7 +577,7 @@ static void stream_start(struct usb_stream_kernel *sk, + (s->inpacket_head + 1) % s->inpackets; + s->next_inpacket_split_at = 0; + } else { +- unsigned split = s->inpacket_head; ++ unsigned int split = s->inpacket_head; + + l = s->idle_insize; + while (l > s->inpacket[split].length) { +diff --git a/sound/usb/usx2y/usb_stream.h b/sound/usb/usx2y/usb_stream.h +index 851358a8d709a..73e57b341adc8 100644 +--- a/sound/usb/usx2y/usb_stream.h ++++ b/sound/usb/usx2y/usb_stream.h +@@ -12,7 +12,7 @@ struct usb_stream_kernel { + + void *write_page; + +- unsigned n_o_ps; ++ unsigned int n_o_ps; + + struct urb *inurb[USB_STREAM_NURBS]; + struct urb *idle_inurb; +@@ -26,18 +26,21 @@ struct usb_stream_kernel { + + wait_queue_head_t sleep; + +- unsigned out_phase; +- unsigned out_phase_peeked; +- unsigned freqn; ++ unsigned int out_phase; ++ unsigned int out_phase_peeked; ++ unsigned int freqn; + }; + + struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, + struct usb_device *dev, +- unsigned in_endpoint, unsigned out_endpoint, +- unsigned sample_rate, unsigned use_packsize, +- unsigned period_frames, unsigned frame_size); +-void usb_stream_free(struct usb_stream_kernel *); +-int usb_stream_start(struct usb_stream_kernel *); +-void usb_stream_stop(struct usb_stream_kernel *); ++ unsigned int in_endpoint, ++ unsigned int out_endpoint, ++ unsigned int sample_rate, ++ unsigned int use_packsize, ++ unsigned int period_frames, ++ unsigned int frame_size); ++void usb_stream_free(struct usb_stream_kernel *sk); ++int usb_stream_start(struct usb_stream_kernel *sk); ++void usb_stream_stop(struct usb_stream_kernel *sk); + + #endif /* __USB_STREAM_H */ +diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c +index 9bd2ade8f9b5b..373c600ba3fec 100644 +--- a/sound/usb/usx2y/usbusx2y.c ++++ b/sound/usb/usx2y/usbusx2y.c +@@ -164,7 +164,7 @@ static void i_usx2y_out04_int(struct urb *urb) + + for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++) + ; +- snd_printdd("i_usx2y_out04_int() urb %i status=%i\n", i, urb->status); ++ snd_printdd("%s urb %i status=%i\n", __func__, i, urb->status); + } + #endif + } +@@ -174,6 +174,8 @@ static void i_usx2y_in04_int(struct urb *urb) + int err = 0; + struct usx2ydev *usx2y = urb->context; + struct us428ctls_sharedmem *us428ctls = usx2y->us428ctls_sharedmem; ++ struct us428_p4out *p4out; ++ int i, j, n, diff, send; + + usx2y->in04_int_calls++; + +@@ -184,15 +186,12 @@ static void i_usx2y_in04_int(struct urb *urb) + + // printk("%i:0x%02X ", 8, (int)((unsigned char*)usx2y->in04_buf)[8]); Master volume shows 0 here if fader is at max during boot ?!? + if (us428ctls) { +- int diff = -1; +- +- if (-2 == us428ctls->ctl_snapshot_last) { ++ diff = -1; ++ if (us428ctls->ctl_snapshot_last == -2) { + diff = 0; + memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last)); + us428ctls->ctl_snapshot_last = -1; + } else { +- int i; +- + for (i = 0; i < 21; i++) { + if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) { + if (diff < 0) +@@ -201,10 +200,9 @@ static void i_usx2y_in04_int(struct urb *urb) + } + } + } +- if (0 <= diff) { +- int n = us428ctls->ctl_snapshot_last + 1; +- +- if (n >= N_US428_CTL_BUFS || n < 0) ++ if (diff >= 0) { ++ n = us428ctls->ctl_snapshot_last + 1; ++ if (n >= N_US428_CTL_BUFS || n < 0) + n = 0; + memcpy(us428ctls->ctl_snapshot + n, usx2y->in04_buf, sizeof(us428ctls->ctl_snapshot[0])); + us428ctls->ctl_snapshot_differs_at[n] = diff; +@@ -214,21 +212,20 @@ static void i_usx2y_in04_int(struct urb *urb) + } + + if (usx2y->us04) { +- if (0 == usx2y->us04->submitted) ++ if (!usx2y->us04->submitted) { + do { + err = usb_submit_urb(usx2y->us04->urb[usx2y->us04->submitted++], GFP_ATOMIC); + } while (!err && usx2y->us04->submitted < usx2y->us04->len); +- } else ++ } ++ } else { + if (us428ctls && us428ctls->p4out_last >= 0 && us428ctls->p4out_last < N_US428_P4OUT_BUFS) { + if (us428ctls->p4out_last != us428ctls->p4out_sent) { +- int j, send = us428ctls->p4out_sent + 1; +- ++ send = us428ctls->p4out_sent + 1; + if (send >= N_US428_P4OUT_BUFS) + send = 0; +- for (j = 0; j < URBS_ASYNC_SEQ && !err; ++j) +- if (0 == usx2y->as04.urb[j]->status) { +- struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. +- ++ for (j = 0; j < URBS_ASYNC_SEQ && !err; ++j) { ++ if (!usx2y->as04.urb[j]->status) { ++ p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. + usb_fill_bulk_urb(usx2y->as04.urb[j], usx2y->dev, + usb_sndbulkpipe(usx2y->dev, 0x04), &p4out->val.vol, + p4out->type == ELT_LIGHT ? sizeof(struct us428_lights) : 5, +@@ -237,8 +234,10 @@ static void i_usx2y_in04_int(struct urb *urb) + us428ctls->p4out_sent = send; + break; + } ++ } + } + } ++ } + + if (err) + snd_printk(KERN_ERR "in04_int() usb_submit_urb err=%i\n", err); +@@ -256,31 +255,35 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y) + + usx2y->as04.buffer = kmalloc_array(URBS_ASYNC_SEQ, + URB_DATA_LEN_ASYNC_SEQ, GFP_KERNEL); +- if (NULL == usx2y->as04.buffer) { ++ if (!usx2y->as04.buffer) { + err = -ENOMEM; +- } else ++ } else { + for (i = 0; i < URBS_ASYNC_SEQ; ++i) { +- if (NULL == (usx2y->as04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { ++ usx2y->as04.urb[i] = usb_alloc_urb(0, GFP_KERNEL); ++ if (!usx2y->as04.urb[i]) { + err = -ENOMEM; + break; + } + usb_fill_bulk_urb(usx2y->as04.urb[i], usx2y->dev, + usb_sndbulkpipe(usx2y->dev, 0x04), +- usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ*i, 0, ++ usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ * i, 0, + i_usx2y_out04_int, usx2y); + err = usb_urb_ep_type_check(usx2y->as04.urb[i]); + if (err < 0) + break; + } ++ } + return err; + } + + int usx2y_in04_init(struct usx2ydev *usx2y) + { +- if (!(usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL))) ++ usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!usx2y->in04_urb) + return -ENOMEM; + +- if (!(usx2y->in04_buf = kmalloc(21, GFP_KERNEL))) ++ usx2y->in04_buf = kmalloc(21, GFP_KERNEL); ++ if (!usx2y->in04_buf) + return -ENOMEM; + + init_waitqueue_head(&usx2y->in04_wait_queue); +@@ -355,8 +358,7 @@ static int usx2y_create_card(struct usb_device *device, + le16_to_cpu(device->descriptor.idVendor), + le16_to_cpu(device->descriptor.idProduct), + 0,//us428(card)->usbmidi.ifnum, +- usx2y(card)->dev->bus->busnum, usx2y(card)->dev->devnum +- ); ++ usx2y(card)->dev->bus->busnum, usx2y(card)->dev->devnum); + *cardp = card; + return 0; + } +@@ -379,13 +381,18 @@ static int usx2y_usb_probe(struct usb_device *device, + err = usx2y_create_card(device, intf, &card); + if (err < 0) + return err; +- if ((err = usx2y_hwdep_new(card, device)) < 0 || +- (err = snd_card_register(card)) < 0) { +- snd_card_free(card); +- return err; +- } ++ err = usx2y_hwdep_new(card, device); ++ if (err < 0) ++ goto error; ++ err = snd_card_register(card); ++ if (err < 0) ++ goto error; + *cardp = card; + return 0; ++ ++ error: ++ snd_card_free(card); ++ return err; + } + + /* +@@ -406,7 +413,7 @@ static int snd_usx2y_probe(struct usb_interface *intf, const struct usb_device_i + static void snd_usx2y_disconnect(struct usb_interface *intf) + { + usx2y_usb_disconnect(interface_to_usbdev(intf), +- usb_get_intfdata(intf)); ++ usb_get_intfdata(intf)); + } + + static struct usb_driver snd_usx2y_usb_driver = { +@@ -418,13 +425,15 @@ static struct usb_driver snd_usx2y_usb_driver = { + + static void snd_usx2y_card_private_free(struct snd_card *card) + { +- kfree(usx2y(card)->in04_buf); +- usb_free_urb(usx2y(card)->in04_urb); +- if (usx2y(card)->us428ctls_sharedmem) +- free_pages_exact(usx2y(card)->us428ctls_sharedmem, +- sizeof(*usx2y(card)->us428ctls_sharedmem)); +- if (usx2y(card)->card_index >= 0 && usx2y(card)->card_index < SNDRV_CARDS) +- snd_usx2y_card_used[usx2y(card)->card_index] = 0; ++ struct usx2ydev *usx2y = usx2y(card); ++ ++ kfree(usx2y->in04_buf); ++ usb_free_urb(usx2y->in04_urb); ++ if (usx2y->us428ctls_sharedmem) ++ free_pages_exact(usx2y->us428ctls_sharedmem, ++ sizeof(*usx2y->us428ctls_sharedmem)); ++ if (usx2y->card_index >= 0 && usx2y->card_index < SNDRV_CARDS) ++ snd_usx2y_card_used[usx2y->card_index] = 0; + } + + /* +@@ -432,23 +441,26 @@ static void snd_usx2y_card_private_free(struct snd_card *card) + */ + static void usx2y_usb_disconnect(struct usb_device *device, void *ptr) + { +- if (ptr) { +- struct snd_card *card = ptr; +- struct usx2ydev *usx2y = usx2y(card); +- struct list_head *p; +- +- usx2y->chip_status = USX2Y_STAT_CHIP_HUP; +- usx2y_unlinkseq(&usx2y->as04); +- usb_kill_urb(usx2y->in04_urb); +- snd_card_disconnect(card); +- /* release the midi resources */ +- list_for_each(p, &usx2y->midi_list) { +- snd_usbmidi_disconnect(p); +- } +- if (usx2y->us428ctls_sharedmem) +- wake_up(&usx2y->us428ctls_wait_queue_head); +- snd_card_free(card); ++ struct snd_card *card; ++ struct usx2ydev *usx2y; ++ struct list_head *p; ++ ++ if (!ptr) ++ return; ++ card = ptr; ++ usx2y = usx2y(card); ++ usx2y->chip_status = USX2Y_STAT_CHIP_HUP; ++ usx2y_unlinkseq(&usx2y->as04); ++ usb_kill_urb(usx2y->in04_urb); ++ snd_card_disconnect(card); ++ ++ /* release the midi resources */ ++ list_for_each(p, &usx2y->midi_list) { ++ snd_usbmidi_disconnect(p); + } ++ if (usx2y->us428ctls_sharedmem) ++ wake_up(&usx2y->us428ctls_wait_queue_head); ++ snd_card_free(card); + } + + module_usb_driver(snd_usx2y_usb_driver); +diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h +index 5ad6e3767621c..6d0e97a07bb8d 100644 +--- a/sound/usb/usx2y/usbusx2y.h ++++ b/sound/usb/usx2y/usbusx2y.h +@@ -30,7 +30,7 @@ struct usx2ydev { + struct urb *in04_urb; + void *in04_buf; + char in04_last[24]; +- unsigned in04_int_calls; ++ unsigned int in04_int_calls; + struct snd_usx2y_urb_seq *us04; + wait_queue_head_t in04_wait_queue; + struct snd_usx2y_async_seq as04; +diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c +index f92a9d52ea332..a2eeca9548f1c 100644 +--- a/sound/usb/usx2y/usbusx2yaudio.c ++++ b/sound/usb/usx2y/usbusx2yaudio.c +@@ -61,6 +61,7 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; + unsigned char *cp; + int i, len, lens = 0, hwptr_done = subs->hwptr_done; ++ int cnt, blen; + struct usx2ydev *usx2y = subs->usx2y; + + for (i = 0; i < nr_of_packs(); i++) { +@@ -79,9 +80,8 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + + /* copy a data chunk */ + if ((hwptr_done + len) > runtime->buffer_size) { +- int cnt = runtime->buffer_size - hwptr_done; +- int blen = cnt * usx2y->stride; +- ++ cnt = runtime->buffer_size - hwptr_done; ++ blen = cnt * usx2y->stride; + memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp, blen); + memcpy(runtime->dma_area, cp + blen, len * usx2y->stride - blen); + } else { +@@ -89,7 +89,8 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + len * usx2y->stride); + } + lens += len; +- if ((hwptr_done += len) >= runtime->buffer_size) ++ hwptr_done += len; ++ if (hwptr_done >= runtime->buffer_size) + hwptr_done -= runtime->buffer_size; + } + +@@ -117,9 +118,9 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs, + struct urb *cap_urb, + struct urb *urb) + { +- int count, counts, pack; + struct usx2ydev *usx2y = subs->usx2y; + struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; ++ int count, counts, pack, len; + + count = 0; + for (pack = 0; pack < nr_of_packs(); pack++) { +@@ -137,13 +138,11 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs, + 0; + urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length; + } +- if (atomic_read(&subs->state) >= STATE_PRERUNNING) ++ if (atomic_read(&subs->state) >= STATE_PRERUNNING) { + if (subs->hwptr + count > runtime->buffer_size) { + /* err, the transferred area goes over buffer boundary. + * copy the data to the temp buffer. + */ +- int len; +- + len = runtime->buffer_size - subs->hwptr; + urb->transfer_buffer = subs->tmpbuf; + memcpy(subs->tmpbuf, runtime->dma_area + +@@ -155,11 +154,13 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs, + } else { + /* set the buffer pointer */ + urb->transfer_buffer = runtime->dma_area + subs->hwptr * usx2y->stride; +- if ((subs->hwptr += count) >= runtime->buffer_size) ++ subs->hwptr += count; ++ if (subs->hwptr >= runtime->buffer_size) + subs->hwptr -= runtime->buffer_size; + } +- else ++ } else { + urb->transfer_buffer = subs->tmpbuf; ++ } + urb->transfer_buffer_length = count * usx2y->stride; + return 0; + } +@@ -190,25 +191,26 @@ static int usx2y_urb_submit(struct snd_usx2y_substream *subs, struct urb *urb, i + + if (!urb) + return -ENODEV; +- urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks ++ urb->start_frame = frame + NRURBS * nr_of_packs(); // let hcd do rollover sanity checks + urb->hcpriv = NULL; + urb->dev = subs->usx2y->dev; /* we need to set this at each time */ +- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { ++ err = usb_submit_urb(urb, GFP_ATOMIC); ++ if (err < 0) { + snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err); + return err; + } + return 0; + } + +-static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs, +- struct snd_usx2y_substream *playbacksubs, +- int frame) ++static int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs, ++ struct snd_usx2y_substream *playbacksubs, ++ int frame) + { + int err, state; + struct urb *urb = playbacksubs->completed_urb; + + state = atomic_read(&playbacksubs->state); +- if (NULL != urb) { ++ if (urb) { + if (state == STATE_RUNNING) + usx2y_urb_play_retire(playbacksubs, urb); + else if (state >= STATE_PRERUNNING) +@@ -226,10 +228,12 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs, + } + } + if (urb) { +- if ((err = usx2y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) || +- (err = usx2y_urb_submit(playbacksubs, urb, frame))) { ++ err = usx2y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb); ++ if (err) ++ return err; ++ err = usx2y_urb_submit(playbacksubs, urb, frame); ++ if (err) + return err; +- } + } + + playbacksubs->completed_urb = NULL; +@@ -237,11 +241,14 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs, + state = atomic_read(&capsubs->state); + if (state >= STATE_PREPARED) { + if (state == STATE_RUNNING) { +- if ((err = usx2y_urb_capt_retire(capsubs))) ++ err = usx2y_urb_capt_retire(capsubs); ++ if (err) + return err; +- } else if (state >= STATE_PRERUNNING) ++ } else if (state >= STATE_PRERUNNING) { + atomic_inc(&capsubs->state); +- if ((err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame))) ++ } ++ err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame); ++ if (err) + return err; + } + capsubs->completed_urb = NULL; +@@ -250,26 +257,25 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs, + + static void usx2y_clients_stop(struct usx2ydev *usx2y) + { ++ struct snd_usx2y_substream *subs; ++ struct urb *urb; + int s, u; + + for (s = 0; s < 4; s++) { +- struct snd_usx2y_substream *subs = usx2y->subs[s]; +- ++ subs = usx2y->subs[s]; + if (subs) { + snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state)); + atomic_set(&subs->state, STATE_STOPPED); + } + } + for (s = 0; s < 4; s++) { +- struct snd_usx2y_substream *subs = usx2y->subs[s]; +- ++ subs = usx2y->subs[s]; + if (subs) { + if (atomic_read(&subs->state) >= STATE_PRERUNNING) + snd_pcm_stop_xrun(subs->pcm_substream); + for (u = 0; u < NRURBS; u++) { +- struct urb *urb = subs->urb[u]; +- +- if (NULL != urb) ++ urb = subs->urb[u]; ++ if (urb) + snd_printdd("%i status=%i start_frame=%i\n", + u, urb->status, urb->start_frame); + } +@@ -291,6 +297,7 @@ static void i_usx2y_urb_complete(struct urb *urb) + { + struct snd_usx2y_substream *subs = urb->context; + struct usx2ydev *usx2y = subs->usx2y; ++ struct snd_usx2y_substream *capsubs, *playbacksubs; + + if (unlikely(atomic_read(&subs->state) < STATE_PREPARED)) { + snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", +@@ -306,20 +313,18 @@ static void i_usx2y_urb_complete(struct urb *urb) + + subs->completed_urb = urb; + +- { +- struct snd_usx2y_substream *capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE], +- *playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; +- +- if (capsubs->completed_urb && +- atomic_read(&capsubs->state) >= STATE_PREPARED && +- (playbacksubs->completed_urb || +- atomic_read(&playbacksubs->state) < STATE_PREPARED)) { +- if (!usx2y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) +- usx2y->wait_iso_frame += nr_of_packs(); +- else { +- snd_printdd("\n"); +- usx2y_clients_stop(usx2y); +- } ++ capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; ++ playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; ++ ++ if (capsubs->completed_urb && ++ atomic_read(&capsubs->state) >= STATE_PREPARED && ++ (playbacksubs->completed_urb || ++ atomic_read(&playbacksubs->state) < STATE_PREPARED)) { ++ if (!usx2y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) { ++ usx2y->wait_iso_frame += nr_of_packs(); ++ } else { ++ snd_printdd("\n"); ++ usx2y_clients_stop(usx2y); + } + } + } +@@ -327,18 +332,19 @@ static void i_usx2y_urb_complete(struct urb *urb) + static void usx2y_urbs_set_complete(struct usx2ydev *usx2y, + void (*complete)(struct urb *)) + { ++ struct snd_usx2y_substream *subs; ++ struct urb *urb; + int s, u; + + for (s = 0; s < 4; s++) { +- struct snd_usx2y_substream *subs = usx2y->subs[s]; +- +- if (NULL != subs) ++ subs = usx2y->subs[s]; ++ if (subs) { + for (u = 0; u < NRURBS; u++) { +- struct urb *urb = subs->urb[u]; +- +- if (NULL != urb) ++ urb = subs->urb[u]; ++ if (urb) + urb->complete = complete; + } ++ } + } + } + +@@ -354,12 +360,13 @@ static void i_usx2y_subs_startup(struct urb *urb) + struct usx2ydev *usx2y = subs->usx2y; + struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs; + +- if (NULL != prepare_subs) ++ if (prepare_subs) { + if (urb->start_frame == prepare_subs->urb[0]->start_frame) { + usx2y_subs_startup_finish(usx2y); + atomic_inc(&prepare_subs->state); + wake_up(&usx2y->prepare_wait_queue); + } ++ } + + i_usx2y_urb_complete(urb); + } +@@ -392,7 +399,7 @@ static void usx2y_urbs_release(struct snd_usx2y_substream *subs) + { + int i; + +- snd_printdd("usx2y_urbs_release() %i\n", subs->endpoint); ++ snd_printdd("%s %i\n", __func__, subs->endpoint); + for (i = 0; i < NRURBS; i++) + usx2y_urb_release(subs->urb + i, + subs != subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]); +@@ -410,6 +417,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs) + unsigned int pipe; + int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + struct usb_device *dev = subs->usx2y->dev; ++ struct urb **purb; + + pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) : + usb_rcvisocpipe(dev, subs->endpoint); +@@ -417,21 +425,20 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs) + if (!subs->maxpacksize) + return -EINVAL; + +- if (is_playback && NULL == subs->tmpbuf) { /* allocate a temporary buffer for playback */ ++ if (is_playback && !subs->tmpbuf) { /* allocate a temporary buffer for playback */ + subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL); + if (!subs->tmpbuf) + return -ENOMEM; + } + /* allocate and initialize data urbs */ + for (i = 0; i < NRURBS; i++) { +- struct urb **purb = subs->urb + i; +- ++ purb = subs->urb + i; + if (*purb) { + usb_kill_urb(*purb); + continue; + } + *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL); +- if (NULL == *purb) { ++ if (!*purb) { + usx2y_urbs_release(subs); + return -ENOMEM; + } +@@ -440,7 +447,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs) + (*purb)->transfer_buffer = + kmalloc_array(subs->maxpacksize, + nr_of_packs(), GFP_KERNEL); +- if (NULL == (*purb)->transfer_buffer) { ++ if (!(*purb)->transfer_buffer) { + usx2y_urbs_release(subs); + return -ENOMEM; + } +@@ -469,26 +476,26 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + { + int i, err; + struct usx2ydev *usx2y = subs->usx2y; ++ struct urb *urb; ++ unsigned long pack; + +- if ((err = usx2y_urbs_allocate(subs)) < 0) ++ err = usx2y_urbs_allocate(subs); ++ if (err < 0) + return err; + subs->completed_urb = NULL; + for (i = 0; i < 4; i++) { + struct snd_usx2y_substream *subs = usx2y->subs[i]; + +- if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED) ++ if (subs && atomic_read(&subs->state) >= STATE_PREPARED) + goto start; + } + + start: + usx2y_subs_startup(subs); + for (i = 0; i < NRURBS; i++) { +- struct urb *urb = subs->urb[i]; +- ++ urb = subs->urb[i]; + if (usb_pipein(urb->pipe)) { +- unsigned long pack; +- +- if (0 == i) ++ if (!i) + atomic_set(&subs->state, STATE_STARTING3); + urb->dev = usx2y->dev; + for (pack = 0; pack < nr_of_packs(); pack++) { +@@ -496,13 +503,15 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + urb->iso_frame_desc[pack].length = subs->maxpacksize; + } + urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); +- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { ++ err = usb_submit_urb(urb, GFP_ATOMIC); ++ if (err < 0) { + snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); + err = -EPIPE; + goto cleanup; +- } else +- if (i == 0) ++ } else { ++ if (!i) + usx2y->wait_iso_frame = urb->start_frame; ++ } + urb->transfer_flags = 0; + } else { + atomic_set(&subs->state, STATE_STARTING1); +@@ -510,7 +519,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + } + } + err = 0; +- wait_event(usx2y->prepare_wait_queue, NULL == usx2y->prepare_subs); ++ wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs); + if (atomic_read(&subs->state) != STATE_PREPARED) + err = -EPIPE; + +@@ -541,7 +550,7 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd) + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: +- snd_printdd("snd_usx2y_pcm_trigger(START)\n"); ++ snd_printdd("%s(START)\n", __func__); + if (atomic_read(&subs->state) == STATE_PREPARED && + atomic_read(&subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= STATE_PREPARED) { + atomic_set(&subs->state, STATE_PRERUNNING); +@@ -551,7 +560,7 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd) + } + break; + case SNDRV_PCM_TRIGGER_STOP: +- snd_printdd("snd_usx2y_pcm_trigger(STOP)\n"); ++ snd_printdd("%s(STOP)\n", __func__); + if (atomic_read(&subs->state) >= STATE_PRERUNNING) + atomic_set(&subs->state, STATE_PREPARED); + break; +@@ -569,11 +578,11 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd) + * if sg buffer is supported on the later version of alsa, we'll follow + * that. + */ +-static const struct s_c2 +-{ ++struct s_c2 { + char c1, c2; +-} +- setrate_44100[] = { ++}; ++ ++static const struct s_c2 setrate_44100[] = { + { 0x14, 0x08}, // this line sets 44100, well actually a little less + { 0x18, 0x40}, // only tascam / frontier design knows the further lines ....... + { 0x18, 0x42}, +@@ -653,7 +662,7 @@ static void i_usx2y_04int(struct urb *urb) + + if (urb->status) + snd_printk(KERN_ERR "snd_usx2y_04int() urb->status=%i\n", urb->status); +- if (0 == --usx2y->us04->len) ++ if (!--usx2y->us04->len) + wake_up(&usx2y->in04_wait_queue); + } + +@@ -663,21 +672,23 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + struct snd_usx2y_urb_seq *us = NULL; + int *usbdata = NULL; + const struct s_c2 *ra = rate == 48000 ? setrate_48000 : setrate_44100; ++ struct urb *urb; + + if (usx2y->rate != rate) { + us = kzalloc(sizeof(*us) + sizeof(struct urb *) * NOOF_SETRATE_URBS, GFP_KERNEL); +- if (NULL == us) { ++ if (!us) { + err = -ENOMEM; + goto cleanup; + } + usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int), + GFP_KERNEL); +- if (NULL == usbdata) { ++ if (!usbdata) { + err = -ENOMEM; + goto cleanup; + } + for (i = 0; i < NOOF_SETRATE_URBS; ++i) { +- if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) { ++ us->urb[i] = usb_alloc_urb(0, GFP_KERNEL); ++ if (!us->urb[i]) { + err = -ENOMEM; + goto cleanup; + } +@@ -692,7 +703,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + us->submitted = 0; + us->len = NOOF_SETRATE_URBS; + usx2y->us04 = us; +- wait_event_timeout(usx2y->in04_wait_queue, 0 == us->len, HZ); ++ wait_event_timeout(usx2y->in04_wait_queue, !us->len, HZ); + usx2y->us04 = NULL; + if (us->len) + err = -ENODEV; +@@ -700,8 +711,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + if (us) { + us->submitted = 2*NOOF_SETRATE_URBS; + for (i = 0; i < NOOF_SETRATE_URBS; ++i) { +- struct urb *urb = us->urb[i]; +- ++ urb = us->urb[i]; + if (!urb) + continue; + if (urb->status) { +@@ -722,7 +732,6 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + return err; + } + +- + static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format) + { + int alternate, err; +@@ -739,7 +748,8 @@ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format) + snd_usbmidi_input_stop(p); + } + usb_kill_urb(usx2y->in04_urb); +- if ((err = usb_set_interface(usx2y->dev, 0, alternate))) { ++ err = usb_set_interface(usx2y->dev, 0, alternate); ++ if (err) { + snd_printk(KERN_ERR "usb_set_interface error\n"); + return err; + } +@@ -762,6 +772,8 @@ static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream, + snd_pcm_format_t format = params_format(hw_params); + struct snd_card *card = substream->pstr->pcm->card; + struct usx2ydev *dev = usx2y(card); ++ struct snd_usx2y_substream *subs; ++ struct snd_pcm_substream *test_substream; + int i; + + mutex_lock(&usx2y(card)->pcm_mutex); +@@ -770,9 +782,7 @@ static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream, + * rate & format + */ + for (i = 0; i < dev->pcm_devs * 2; i++) { +- struct snd_usx2y_substream *subs = dev->subs[i]; +- struct snd_pcm_substream *test_substream; +- ++ subs = dev->subs[i]; + if (!subs) + continue; + test_substream = subs->pcm_substream; +@@ -800,13 +810,13 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_usx2y_substream *subs = runtime->private_data; ++ struct snd_usx2y_substream *cap_subs, *playback_subs; + + mutex_lock(&subs->usx2y->pcm_mutex); + snd_printdd("snd_usx2y_hw_free(%p)\n", substream); + +- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { +- struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; +- ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; + atomic_set(&subs->state, STATE_STOPPED); + usx2y_urbs_release(subs); + if (!cap_subs->pcm_substream || +@@ -817,8 +827,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream) + usx2y_urbs_release(cap_subs); + } + } else { +- struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; +- ++ playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + if (atomic_read(&playback_subs->state) < STATE_PREPARED) { + atomic_set(&subs->state, STATE_STOPPED); + usx2y_urbs_release(subs); +@@ -841,21 +850,26 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream) + struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; + int err = 0; + +- snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream); ++ snd_printdd("%s(%p)\n", __func__, substream); + + mutex_lock(&usx2y->pcm_mutex); + usx2y_subs_prepare(subs); + // Start hardware streams + // SyncStream first.... + if (atomic_read(&capsubs->state) < STATE_PREPARED) { +- if (usx2y->format != runtime->format) +- if ((err = usx2y_format_set(usx2y, runtime->format)) < 0) ++ if (usx2y->format != runtime->format) { ++ err = usx2y_format_set(usx2y, runtime->format); ++ if (err < 0) + goto up_prepare_mutex; +- if (usx2y->rate != runtime->rate) +- if ((err = usx2y_rate_set(usx2y, runtime->rate)) < 0) ++ } ++ if (usx2y->rate != runtime->rate) { ++ err = usx2y_rate_set(usx2y, runtime->rate); ++ if (err < 0) + goto up_prepare_mutex; ++ } + snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe"); +- if (0 > (err = usx2y_urbs_start(capsubs))) ++ err = usx2y_urbs_start(capsubs); ++ if (err < 0) + goto up_prepare_mutex; + } + +@@ -888,8 +902,9 @@ static const struct snd_pcm_hardware snd_usx2y_2c = { + + static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream) + { +- struct snd_usx2y_substream *subs = ((struct snd_usx2y_substream **) +- snd_pcm_substream_chip(substream))[substream->stream]; ++ struct snd_usx2y_substream *subs = ++ ((struct snd_usx2y_substream **) ++ snd_pcm_substream_chip(substream))[substream->stream]; + struct snd_pcm_runtime *runtime = substream->runtime; + + if (subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS) +@@ -1006,11 +1021,14 @@ int usx2y_audio_create(struct snd_card *card) + + INIT_LIST_HEAD(&usx2y(card)->pcm_list); + +- if (0 > (err = usx2y_audio_stream_new(card, 0xA, 0x8))) ++ err = usx2y_audio_stream_new(card, 0xA, 0x8); ++ if (err < 0) + return err; +- if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428) +- if (0 > (err = usx2y_audio_stream_new(card, 0, 0xA))) ++ if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428) { ++ err = usx2y_audio_stream_new(card, 0, 0xA); ++ if (err < 0) + return err; ++ } + if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) != USB_ID_US122) + err = usx2y_rate_set(usx2y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122. + return err; +diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c +index b7e15fc3d1b48..9219341d71c79 100644 +--- a/sound/usb/usx2y/usx2yhwdeppcm.c ++++ b/sound/usb/usx2y/usx2yhwdeppcm.c +@@ -52,10 +52,10 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs) + struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; + int i, lens = 0, hwptr_done = subs->hwptr_done; + struct usx2ydev *usx2y = subs->usx2y; ++ int head; + +- if (0 > usx2y->hwdep_pcm_shm->capture_iso_start) { //FIXME +- int head = usx2y->hwdep_pcm_shm->captured_iso_head + 1; +- ++ if (usx2y->hwdep_pcm_shm->capture_iso_start < 0) { //FIXME ++ head = usx2y->hwdep_pcm_shm->captured_iso_head + 1; + if (head >= ARRAY_SIZE(usx2y->hwdep_pcm_shm->captured_iso)) + head = 0; + usx2y->hwdep_pcm_shm->capture_iso_start = head; +@@ -70,7 +70,8 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs) + } + lens += urb->iso_frame_desc[i].actual_length / usx2y->stride; + } +- if ((hwptr_done += lens) >= runtime->buffer_size) ++ hwptr_done += lens; ++ if (hwptr_done >= runtime->buffer_size) + hwptr_done -= runtime->buffer_size; + subs->hwptr_done = hwptr_done; + subs->transfer_done += lens; +@@ -82,7 +83,7 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs) + return 0; + } + +-static inline int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime, ++static int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime, + struct usx2ydev *usx2y) + { + return (runtime->buffer_size * 1000) / usx2y->rate + 1; //FIXME: so far only correct period_size == 2^x ? +@@ -106,10 +107,10 @@ static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs, + struct snd_usx2y_hwdep_pcm_shm *shm = usx2y->hwdep_pcm_shm; + struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; + +- if (0 > shm->playback_iso_start) { ++ if (shm->playback_iso_start < 0) { + shm->playback_iso_start = shm->captured_iso_head - + usx2y_iso_frames_per_buffer(runtime, usx2y); +- if (0 > shm->playback_iso_start) ++ if (shm->playback_iso_start < 0) + shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso); + shm->playback_iso_head = shm->playback_iso_start; + } +@@ -136,18 +137,18 @@ static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs, + return 0; + } + +-static inline void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs, +- struct urb *urb) ++static void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs, ++ struct urb *urb) + { +- int pack; ++ struct usb_iso_packet_descriptor *desc; ++ struct snd_usx2y_hwdep_pcm_shm *shm; ++ int pack, head; + + for (pack = 0; pack < nr_of_packs(); ++pack) { +- struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack; +- +- if (NULL != subs) { +- struct snd_usx2y_hwdep_pcm_shm *shm = subs->usx2y->hwdep_pcm_shm; +- int head = shm->captured_iso_head + 1; +- ++ desc = urb->iso_frame_desc + pack; ++ if (subs) { ++ shm = subs->usx2y->hwdep_pcm_shm; ++ head = shm->captured_iso_head + 1; + if (head >= ARRAY_SIZE(shm->captured_iso)) + head = 0; + shm->captured_iso[head].frame = urb->start_frame + pack; +@@ -156,22 +157,22 @@ static inline void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream + shm->captured_iso_head = head; + shm->captured_iso_frames++; + } +- if ((desc->offset += desc->length * NRURBS*nr_of_packs()) + +- desc->length >= SSS) ++ desc->offset += desc->length * NRURBS * nr_of_packs(); ++ if (desc->offset + desc->length >= SSS) + desc->offset -= (SSS - desc->length); + } + } + +-static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *capsubs, +- struct snd_usx2y_substream *capsubs2, +- struct snd_usx2y_substream *playbacksubs, +- int frame) ++static int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *capsubs, ++ struct snd_usx2y_substream *capsubs2, ++ struct snd_usx2y_substream *playbacksubs, ++ int frame) + { + int err, state; + struct urb *urb = playbacksubs->completed_urb; + + state = atomic_read(&playbacksubs->state); +- if (NULL != urb) { ++ if (urb) { + if (state == STATE_RUNNING) + usx2y_urb_play_retire(playbacksubs, urb); + else if (state >= STATE_PRERUNNING) +@@ -189,10 +190,12 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap + } + } + if (urb) { +- if ((err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb)) || +- (err = usx2y_urb_submit(playbacksubs, urb, frame))) { ++ err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb); ++ if (err) ++ return err; ++ err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb); ++ if (err) + return err; +- } + } + + playbacksubs->completed_urb = NULL; +@@ -200,21 +203,26 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap + state = atomic_read(&capsubs->state); + if (state >= STATE_PREPARED) { + if (state == STATE_RUNNING) { +- if ((err = usx2y_usbpcm_urb_capt_retire(capsubs))) ++ err = usx2y_usbpcm_urb_capt_retire(capsubs); ++ if (err) + return err; +- } else if (state >= STATE_PRERUNNING) ++ } else if (state >= STATE_PRERUNNING) { + atomic_inc(&capsubs->state); ++ } + usx2y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb); +- if (NULL != capsubs2) ++ if (capsubs2) + usx2y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb); +- if ((err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame))) ++ err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame); ++ if (err) + return err; +- if (NULL != capsubs2) +- if ((err = usx2y_urb_submit(capsubs2, capsubs2->completed_urb, frame))) ++ if (capsubs2) { ++ err = usx2y_urb_submit(capsubs2, capsubs2->completed_urb, frame); ++ if (err) + return err; ++ } + } + capsubs->completed_urb = NULL; +- if (NULL != capsubs2) ++ if (capsubs2) + capsubs2->completed_urb = NULL; + return 0; + } +@@ -242,11 +250,11 @@ static void i_usx2y_usbpcm_urb_complete(struct urb *urb) + capsubs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; + playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + if (capsubs->completed_urb && atomic_read(&capsubs->state) >= STATE_PREPARED && +- (NULL == capsubs2 || capsubs2->completed_urb) && ++ (!capsubs2 || capsubs2->completed_urb) && + (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < STATE_PREPARED)) { +- if (!usx2y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) ++ if (!usx2y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) { + usx2y->wait_iso_frame += nr_of_packs(); +- else { ++ } else { + snd_printdd("\n"); + usx2y_clients_stop(usx2y); + } +@@ -283,14 +291,14 @@ static void i_usx2y_usbpcm_subs_startup(struct urb *urb) + struct snd_usx2y_substream *subs = urb->context; + struct usx2ydev *usx2y = subs->usx2y; + struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs; ++ struct snd_usx2y_substream *cap_subs2; + +- if (NULL != prepare_subs && ++ if (prepare_subs && + urb->start_frame == prepare_subs->urb[0]->start_frame) { + atomic_inc(&prepare_subs->state); + if (prepare_subs == usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]) { +- struct snd_usx2y_substream *cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; +- +- if (cap_subs2 != NULL) ++ cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; ++ if (cap_subs2) + atomic_inc(&cap_subs2->state); + } + usx2y_usbpcm_subs_startup_finish(usx2y); +@@ -309,6 +317,7 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs) + unsigned int pipe; + int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + struct usb_device *dev = subs->usx2y->dev; ++ struct urb **purb; + + pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) : + usb_rcvisocpipe(dev, subs->endpoint); +@@ -318,14 +327,13 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs) + + /* allocate and initialize data urbs */ + for (i = 0; i < NRURBS; i++) { +- struct urb **purb = subs->urb + i; +- ++ purb = subs->urb + i; + if (*purb) { + usb_kill_urb(*purb); + continue; + } + *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL); +- if (NULL == *purb) { ++ if (!*purb) { + usx2y_usbpcm_urbs_release(subs); + return -ENOMEM; + } +@@ -351,15 +359,17 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs) + static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; +- struct snd_usx2y_substream *subs = runtime->private_data, +- *cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; ++ struct snd_usx2y_substream *subs = runtime->private_data; ++ struct snd_usx2y_substream *cap_subs; ++ struct snd_usx2y_substream *playback_subs; ++ struct snd_usx2y_substream *cap_subs2; + + mutex_lock(&subs->usx2y->pcm_mutex); +- snd_printdd("snd_usx2y_usbpcm_hw_free(%p)\n", substream); +- +- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { +- struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; ++ snd_printdd("%s(%p)\n", __func__, substream); + ++ cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; + atomic_set(&subs->state, STATE_STOPPED); + usx2y_usbpcm_urbs_release(subs); + if (!cap_subs->pcm_substream || +@@ -367,21 +377,20 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream) + !cap_subs->pcm_substream->runtime->status || + cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) { + atomic_set(&cap_subs->state, STATE_STOPPED); +- if (NULL != cap_subs2) ++ if (cap_subs2) + atomic_set(&cap_subs2->state, STATE_STOPPED); + usx2y_usbpcm_urbs_release(cap_subs); +- if (NULL != cap_subs2) ++ if (cap_subs2) + usx2y_usbpcm_urbs_release(cap_subs2); + } + } else { +- struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; +- ++ playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; + if (atomic_read(&playback_subs->state) < STATE_PREPARED) { + atomic_set(&subs->state, STATE_STOPPED); +- if (NULL != cap_subs2) ++ if (cap_subs2) + atomic_set(&cap_subs2->state, STATE_STOPPED); + usx2y_usbpcm_urbs_release(subs); +- if (NULL != cap_subs2) ++ if (cap_subs2) + usx2y_usbpcm_urbs_release(cap_subs2); + } + } +@@ -403,16 +412,19 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + { + int p, u, err, stream = subs->pcm_substream->stream; + struct usx2ydev *usx2y = subs->usx2y; ++ struct urb *urb; ++ unsigned long pack; + +- if (SNDRV_PCM_STREAM_CAPTURE == stream) { ++ if (stream == SNDRV_PCM_STREAM_CAPTURE) { + usx2y->hwdep_pcm_shm->captured_iso_head = -1; + usx2y->hwdep_pcm_shm->captured_iso_frames = 0; + } + + for (p = 0; 3 >= (stream + p); p += 2) { + struct snd_usx2y_substream *subs = usx2y->subs[stream + p]; +- if (subs != NULL) { +- if ((err = usx2y_usbpcm_urbs_allocate(subs)) < 0) ++ if (subs) { ++ err = usx2y_usbpcm_urbs_allocate(subs); ++ if (err < 0) + return err; + subs->completed_urb = NULL; + } +@@ -421,7 +433,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + for (p = 0; p < 4; p++) { + struct snd_usx2y_substream *subs = usx2y->subs[p]; + +- if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED) ++ if (subs && atomic_read(&subs->state) >= STATE_PREPARED) + goto start; + } + +@@ -431,39 +443,37 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + for (p = 0; 3 >= (stream + p); p += 2) { + struct snd_usx2y_substream *subs = usx2y->subs[stream + p]; + +- if (subs != NULL) { +- struct urb *urb = subs->urb[u]; +- +- if (usb_pipein(urb->pipe)) { +- unsigned long pack; +- +- if (0 == u) +- atomic_set(&subs->state, STATE_STARTING3); +- urb->dev = usx2y->dev; +- for (pack = 0; pack < nr_of_packs(); pack++) { +- urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); +- urb->iso_frame_desc[pack].length = subs->maxpacksize; +- } +- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); +- if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) { +- snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err); +- err = -EPIPE; +- goto cleanup; +- } else { +- snd_printdd("%i\n", urb->start_frame); +- if (u == 0) +- usx2y->wait_iso_frame = urb->start_frame; +- } +- urb->transfer_flags = 0; +- } else { +- atomic_set(&subs->state, STATE_STARTING1); +- break; ++ if (!subs) ++ continue; ++ urb = subs->urb[u]; ++ if (usb_pipein(urb->pipe)) { ++ if (!u) ++ atomic_set(&subs->state, STATE_STARTING3); ++ urb->dev = usx2y->dev; ++ for (pack = 0; pack < nr_of_packs(); pack++) { ++ urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); ++ urb->iso_frame_desc[pack].length = subs->maxpacksize; + } ++ urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); ++ err = usb_submit_urb(urb, GFP_KERNEL); ++ if (err < 0) { ++ snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err); ++ err = -EPIPE; ++ goto cleanup; ++ } else { ++ snd_printdd("%i\n", urb->start_frame); ++ if (!u) ++ usx2y->wait_iso_frame = urb->start_frame; ++ } ++ urb->transfer_flags = 0; ++ } else { ++ atomic_set(&subs->state, STATE_STARTING1); ++ break; + } + } + } + err = 0; +- wait_event(usx2y->prepare_wait_queue, NULL == usx2y->prepare_subs); ++ wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs); + if (atomic_read(&subs->state) != STATE_PREPARED) + err = -EPIPE; + +@@ -490,7 +500,7 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + + snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream); + +- if (NULL == usx2y->hwdep_pcm_shm) { ++ if (!usx2y->hwdep_pcm_shm) { + usx2y->hwdep_pcm_shm = alloc_pages_exact(sizeof(struct snd_usx2y_hwdep_pcm_shm), + GFP_KERNEL); + if (!usx2y->hwdep_pcm_shm) +@@ -503,15 +513,20 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + // Start hardware streams + // SyncStream first.... + if (atomic_read(&capsubs->state) < STATE_PREPARED) { +- if (usx2y->format != runtime->format) +- if ((err = usx2y_format_set(usx2y, runtime->format)) < 0) ++ if (usx2y->format != runtime->format) { ++ err = usx2y_format_set(usx2y, runtime->format); ++ if (err < 0) + goto up_prepare_mutex; +- if (usx2y->rate != runtime->rate) +- if ((err = usx2y_rate_set(usx2y, runtime->rate)) < 0) ++ } ++ if (usx2y->rate != runtime->rate) { ++ err = usx2y_rate_set(usx2y, runtime->rate); ++ if (err < 0) + goto up_prepare_mutex; ++ } + snd_printdd("starting capture pipe for %s\n", subs == capsubs ? + "self" : "playpipe"); +- if (0 > (err = usx2y_usbpcm_urbs_start(capsubs))) ++ err = usx2y_usbpcm_urbs_start(capsubs); ++ if (err < 0) + goto up_prepare_mutex; + } + +@@ -528,14 +543,16 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + goto up_prepare_mutex; + } + } +- if (0 > (err = usx2y_usbpcm_urbs_start(subs))) ++ err = usx2y_usbpcm_urbs_start(subs); ++ if (err < 0) + goto up_prepare_mutex; + } + snd_printdd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", + usx2y_iso_frames_per_buffer(runtime, usx2y), + usx2y->hwdep_pcm_shm->captured_iso_frames); +- } else ++ } else { + usx2y->hwdep_pcm_shm->capture_iso_start = -1; ++ } + + up_prepare_mutex: + mutex_unlock(&usx2y->pcm_mutex); +@@ -562,15 +579,18 @@ static const struct snd_pcm_hardware snd_usx2y_4c = { + + static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream) + { +- struct snd_usx2y_substream *subs = ((struct snd_usx2y_substream **) +- snd_pcm_substream_chip(substream))[substream->stream]; ++ struct snd_usx2y_substream *subs = ++ ((struct snd_usx2y_substream **) ++ snd_pcm_substream_chip(substream))[substream->stream]; + struct snd_pcm_runtime *runtime = substream->runtime; + + if (!(subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)) + return -EBUSY; + +- runtime->hw = SNDRV_PCM_STREAM_PLAYBACK == substream->stream ? snd_usx2y_2c : +- (subs->usx2y->subs[3] ? snd_usx2y_4c : snd_usx2y_2c); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ runtime->hw = snd_usx2y_2c; ++ else ++ runtime->hw = (subs->usx2y->subs[3] ? snd_usx2y_4c : snd_usx2y_2c); + runtime->private_data = subs; + subs->pcm_substream = substream; + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000); +@@ -599,11 +619,11 @@ static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = { + static int usx2y_pcms_busy_check(struct snd_card *card) + { + struct usx2ydev *dev = usx2y(card); ++ struct snd_usx2y_substream *subs; + int i; + + for (i = 0; i < dev->pcm_devs * 2; i++) { +- struct snd_usx2y_substream *subs = dev->subs[i]; +- ++ subs = dev->subs[i]; + if (subs && subs->pcm_substream && + SUBSTREAM_BUSY(subs->pcm_substream)) + return -EBUSY; +@@ -677,9 +697,9 @@ static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep *hw, struct file *filp, str + return -EINVAL; + } + +- if (!usx2y->hwdep_pcm_shm) { ++ if (!usx2y->hwdep_pcm_shm) + return -ENODEV; +- } ++ + area->vm_ops = &snd_usx2y_hwdep_pcm_vm_ops; + area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; + area->vm_private_data = hw->private_data; +@@ -690,7 +710,7 @@ static void snd_usx2y_hwdep_pcm_private_free(struct snd_hwdep *hwdep) + { + struct usx2ydev *usx2y = hwdep->private_data; + +- if (NULL != usx2y->hwdep_pcm_shm) ++ if (usx2y->hwdep_pcm_shm) + free_pages_exact(usx2y->hwdep_pcm_shm, sizeof(struct snd_usx2y_hwdep_pcm_shm)); + } + +@@ -701,10 +721,11 @@ int usx2y_hwdep_pcm_new(struct snd_card *card) + struct snd_pcm *pcm; + struct usb_device *dev = usx2y(card)->dev; + +- if (1 != nr_of_packs()) ++ if (nr_of_packs() != 1) + return 0; + +- if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0) ++ err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw); ++ if (err < 0) + return err; + + hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM; +@@ -717,9 +738,9 @@ int usx2y_hwdep_pcm_new(struct snd_card *card) + sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum); + + err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm); +- if (err < 0) { ++ if (err < 0) + return err; +- } ++ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usx2y_usbpcm_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usx2y_usbpcm_ops); + +-- +2.43.0 + diff --git a/queue-5.10/alsa-usx2y-fix-spaces.patch b/queue-5.10/alsa-usx2y-fix-spaces.patch new file mode 100644 index 00000000000..78d8b7010e7 --- /dev/null +++ b/queue-5.10/alsa-usx2y-fix-spaces.patch @@ -0,0 +1,1893 @@ +From 877527906fecc26a01520a937061ca7e0e7a3019 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 May 2021 15:15:36 +0200 +Subject: ALSA: usx2y: Fix spaces + +From: Takashi Iwai + +[ Upstream commit 4c0a58ef36f3de1be0d1c8565ca854bcabd37e2b ] + +This patch corrects merely the spaces in the usx2y code, including the +superfluous trailing space in the debug prints and a slight reformat +of some comment lines. Nothing really touches about the code itself. + +Link: https://lore.kernel.org/r/20210517131545.27252-3-tiwai@suse.de +Signed-off-by: Takashi Iwai +Stable-dep-of: dafb28f02be4 ("ALSA: usx2y: Use snd_card_free_when_closed() at disconnection") +Signed-off-by: Sasha Levin +--- + sound/usb/usx2y/us122l.c | 38 ++++---- + sound/usb/usx2y/usX2Yhwdep.c | 52 ++++++----- + sound/usb/usx2y/usX2Yhwdep.h | 2 +- + sound/usb/usx2y/usb_stream.c | 43 ++++++--- + sound/usb/usx2y/usbus428ctldefs.h | 18 ++-- + sound/usb/usx2y/usbusx2y.c | 78 ++++++++--------- + sound/usb/usx2y/usbusx2y.h | 6 +- + sound/usb/usx2y/usbusx2yaudio.c | 140 +++++++++++++++++------------- + sound/usb/usx2y/usx2yhwdeppcm.c | 90 +++++++++---------- + 9 files changed, 256 insertions(+), 211 deletions(-) + +diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c +index 6e1bfe894dd5d..53e7eb4480b30 100644 +--- a/sound/usb/usx2y/us122l.c ++++ b/sound/usb/usx2y/us122l.c +@@ -49,7 +49,7 @@ static int us122l_create_usbmidi(struct snd_card *card) + static const struct snd_usb_audio_quirk quirk = { + .vendor_name = "US122L", + .product_name = NAME_ALLCAPS, +- .ifnum = 1, ++ .ifnum = 1, + .type = QUIRK_MIDI_US122L, + .data = &quirk_data + }; +@@ -71,7 +71,7 @@ static int us144_create_usbmidi(struct snd_card *card) + static const struct snd_usb_audio_quirk quirk = { + .vendor_name = "US144", + .product_name = NAME_ALLCAPS, +- .ifnum = 0, ++ .ifnum = 0, + .type = QUIRK_MIDI_US122L, + .data = &quirk_data + }; +@@ -95,6 +95,7 @@ static void pt_info_set(struct usb_device *dev, u8 v) + static void usb_stream_hwdep_vm_open(struct vm_area_struct *area) + { + struct us122l *us122l = area->vm_private_data; ++ + atomic_inc(&us122l->mmap_count); + snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count)); + } +@@ -138,6 +139,7 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf) + static void usb_stream_hwdep_vm_close(struct vm_area_struct *area) + { + struct us122l *us122l = area->vm_private_data; ++ + atomic_dec(&us122l->mmap_count); + snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count)); + } +@@ -148,11 +150,11 @@ static const struct vm_operations_struct usb_stream_hwdep_vm_ops = { + .close = usb_stream_hwdep_vm_close, + }; + +- + static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file) + { + struct us122l *us122l = hw->private_data; + struct usb_interface *iface; ++ + snd_printdd(KERN_DEBUG "%p %p\n", hw, file); + if (hw->used >= 2) + return -EBUSY; +@@ -173,6 +175,7 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) + { + struct us122l *us122l = hw->private_data; + struct usb_interface *iface; ++ + snd_printdd(KERN_DEBUG "%p %p\n", hw, file); + + if (us122l->is_us144) { +@@ -243,6 +246,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw, + mask = EPOLLIN | EPOLLOUT | EPOLLWRNORM | EPOLLERR; + if (mutex_trylock(&us122l->mutex)) { + struct usb_stream *s = us122l->sk.s; ++ + if (s && s->state == usb_stream_ready) { + if (us122l->first == file) + polled = &s->periods_polled; +@@ -262,6 +266,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw, + static void us122l_stop(struct us122l *us122l) + { + struct list_head *p; ++ + list_for_each(p, &us122l->midi_list) + snd_usbmidi_input_stop(p); + +@@ -320,13 +325,13 @@ static bool us122l_start(struct us122l *us122l, + err = us122l_set_sample_rate(us122l->dev, rate); + if (err < 0) { + us122l_stop(us122l); +- snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); ++ snd_printk(KERN_ERR "us122l_set_sample_rate error\n"); + goto out; + } + err = usb_stream_start(&us122l->sk); + if (err < 0) { + us122l_stop(us122l); +- snd_printk(KERN_ERR "us122l_start error %i \n", err); ++ snd_printk(KERN_ERR "us122l_start error %i\n", err); + goto out; + } + list_for_each(p, &us122l->midi_list) +@@ -431,7 +436,6 @@ static int usb_stream_hwdep_new(struct snd_card *card) + return 0; + } + +- + static bool us122l_create_card(struct snd_card *card) + { + int err; +@@ -440,13 +444,13 @@ static bool us122l_create_card(struct snd_card *card) + if (us122l->is_us144) { + err = usb_set_interface(us122l->dev, 0, 1); + if (err) { +- snd_printk(KERN_ERR "usb_set_interface error \n"); ++ snd_printk(KERN_ERR "usb_set_interface error\n"); + return false; + } + } + err = usb_set_interface(us122l->dev, 1, 1); + if (err) { +- snd_printk(KERN_ERR "usb_set_interface error \n"); ++ snd_printk(KERN_ERR "usb_set_interface error\n"); + return false; + } + +@@ -461,13 +465,14 @@ static bool us122l_create_card(struct snd_card *card) + else + err = us122l_create_usbmidi(card); + if (err < 0) { +- snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err); ++ snd_printk(KERN_ERR "us122l_create_usbmidi error %i\n", err); + goto stop; + } + err = usb_stream_hwdep_new(card); + if (err < 0) { +-/* release the midi resources */ ++ /* release the midi resources */ + struct list_head *p; ++ + list_for_each(p, &us122l->midi_list) + snd_usbmidi_disconnect(p); + +@@ -484,6 +489,7 @@ static void snd_us122l_free(struct snd_card *card) + { + struct us122l *us122l = US122L(card); + int index = us122l->card_index; ++ + if (index >= 0 && index < SNDRV_CARDS) + snd_us122l_card_used[index] = 0; + } +@@ -565,7 +571,7 @@ static int snd_us122l_probe(struct usb_interface *intf, + + if (id->driver_info & US122L_FLAG_US144 && + device->speed == USB_SPEED_HIGH) { +- snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n"); ++ snd_printk(KERN_ERR "disable ehci-hcd to run US-144\n"); + return -ENODEV; + } + +@@ -601,7 +607,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf) + us122l_stop(us122l); + mutex_unlock(&us122l->mutex); + +-/* release the midi resources */ ++ /* release the midi resources */ + list_for_each(p, &us122l->midi_list) { + snd_usbmidi_disconnect(p); + } +@@ -661,13 +667,13 @@ static int snd_us122l_resume(struct usb_interface *intf) + if (us122l->is_us144) { + err = usb_set_interface(us122l->dev, 0, 1); + if (err) { +- snd_printk(KERN_ERR "usb_set_interface error \n"); ++ snd_printk(KERN_ERR "usb_set_interface error\n"); + goto unlock; + } + } + err = usb_set_interface(us122l->dev, 1, 1); + if (err) { +- snd_printk(KERN_ERR "usb_set_interface error \n"); ++ snd_printk(KERN_ERR "usb_set_interface error\n"); + goto unlock; + } + +@@ -677,7 +683,7 @@ static int snd_us122l_resume(struct usb_interface *intf) + err = us122l_set_sample_rate(us122l->dev, + us122l->sk.s->cfg.sample_rate); + if (err < 0) { +- snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); ++ snd_printk(KERN_ERR "us122l_set_sample_rate error\n"); + goto unlock; + } + err = usb_stream_start(&us122l->sk); +@@ -717,8 +723,8 @@ static const struct usb_device_id snd_us122l_usb_id_table[] = { + }, + { /* terminator */ } + }; +- + MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table); ++ + static struct usb_driver snd_us122l_usb_driver = { + .name = "snd-usb-us122l", + .probe = snd_us122l_probe, +diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c +index 10868c3fb6561..90246518dbddb 100644 +--- a/sound/usb/usx2y/usX2Yhwdep.c ++++ b/sound/usb/usx2y/usX2Yhwdep.c +@@ -21,13 +21,13 @@ + static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf) + { + unsigned long offset; +- struct page * page; ++ struct page *page; + void *vaddr; + + snd_printdd("ENTER, start %lXh, pgoff %ld\n", + vmf->vma->vm_start, + vmf->pgoff); +- ++ + offset = vmf->pgoff << PAGE_SHIFT; + vaddr = (char *)((struct usx2ydev *)vmf->vma->vm_private_data)->us428ctls_sharedmem + offset; + page = virt_to_page(vaddr); +@@ -44,20 +44,20 @@ static const struct vm_operations_struct us428ctls_vm_ops = { + .fault = snd_us428ctls_vm_fault, + }; + +-static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area) ++static int snd_us428ctls_mmap(struct snd_hwdep *hw, struct file *filp, struct vm_area_struct *area) + { + unsigned long size = (unsigned long)(area->vm_end - area->vm_start); + struct usx2ydev *us428 = hw->private_data; + + // FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs? + // so as long as the device isn't fully initialised yet we return -EBUSY here. +- if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT)) ++ if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT)) + return -EBUSY; + +- /* if userspace tries to mmap beyond end of our buffer, fail */ +- if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) { +- snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem)); +- return -EINVAL; ++ /* if userspace tries to mmap beyond end of our buffer, fail */ ++ if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) { ++ snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem)); ++ return -EINVAL; + } + + if (!us428->us428ctls_sharedmem) { +@@ -79,6 +79,7 @@ static __poll_t snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll + __poll_t mask = 0; + struct usx2ydev *us428 = hw->private_data; + struct us428ctls_sharedmem *shm = us428->us428ctls_sharedmem; ++ + if (us428->chip_status & USX2Y_STAT_CHIP_HUP) + return EPOLLHUP; + +@@ -123,7 +124,6 @@ static int snd_usx2y_hwdep_dsp_status(struct snd_hwdep *hw, + return 0; + } + +- + static int usx2y_create_usbmidi(struct snd_card *card) + { + static const struct snd_usb_midi_endpoint_info quirk_data_1 = { +@@ -135,8 +135,8 @@ static int usx2y_create_usbmidi(struct snd_card *card) + static const struct snd_usb_audio_quirk quirk_1 = { + .vendor_name = "TASCAM", + .product_name = NAME_ALLCAPS, +- .ifnum = 0, +- .type = QUIRK_MIDI_FIXED_ENDPOINT, ++ .ifnum = 0, ++ .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = &quirk_data_1 + }; + static const struct snd_usb_midi_endpoint_info quirk_data_2 = { +@@ -148,8 +148,8 @@ static int usx2y_create_usbmidi(struct snd_card *card) + static const struct snd_usb_audio_quirk quirk_2 = { + .vendor_name = "TASCAM", + .product_name = "US428", +- .ifnum = 0, +- .type = QUIRK_MIDI_FIXED_ENDPOINT, ++ .ifnum = 0, ++ .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = &quirk_data_2 + }; + struct usb_device *dev = usx2y(card)->dev; +@@ -158,7 +158,7 @@ static int usx2y_create_usbmidi(struct snd_card *card) + le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? + &quirk_2 : &quirk_1; + +- snd_printdd("usx2y_create_usbmidi \n"); ++ snd_printdd("usx2y_create_usbmidi\n"); + return snd_usbmidi_create(card, iface, &usx2y(card)->midi_list, quirk); + } + +@@ -168,10 +168,10 @@ static int usx2y_create_alsa_devices(struct snd_card *card) + + do { + if ((err = usx2y_create_usbmidi(card)) < 0) { +- snd_printk(KERN_ERR "usx2y_create_alsa_devices: usx2y_create_usbmidi error %i \n", err); ++ snd_printk(KERN_ERR "usx2y_create_alsa_devices: usx2y_create_usbmidi error %i\n", err); + break; + } +- if ((err = usx2y_audio_create(card)) < 0) ++ if ((err = usx2y_audio_create(card)) < 0) + break; + if ((err = usx2y_hwdep_pcm_new(card)) < 0) + break; +@@ -180,17 +180,17 @@ static int usx2y_create_alsa_devices(struct snd_card *card) + } while (0); + + return err; +-} ++} + + static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw, + struct snd_hwdep_dsp_image *dsp) + { + struct usx2ydev *priv = hw->private_data; +- struct usb_device* dev = priv->dev; ++ struct usb_device *dev = priv->dev; + int lret, err; + char *buf; + +- snd_printdd( "dsp_load %s\n", dsp->name); ++ snd_printdd("dsp_load %s\n", dsp->name); + + buf = memdup_user(dsp->image, dsp->length); + if (IS_ERR(buf)) +@@ -198,7 +198,7 @@ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw, + + err = usb_set_interface(dev, 0, 1); + if (err) +- snd_printk(KERN_ERR "usb_set_interface error \n"); ++ snd_printk(KERN_ERR "usb_set_interface error\n"); + else + err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000); + kfree(buf); +@@ -208,28 +208,27 @@ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw, + msleep(250); // give the device some time + err = usx2y_async_seq04_init(priv); + if (err) { +- snd_printk(KERN_ERR "usx2y_async_seq04_init error \n"); ++ snd_printk(KERN_ERR "usx2y_async_seq04_init error\n"); + return err; + } + err = usx2y_in04_init(priv); + if (err) { +- snd_printk(KERN_ERR "usx2y_in04_init error \n"); ++ snd_printk(KERN_ERR "usx2y_in04_init error\n"); + return err; + } + err = usx2y_create_alsa_devices(hw->card); + if (err) { +- snd_printk(KERN_ERR "usx2y_create_alsa_devices error %i \n", err); ++ snd_printk(KERN_ERR "usx2y_create_alsa_devices error %i\n", err); + snd_card_free(hw->card); + return err; + } +- priv->chip_status |= USX2Y_STAT_CHIP_INIT; ++ priv->chip_status |= USX2Y_STAT_CHIP_INIT; + snd_printdd("%s: alsa all started\n", hw->name); + } + return err; + } + +- +-int usx2y_hwdep_new(struct snd_card *card, struct usb_device* device) ++int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device) + { + int err; + struct snd_hwdep *hw; +@@ -247,4 +246,3 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device* device) + sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum); + return 0; + } +- +diff --git a/sound/usb/usx2y/usX2Yhwdep.h b/sound/usb/usx2y/usX2Yhwdep.h +index 34cef625712c6..0c9946d9cd999 100644 +--- a/sound/usb/usx2y/usX2Yhwdep.h ++++ b/sound/usb/usx2y/usX2Yhwdep.h +@@ -2,6 +2,6 @@ + #ifndef USX2YHWDEP_H + #define USX2YHWDEP_H + +-int usx2y_hwdep_new(struct snd_card *card, struct usb_device* device); ++int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device); + + #endif +diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c +index cff684942c4f0..5726466c53257 100644 +--- a/sound/usb/usx2y/usb_stream.c ++++ b/sound/usb/usx2y/usb_stream.c +@@ -8,12 +8,12 @@ + + #include "usb_stream.h" + +- + /* setup */ + + static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk) + { + struct usb_stream *s = sk->s; ++ + sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn; + return (sk->out_phase_peeked >> 16) * s->cfg.frame_size; + } +@@ -25,6 +25,7 @@ static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb) + + for (pack = 0; pack < sk->n_o_ps; pack++) { + int l = usb_stream_next_packet_size(sk); ++ + if (s->idle_outsize + lb + l > s->period_size) + goto check; + +@@ -56,6 +57,7 @@ static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, + ++u, transfer += transfer_length) { + struct urb *urb = urbs[u]; + struct usb_iso_packet_descriptor *desc; ++ + urb->transfer_buffer = transfer; + urb->dev = dev; + urb->pipe = pipe; +@@ -84,9 +86,8 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, + struct usb_device *dev, int in_pipe, int out_pipe) + { + struct usb_stream *s = sk->s; +- char *indata = (char *)s + sizeof(*s) + +- sizeof(struct usb_stream_packet) * +- s->inpackets; ++ char *indata = ++ (char *)s + sizeof(*s) + sizeof(struct usb_stream_packet) * s->inpackets; + int u; + + for (u = 0; u < USB_STREAM_NURBS; ++u) { +@@ -107,7 +108,6 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, + return 0; + } + +- + /* + * convert a sampling rate into our full speed format (fs/1000 in Q16.16) + * this will overflow at approx 524 kHz +@@ -234,12 +234,12 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, + return sk->s; + } + +- + /* start */ + + static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb) + { + bool r; ++ + if (unlikely(urb->status)) { + if (urb->status != -ESHUTDOWN && urb->status != -ENOENT) + snd_printk(KERN_WARNING "status=%i\n", urb->status); +@@ -270,6 +270,7 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *)) + + for (u = 0; u < USB_STREAM_NURBS; u++) { + struct urb *urb = urbs[u]; ++ + urb->complete = complete; + } + } +@@ -287,6 +288,7 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk, + + for (; s->sync_packet < 0; ++p, ++s->sync_packet) { + struct urb *ii = sk->completed_inurb; ++ + id = ii->iso_frame_desc + + ii->number_of_packets + s->sync_packet; + l = id->actual_length; +@@ -354,6 +356,7 @@ static int submit_urbs(struct usb_stream_kernel *sk, + struct urb *inurb, struct urb *outurb) + { + int err; ++ + prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb); + err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC); + if (err < 0) +@@ -450,6 +453,7 @@ static void stream_idle(struct usb_stream_kernel *sk, + + for (p = 0; p < inurb->number_of_packets; ++p) { + struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc; ++ + l = id[p].actual_length; + if (unlikely(l == 0 || id[p].status)) { + snd_printk(KERN_WARNING "underrun, status=%u\n", +@@ -506,6 +510,7 @@ static void stream_idle(struct usb_stream_kernel *sk, + static void i_capture_idle(struct urb *urb) + { + struct usb_stream_kernel *sk = urb->context; ++ + if (balance_capture(sk, urb)) + stream_idle(sk, urb, sk->i_urb); + } +@@ -513,6 +518,7 @@ static void i_capture_idle(struct urb *urb) + static void i_playback_idle(struct urb *urb) + { + struct usb_stream_kernel *sk = urb->context; ++ + if (balance_playback(sk, urb)) + stream_idle(sk, sk->i_urb, urb); + } +@@ -521,10 +527,12 @@ static void stream_start(struct usb_stream_kernel *sk, + struct urb *inurb, struct urb *outurb) + { + struct usb_stream *s = sk->s; ++ + if (s->state >= usb_stream_sync1) { + int l, p, max_diff, max_diff_0; + int urb_size = 0; + unsigned frames_per_packet, min_frames = 0; ++ + frames_per_packet = (s->period_size - s->idle_insize); + frames_per_packet <<= 8; + frames_per_packet /= +@@ -539,6 +547,7 @@ static void stream_start(struct usb_stream_kernel *sk, + max_diff = max_diff_0; + for (p = 0; p < inurb->number_of_packets; ++p) { + int diff; ++ + l = inurb->iso_frame_desc[p].actual_length; + urb_size += l; + +@@ -565,6 +574,7 @@ static void stream_start(struct usb_stream_kernel *sk, + s->next_inpacket_split_at = 0; + } else { + unsigned split = s->inpacket_head; ++ + l = s->idle_insize; + while (l > s->inpacket[split].length) { + l -= s->inpacket[split].length; +@@ -612,6 +622,7 @@ static void i_capture_start(struct urb *urb) + + for (p = 0; p < urb->number_of_packets; ++p) { + int l = id[p].actual_length; ++ + if (l < s->cfg.frame_size) { + ++empty; + if (s->state >= usb_stream_sync0) { +@@ -631,6 +642,7 @@ static void i_capture_start(struct urb *urb) + urb->iso_frame_desc[0].actual_length); + for (pack = 1; pack < urb->number_of_packets; ++pack) { + int l = urb->iso_frame_desc[pack].actual_length; ++ + printk(KERN_CONT " %i", l); + } + printk(KERN_CONT "\n"); +@@ -646,6 +658,7 @@ static void i_capture_start(struct urb *urb) + static void i_playback_start(struct urb *urb) + { + struct usb_stream_kernel *sk = urb->context; ++ + if (balance_playback(sk, urb)) + stream_start(sk, sk->i_urb, urb); + } +@@ -674,6 +687,7 @@ int usb_stream_start(struct usb_stream_kernel *sk) + for (u = 0; u < 2; u++) { + struct urb *inurb = sk->inurb[u]; + struct urb *outurb = sk->outurb[u]; ++ + playback_prep_freqn(sk, outurb); + inurb->number_of_packets = outurb->number_of_packets; + inurb->transfer_buffer_length = +@@ -683,6 +697,7 @@ int usb_stream_start(struct usb_stream_kernel *sk) + if (u == 0) { + int now; + struct usb_device *dev = inurb->dev; ++ + frame = usb_get_current_frame_number(dev); + do { + now = usb_get_current_frame_number(dev); +@@ -691,14 +706,16 @@ int usb_stream_start(struct usb_stream_kernel *sk) + } + err = usb_submit_urb(inurb, GFP_ATOMIC); + if (err < 0) { +- snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])" +- " returned %i\n", u, err); ++ snd_printk(KERN_ERR ++ "usb_submit_urb(sk->inurb[%i]) returned %i\n", ++ u, err); + return err; + } + err = usb_submit_urb(outurb, GFP_ATOMIC); + if (err < 0) { +- snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])" +- " returned %i\n", u, err); ++ snd_printk(KERN_ERR ++ "usb_submit_urb(sk->outurb[%i]) returned %i\n", ++ u, err); + return err; + } + +@@ -719,8 +736,8 @@ int usb_stream_start(struct usb_stream_kernel *sk) + snd_printd(KERN_DEBUG "goto dotry;\n"); + goto dotry; + } +- snd_printk(KERN_WARNING"couldn't start" +- " all urbs on the same start_frame.\n"); ++ snd_printk(KERN_WARNING ++ "couldn't start all urbs on the same start_frame.\n"); + return -EFAULT; + } + +@@ -732,6 +749,7 @@ int usb_stream_start(struct usb_stream_kernel *sk) + /* wait, check */ + { + int wait_ms = 3000; ++ + while (s->state != usb_stream_ready && wait_ms > 0) { + snd_printdd(KERN_DEBUG "%i\n", s->state); + msleep(200); +@@ -748,6 +766,7 @@ int usb_stream_start(struct usb_stream_kernel *sk) + void usb_stream_stop(struct usb_stream_kernel *sk) + { + int u; ++ + if (!sk->s) + return; + for (u = 0; u < USB_STREAM_NURBS; ++u) { +diff --git a/sound/usb/usx2y/usbus428ctldefs.h b/sound/usb/usx2y/usbus428ctldefs.h +index 7366a940ffbba..06b27d23d3c22 100644 +--- a/sound/usb/usx2y/usbus428ctldefs.h ++++ b/sound/usb/usx2y/usbus428ctldefs.h +@@ -39,15 +39,15 @@ enum E_IN84 { + + + struct us428_ctls { +- unsigned char fader[9]; +- unsigned char transport; +- unsigned char modifier; +- unsigned char filters_elect; +- unsigned char select; +- unsigned char mute; +- unsigned char unknown; +- unsigned char wswitch; +- unsigned char wheel[5]; ++ unsigned char fader[9]; ++ unsigned char transport; ++ unsigned char modifier; ++ unsigned char filters_elect; ++ unsigned char select; ++ unsigned char mute; ++ unsigned char unknown; ++ unsigned char wswitch; ++ unsigned char wheel[5]; + }; + + struct us428_set_byte { +diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c +index 6d910f23da0d0..9bd2ade8f9b5b 100644 +--- a/sound/usb/usx2y/usbusx2y.c ++++ b/sound/usb/usx2y/usbusx2y.c +@@ -70,7 +70,7 @@ + + 2003-11-03 Karsten Wiese + Version 0.3: +- 24Bit support. ++ 24Bit support. + "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works. + + 2003-08-22 Karsten Wiese +@@ -94,16 +94,15 @@ + This helped me much on my slowish PII 400 & PIII 500. + ACPI yet untested but might cause the same bad behaviour. + Use a kernel with lowlatency and preemptiv patches applied. +- To autoload snd-usb-midi append a line ++ To autoload snd-usb-midi append a line + post-install snd-usb-us428 modprobe snd-usb-midi + to /etc/modules.conf. + + known problems: + sliders, knobs, lights not yet handled except MASTER Volume slider. +- "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does. ++ "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does. + KDE3: "Enable full duplex operation" deadlocks. + +- + 2002-08-31 Karsten Wiese + Version 0.0.3: audio also simplex; + simplifying: iso urbs only 1 packet, melted structs. +@@ -115,7 +114,7 @@ + The firmware has been sniffed from win2k us-428 driver 3.09. + + * Copyright (c) 2002 - 2004 Karsten Wiese +-*/ ++ */ + + #include + #include +@@ -132,15 +131,13 @@ + #include "usbusx2y.h" + #include "usX2Yhwdep.h" + +- +- + MODULE_AUTHOR("Karsten Wiese "); + MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); + MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604),"NAME_ALLCAPS"(0x8001)(0x8005)(0x8007)}}"); + + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ +-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ ++static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ + static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ + + module_param_array(index, int, NULL, 0444); +@@ -150,22 +147,23 @@ MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS"."); + module_param_array(enable, bool, NULL, 0444); + MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); + +- + static int snd_usx2y_card_used[SNDRV_CARDS]; + +-static void usx2y_usb_disconnect(struct usb_device* usb_device, void* ptr); ++static void usx2y_usb_disconnect(struct usb_device *usb_device, void *ptr); + static void snd_usx2y_card_private_free(struct snd_card *card); + +-/* +- * pipe 4 is used for switching the lamps, setting samplerate, volumes .... ++/* ++ * pipe 4 is used for switching the lamps, setting samplerate, volumes .... + */ + static void i_usx2y_out04_int(struct urb *urb) + { + #ifdef CONFIG_SND_DEBUG + if (urb->status) { +- int i; ++ int i; + struct usx2ydev *usx2y = urb->context; +- for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++); ++ ++ for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++) ++ ; + snd_printdd("i_usx2y_out04_int() urb %i status=%i\n", i, urb->status); + } + #endif +@@ -187,22 +185,25 @@ static void i_usx2y_in04_int(struct urb *urb) + // printk("%i:0x%02X ", 8, (int)((unsigned char*)usx2y->in04_buf)[8]); Master volume shows 0 here if fader is at max during boot ?!? + if (us428ctls) { + int diff = -1; ++ + if (-2 == us428ctls->ctl_snapshot_last) { + diff = 0; + memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last)); + us428ctls->ctl_snapshot_last = -1; + } else { + int i; ++ + for (i = 0; i < 21; i++) { +- if (usx2y->in04_last[i] != ((char*)usx2y->in04_buf)[i]) { ++ if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) { + if (diff < 0) + diff = i; +- usx2y->in04_last[i] = ((char*)usx2y->in04_buf)[i]; ++ usx2y->in04_last[i] = ((char *)usx2y->in04_buf)[i]; + } + } + } + if (0 <= diff) { + int n = us428ctls->ctl_snapshot_last + 1; ++ + if (n >= N_US428_CTL_BUFS || n < 0) + n = 0; + memcpy(us428ctls->ctl_snapshot + n, usx2y->in04_buf, sizeof(us428ctls->ctl_snapshot[0])); +@@ -211,8 +212,7 @@ static void i_usx2y_in04_int(struct urb *urb) + wake_up(&usx2y->us428ctls_wait_queue_head); + } + } +- +- ++ + if (usx2y->us04) { + if (0 == usx2y->us04->submitted) + do { +@@ -222,11 +222,13 @@ static void i_usx2y_in04_int(struct urb *urb) + if (us428ctls && us428ctls->p4out_last >= 0 && us428ctls->p4out_last < N_US428_P4OUT_BUFS) { + if (us428ctls->p4out_last != us428ctls->p4out_sent) { + int j, send = us428ctls->p4out_sent + 1; ++ + if (send >= N_US428_P4OUT_BUFS) + send = 0; + for (j = 0; j < URBS_ASYNC_SEQ && !err; ++j) + if (0 == usx2y->as04.urb[j]->status) { + struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. ++ + usb_fill_bulk_urb(usx2y->as04.urb[j], usx2y->dev, + usb_sndbulkpipe(usx2y->dev, 0x04), &p4out->val.vol, + p4out->type == ELT_LIGHT ? sizeof(struct us428_lights) : 5, +@@ -250,8 +252,7 @@ static void i_usx2y_in04_int(struct urb *urb) + */ + int usx2y_async_seq04_init(struct usx2ydev *usx2y) + { +- int err = 0, +- i; ++ int err = 0, i; + + usx2y->as04.buffer = kmalloc_array(URBS_ASYNC_SEQ, + URB_DATA_LEN_ASYNC_SEQ, GFP_KERNEL); +@@ -263,11 +264,10 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y) + err = -ENOMEM; + break; + } +- usb_fill_bulk_urb( usx2y->as04.urb[i], usx2y->dev, +- usb_sndbulkpipe(usx2y->dev, 0x04), +- usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ*i, 0, +- i_usx2y_out04_int, usx2y +- ); ++ usb_fill_bulk_urb(usx2y->as04.urb[i], usx2y->dev, ++ usb_sndbulkpipe(usx2y->dev, 0x04), ++ usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ*i, 0, ++ i_usx2y_out04_int, usx2y); + err = usb_urb_ep_type_check(usx2y->as04.urb[i]); + if (err < 0) + break; +@@ -277,12 +277,12 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y) + + int usx2y_in04_init(struct usx2ydev *usx2y) + { +- if (! (usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL))) ++ if (!(usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL))) + return -ENOMEM; + +- if (! (usx2y->in04_buf = kmalloc(21, GFP_KERNEL))) ++ if (!(usx2y->in04_buf = kmalloc(21, GFP_KERNEL))) + return -ENOMEM; +- ++ + init_waitqueue_head(&usx2y->in04_wait_queue); + usb_fill_int_urb(usx2y->in04_urb, usx2y->dev, usb_rcvintpipe(usx2y->dev, 0x4), + usx2y->in04_buf, 21, +@@ -296,6 +296,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y) + static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s) + { + int i; ++ + for (i = 0; i < URBS_ASYNC_SEQ; ++i) { + usb_kill_urb(s->urb[i]); + usb_free_urb(s->urb[i]); +@@ -304,32 +305,32 @@ static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s) + kfree(s->buffer); + } + +- + static const struct usb_device_id snd_usx2y_usb_id_table[] = { + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x1604, +- .idProduct = USB_ID_US428 ++ .idProduct = USB_ID_US428 + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x1604, +- .idProduct = USB_ID_US122 ++ .idProduct = USB_ID_US122 + }, +- { ++ { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x1604, + .idProduct = USB_ID_US224 + }, + { /* terminator */ } + }; ++MODULE_DEVICE_TABLE(usb, snd_usx2y_usb_id_table); + + static int usx2y_create_card(struct usb_device *device, + struct usb_interface *intf, + struct snd_card **cardp) + { + int dev; +- struct snd_card * card; ++ struct snd_card *card; + int err; + + for (dev = 0; dev < SNDRV_CARDS; ++dev) +@@ -350,7 +351,7 @@ static int usx2y_create_card(struct usb_device *device, + strcpy(card->driver, "USB "NAME_ALLCAPS""); + sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); + sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", +- card->shortname, ++ card->shortname, + le16_to_cpu(device->descriptor.idVendor), + le16_to_cpu(device->descriptor.idProduct), + 0,//us428(card)->usbmidi.ifnum, +@@ -360,14 +361,13 @@ static int usx2y_create_card(struct usb_device *device, + return 0; + } + +- + static int usx2y_usb_probe(struct usb_device *device, + struct usb_interface *intf, + const struct usb_device_id *device_id, + struct snd_card **cardp) + { + int err; +- struct snd_card * card; ++ struct snd_card *card; + + *cardp = NULL; + if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || +@@ -409,7 +409,6 @@ static void snd_usx2y_disconnect(struct usb_interface *intf) + usb_get_intfdata(intf)); + } + +-MODULE_DEVICE_TABLE(usb, snd_usx2y_usb_id_table); + static struct usb_driver snd_usx2y_usb_driver = { + .name = "snd-usb-usx2y", + .probe = snd_usx2y_probe, +@@ -431,12 +430,13 @@ static void snd_usx2y_card_private_free(struct snd_card *card) + /* + * Frees the device. + */ +-static void usx2y_usb_disconnect(struct usb_device *device, void* ptr) ++static void usx2y_usb_disconnect(struct usb_device *device, void *ptr) + { + if (ptr) { + struct snd_card *card = ptr; + struct usx2ydev *usx2y = usx2y(card); + struct list_head *p; ++ + usx2y->chip_status = USX2Y_STAT_CHIP_HUP; + usx2y_unlinkseq(&usx2y->as04); + usb_kill_urb(usx2y->in04_urb); +@@ -445,7 +445,7 @@ static void usx2y_usb_disconnect(struct usb_device *device, void* ptr) + list_for_each(p, &usx2y->midi_list) { + snd_usbmidi_disconnect(p); + } +- if (usx2y->us428ctls_sharedmem) ++ if (usx2y->us428ctls_sharedmem) + wake_up(&usx2y->us428ctls_wait_queue_head); + snd_card_free(card); + } +diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h +index c330af628bccd..5ad6e3767621c 100644 +--- a/sound/usb/usx2y/usbusx2y.h ++++ b/sound/usb/usx2y/usbusx2y.h +@@ -3,9 +3,9 @@ + #define USBUSX2Y_H + #include "../usbaudio.h" + #include "../midi.h" +-#include "usbus428ctldefs.h" ++#include "usbus428ctldefs.h" + +-#define NRURBS 2 ++#define NRURBS 2 + + + #define URBS_ASYNC_SEQ 10 +@@ -55,7 +55,7 @@ struct snd_usx2y_substream { + struct usx2ydev *usx2y; + struct snd_pcm_substream *pcm_substream; + +- int endpoint; ++ int endpoint; + unsigned int maxpacksize; /* max packet size in bytes */ + + atomic_t state; +diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c +index 8033bb7255d5c..f92a9d52ea332 100644 +--- a/sound/usb/usx2y/usbusx2yaudio.c ++++ b/sound/usb/usx2y/usbusx2yaudio.c +@@ -11,7 +11,7 @@ + * + * Copyright (c) 2002 by Takashi Iwai + * +- * Many codes borrowed from audio.c by ++ * Many codes borrowed from audio.c by + * Alan Cox (alan@lxorguk.ukuu.org.uk) + * Thomas Sailer (sailer@ife.ee.ethz.ch) + */ +@@ -28,50 +28,51 @@ + #include "usx2y.h" + #include "usbusx2y.h" + +-#define USX2Y_NRPACKS 4 /* Default value used for nr of packs per urb. +- 1 to 4 have been tested ok on uhci. +- To use 3 on ohci, you'd need a patch: +- look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on +- "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425" +- . +- 1, 2 and 4 work out of the box on ohci, if I recall correctly. +- Bigger is safer operation, +- smaller gives lower latencies. +- */ +-#define USX2Y_NRPACKS_VARIABLE y /* If your system works ok with this module's parameter +- nrpacks set to 1, you might as well comment +- this #define out, and thereby produce smaller, faster code. +- You'd also set USX2Y_NRPACKS to 1 then. +- */ ++/* Default value used for nr of packs per urb. ++ * 1 to 4 have been tested ok on uhci. ++ * To use 3 on ohci, you'd need a patch: ++ * look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on ++ * "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425" ++ * ++ * 1, 2 and 4 work out of the box on ohci, if I recall correctly. ++ * Bigger is safer operation, smaller gives lower latencies. ++ */ ++#define USX2Y_NRPACKS 4 ++ ++/* If your system works ok with this module's parameter ++ * nrpacks set to 1, you might as well comment ++ * this define out, and thereby produce smaller, faster code. ++ * You'd also set USX2Y_NRPACKS to 1 then. ++ */ ++#define USX2Y_NRPACKS_VARIABLE 1 + + #ifdef USX2Y_NRPACKS_VARIABLE +- static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */ +- #define nr_of_packs() nrpacks +- module_param(nrpacks, int, 0444); +- MODULE_PARM_DESC(nrpacks, "Number of packets per URB."); ++static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */ ++#define nr_of_packs() nrpacks ++module_param(nrpacks, int, 0444); ++MODULE_PARM_DESC(nrpacks, "Number of packets per URB."); + #else +- #define nr_of_packs() USX2Y_NRPACKS ++#define nr_of_packs() USX2Y_NRPACKS + #endif + +- + static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + { + struct urb *urb = subs->completed_urb; + struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; + unsigned char *cp; +- int i, len, lens = 0, hwptr_done = subs->hwptr_done; ++ int i, len, lens = 0, hwptr_done = subs->hwptr_done; + struct usx2ydev *usx2y = subs->usx2y; + + for (i = 0; i < nr_of_packs(); i++) { +- cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; ++ cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; + if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ +- snd_printk(KERN_ERR "active frame status %i. " +- "Most probably some hardware problem.\n", ++ snd_printk(KERN_ERR ++ "active frame status %i. Most probably some hardware problem.\n", + urb->iso_frame_desc[i].status); + return urb->iso_frame_desc[i].status; + } + len = urb->iso_frame_desc[i].actual_length / usx2y->stride; +- if (! len) { ++ if (!len) { + snd_printd("0 == len ERROR!\n"); + continue; + } +@@ -80,6 +81,7 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + if ((hwptr_done + len) > runtime->buffer_size) { + int cnt = runtime->buffer_size - hwptr_done; + int blen = cnt * usx2y->stride; ++ + memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp, blen); + memcpy(runtime->dma_area, cp + blen, len * usx2y->stride - blen); + } else { +@@ -100,6 +102,7 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + } + return 0; + } ++ + /* + * prepare urb for playback data pipe + * +@@ -140,6 +143,7 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs, + * copy the data to the temp buffer. + */ + int len; ++ + len = runtime->buffer_size - subs->hwptr; + urb->transfer_buffer = subs->tmpbuf; + memcpy(subs->tmpbuf, runtime->dma_area + +@@ -183,6 +187,7 @@ static void usx2y_urb_play_retire(struct snd_usx2y_substream *subs, struct urb * + static int usx2y_urb_submit(struct snd_usx2y_substream *subs, struct urb *urb, int frame) + { + int err; ++ + if (!urb) + return -ENODEV; + urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks +@@ -243,13 +248,13 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs, + return 0; + } + +- + static void usx2y_clients_stop(struct usx2ydev *usx2y) + { + int s, u; + + for (s = 0; s < 4; s++) { + struct snd_usx2y_substream *subs = usx2y->subs[s]; ++ + if (subs) { + snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state)); + atomic_set(&subs->state, STATE_STOPPED); +@@ -257,11 +262,13 @@ static void usx2y_clients_stop(struct usx2ydev *usx2y) + } + for (s = 0; s < 4; s++) { + struct snd_usx2y_substream *subs = usx2y->subs[s]; ++ + if (subs) { + if (atomic_read(&subs->state) >= STATE_PRERUNNING) + snd_pcm_stop_xrun(subs->pcm_substream); + for (u = 0; u < NRURBS; u++) { + struct urb *urb = subs->urb[u]; ++ + if (NULL != urb) + snd_printdd("%i status=%i start_frame=%i\n", + u, urb->status, urb->start_frame); +@@ -302,6 +309,7 @@ static void i_usx2y_urb_complete(struct urb *urb) + { + struct snd_usx2y_substream *capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE], + *playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; ++ + if (capsubs->completed_urb && + atomic_read(&capsubs->state) >= STATE_PREPARED && + (playbacksubs->completed_urb || +@@ -316,22 +324,25 @@ static void i_usx2y_urb_complete(struct urb *urb) + } + } + +-static void usx2y_urbs_set_complete(struct usx2ydev * usx2y, ++static void usx2y_urbs_set_complete(struct usx2ydev *usx2y, + void (*complete)(struct urb *)) + { + int s, u; ++ + for (s = 0; s < 4; s++) { + struct snd_usx2y_substream *subs = usx2y->subs[s]; ++ + if (NULL != subs) + for (u = 0; u < NRURBS; u++) { +- struct urb * urb = subs->urb[u]; ++ struct urb *urb = subs->urb[u]; ++ + if (NULL != urb) + urb->complete = complete; + } + } + } + +-static void usx2y_subs_startup_finish(struct usx2ydev * usx2y) ++static void usx2y_subs_startup_finish(struct usx2ydev *usx2y) + { + usx2y_urbs_set_complete(usx2y, i_usx2y_urb_complete); + usx2y->prepare_subs = NULL; +@@ -342,6 +353,7 @@ static void i_usx2y_subs_startup(struct urb *urb) + struct snd_usx2y_substream *subs = urb->context; + struct usx2ydev *usx2y = subs->usx2y; + struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs; ++ + if (NULL != prepare_subs) + if (urb->start_frame == prepare_subs->urb[0]->start_frame) { + usx2y_subs_startup_finish(usx2y); +@@ -362,7 +374,6 @@ static void usx2y_subs_prepare(struct snd_usx2y_substream *subs) + subs->transfer_done = 0; + } + +- + static void usx2y_urb_release(struct urb **urb, int free_tb) + { + if (*urb) { +@@ -373,12 +384,14 @@ static void usx2y_urb_release(struct urb **urb, int free_tb) + *urb = NULL; + } + } ++ + /* + * release a substreams urbs + */ + static void usx2y_urbs_release(struct snd_usx2y_substream *subs) + { + int i; ++ + snd_printdd("usx2y_urbs_release() %i\n", subs->endpoint); + for (i = 0; i < NRURBS; i++) + usx2y_urb_release(subs->urb + i, +@@ -387,6 +400,7 @@ static void usx2y_urbs_release(struct snd_usx2y_substream *subs) + kfree(subs->tmpbuf); + subs->tmpbuf = NULL; + } ++ + /* + * initialize a substream's urbs + */ +@@ -411,6 +425,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs) + /* allocate and initialize data urbs */ + for (i = 0; i < NRURBS; i++) { + struct urb **purb = subs->urb + i; ++ + if (*purb) { + usb_kill_urb(*purb); + continue; +@@ -443,6 +458,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs) + static void usx2y_subs_startup(struct snd_usx2y_substream *subs) + { + struct usx2ydev *usx2y = subs->usx2y; ++ + usx2y->prepare_subs = subs; + subs->urb[0]->start_frame = -1; + wmb(); +@@ -459,6 +475,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + subs->completed_urb = NULL; + for (i = 0; i < 4; i++) { + struct snd_usx2y_substream *subs = usx2y->subs[i]; ++ + if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED) + goto start; + } +@@ -467,8 +484,10 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + usx2y_subs_startup(subs); + for (i = 0; i < NRURBS; i++) { + struct urb *urb = subs->urb[i]; ++ + if (usb_pipein(urb->pipe)) { + unsigned long pack; ++ + if (0 == i) + atomic_set(&subs->state, STATE_STARTING3); + urb->dev = usx2y->dev; +@@ -476,9 +495,9 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; + urb->iso_frame_desc[pack].length = subs->maxpacksize; + } +- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); ++ urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); + if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { +- snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); ++ snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); + err = -EPIPE; + goto cleanup; + } else +@@ -509,8 +528,10 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) + static snd_pcm_uframes_t snd_usx2y_pcm_pointer(struct snd_pcm_substream *substream) + { + struct snd_usx2y_substream *subs = substream->runtime->private_data; ++ + return subs->hwptr_done; + } ++ + /* + * start/stop substream + */ +@@ -540,7 +561,6 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd) + return 0; + } + +- + /* + * allocate a buffer, setup samplerate + * +@@ -553,8 +573,7 @@ static const struct s_c2 + { + char c1, c2; + } +- setrate_44100[] = +-{ ++ setrate_44100[] = { + { 0x14, 0x08}, // this line sets 44100, well actually a little less + { 0x18, 0x40}, // only tascam / frontier design knows the further lines ....... + { 0x18, 0x42}, +@@ -589,8 +608,8 @@ static const struct s_c2 + { 0x18, 0x7C}, + { 0x18, 0x7E} + }; +-static const struct s_c2 setrate_48000[] = +-{ ++ ++static const struct s_c2 setrate_48000[] = { + { 0x14, 0x09}, // this line sets 48000, well actually a little less + { 0x18, 0x40}, // only tascam / frontier design knows the further lines ....... + { 0x18, 0x42}, +@@ -625,12 +644,13 @@ static const struct s_c2 setrate_48000[] = + { 0x18, 0x7C}, + { 0x18, 0x7E} + }; ++ + #define NOOF_SETRATE_URBS ARRAY_SIZE(setrate_48000) + + static void i_usx2y_04int(struct urb *urb) + { + struct usx2ydev *usx2y = urb->context; +- ++ + if (urb->status) + snd_printk(KERN_ERR "snd_usx2y_04int() urb->status=%i\n", urb->status); + if (0 == --usx2y->us04->len) +@@ -645,7 +665,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + const struct s_c2 *ra = rate == 48000 ? setrate_48000 : setrate_44100; + + if (usx2y->rate != rate) { +- us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL); ++ us = kzalloc(sizeof(*us) + sizeof(struct urb *) * NOOF_SETRATE_URBS, GFP_KERNEL); + if (NULL == us) { + err = -ENOMEM; + goto cleanup; +@@ -661,8 +681,8 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + err = -ENOMEM; + goto cleanup; + } +- ((char*)(usbdata + i))[0] = ra[i].c1; +- ((char*)(usbdata + i))[1] = ra[i].c2; ++ ((char *)(usbdata + i))[0] = ra[i].c1; ++ ((char *)(usbdata + i))[1] = ra[i].c2; + usb_fill_bulk_urb(us->urb[i], usx2y->dev, usb_sndbulkpipe(usx2y->dev, 4), + usbdata + i, 2, i_usx2y_04int, usx2y); + } +@@ -681,6 +701,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + us->submitted = 2*NOOF_SETRATE_URBS; + for (i = 0; i < NOOF_SETRATE_URBS; ++i) { + struct urb *urb = us->urb[i]; ++ + if (!urb) + continue; + if (urb->status) { +@@ -705,7 +726,8 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) + static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format) + { + int alternate, err; +- struct list_head* p; ++ struct list_head *p; ++ + if (format == SNDRV_PCM_FORMAT_S24_3LE) { + alternate = 2; + usx2y->stride = 6; +@@ -718,7 +740,7 @@ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format) + } + usb_kill_urb(usx2y->in04_urb); + if ((err = usb_set_interface(usx2y->dev, 0, alternate))) { +- snd_printk(KERN_ERR "usb_set_interface error \n"); ++ snd_printk(KERN_ERR "usb_set_interface error\n"); + return err; + } + usx2y->in04_urb->dev = usx2y->dev; +@@ -778,11 +800,13 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_usx2y_substream *subs = runtime->private_data; ++ + mutex_lock(&subs->usx2y->pcm_mutex); + snd_printdd("snd_usx2y_hw_free(%p)\n", substream); + + if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { + struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; ++ + atomic_set(&subs->state, STATE_STOPPED); + usx2y_urbs_release(subs); + if (!cap_subs->pcm_substream || +@@ -794,6 +818,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream) + } + } else { + struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; ++ + if (atomic_read(&playback_subs->state) < STATE_PREPARED) { + atomic_set(&subs->state, STATE_STOPPED); + usx2y_urbs_release(subs); +@@ -802,6 +827,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream) + mutex_unlock(&subs->usx2y->pcm_mutex); + return 0; + } ++ + /* + * prepare callback + * +@@ -814,12 +840,13 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream) + struct usx2ydev *usx2y = subs->usx2y; + struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; + int err = 0; ++ + snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream); + + mutex_lock(&usx2y->pcm_mutex); + usx2y_subs_prepare(subs); +-// Start hardware streams +-// SyncStream first.... ++ // Start hardware streams ++ // SyncStream first.... + if (atomic_read(&capsubs->state) < STATE_PREPARED) { + if (usx2y->format != runtime->format) + if ((err = usx2y_format_set(usx2y, runtime->format)) < 0) +@@ -840,8 +867,7 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream) + return err; + } + +-static const struct snd_pcm_hardware snd_usx2y_2c = +-{ ++static const struct snd_pcm_hardware snd_usx2y_2c = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | +@@ -860,8 +886,6 @@ static const struct snd_pcm_hardware snd_usx2y_2c = + .fifo_size = 0 + }; + +- +- + static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream) + { + struct snd_usx2y_substream *subs = ((struct snd_usx2y_substream **) +@@ -878,8 +902,6 @@ static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream) + return 0; + } + +- +- + static int snd_usx2y_pcm_close(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; +@@ -890,9 +912,7 @@ static int snd_usx2y_pcm_close(struct snd_pcm_substream *substream) + return 0; + } + +- +-static const struct snd_pcm_ops snd_usx2y_pcm_ops = +-{ ++static const struct snd_pcm_ops snd_usx2y_pcm_ops = { + .open = snd_usx2y_pcm_open, + .close = snd_usx2y_pcm_close, + .hw_params = snd_usx2y_pcm_hw_params, +@@ -902,7 +922,6 @@ static const struct snd_pcm_ops snd_usx2y_pcm_ops = + .pointer = snd_usx2y_pcm_pointer, + }; + +- + /* + * free a usb stream instance + */ +@@ -919,6 +938,7 @@ static void usx2y_audio_stream_free(struct snd_usx2y_substream **usx2y_substream + static void snd_usx2y_pcm_private_free(struct snd_pcm *pcm) + { + struct snd_usx2y_substream **usx2y_stream = pcm->private_data; ++ + if (usx2y_stream) + usx2y_audio_stream_free(usx2y_stream); + } +@@ -983,14 +1003,14 @@ static int usx2y_audio_stream_new(struct snd_card *card, int playback_endpoint, + int usx2y_audio_create(struct snd_card *card) + { + int err = 0; +- ++ + INIT_LIST_HEAD(&usx2y(card)->pcm_list); + + if (0 > (err = usx2y_audio_stream_new(card, 0xA, 0x8))) + return err; + if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428) +- if (0 > (err = usx2y_audio_stream_new(card, 0, 0xA))) +- return err; ++ if (0 > (err = usx2y_audio_stream_new(card, 0, 0xA))) ++ return err; + if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) != USB_ID_US122) + err = usx2y_rate_set(usx2y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122. + return err; +diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c +index 399470e51c411..b7e15fc3d1b48 100644 +--- a/sound/usb/usx2y/usx2yhwdeppcm.c ++++ b/sound/usb/usx2y/usx2yhwdeppcm.c +@@ -6,7 +6,7 @@ + + Its usb's unableness to atomically handle power of 2 period sized data chuncs + at standard samplerates, +- what led to this part of the usx2y module: ++ what led to this part of the usx2y module: + It provides the alsa kernel half of the usx2y-alsa-jack driver pair. + The pair uses a hardware dependent alsa-device for mmaped pcm transport. + Advantage achieved: +@@ -35,7 +35,7 @@ + Kernel: + - rawusb dma pcm buffer transport should go to snd-usb-lib, so also snd-usb-audio + devices can use it. +- Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. ++ Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. + */ + + #include +@@ -46,15 +46,16 @@ + + #include + +- + static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs) + { + struct urb *urb = subs->completed_urb; + struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; +- int i, lens = 0, hwptr_done = subs->hwptr_done; ++ int i, lens = 0, hwptr_done = subs->hwptr_done; + struct usx2ydev *usx2y = subs->usx2y; ++ + if (0 > usx2y->hwdep_pcm_shm->capture_iso_start) { //FIXME + int head = usx2y->hwdep_pcm_shm->captured_iso_head + 1; ++ + if (head >= ARRAY_SIZE(usx2y->hwdep_pcm_shm->captured_iso)) + head = 0; + usx2y->hwdep_pcm_shm->capture_iso_start = head; +@@ -62,7 +63,9 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs) + } + for (i = 0; i < nr_of_packs(); i++) { + if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ +- snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status); ++ snd_printk(KERN_ERR ++ "active frame status %i. Most probably some hardware problem.\n", ++ urb->iso_frame_desc[i].status); + return urb->iso_frame_desc[i].status; + } + lens += urb->iso_frame_desc[i].actual_length / usx2y->stride; +@@ -80,7 +83,7 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs) + } + + static inline int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime, +- struct usx2ydev * usx2y) ++ struct usx2ydev *usx2y) + { + return (runtime->buffer_size * 1000) / usx2y->rate + 1; //FIXME: so far only correct period_size == 2^x ? + } +@@ -133,16 +136,18 @@ static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs, + return 0; + } + +- + static inline void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs, + struct urb *urb) + { + int pack; ++ + for (pack = 0; pack < nr_of_packs(); ++pack) { + struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack; ++ + if (NULL != subs) { + struct snd_usx2y_hwdep_pcm_shm *shm = subs->usx2y->hwdep_pcm_shm; + int head = shm->captured_iso_head + 1; ++ + if (head >= ARRAY_SIZE(shm->captured_iso)) + head = 0; + shm->captured_iso[head].frame = urb->start_frame + pack; +@@ -189,7 +194,7 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap + return err; + } + } +- ++ + playbacksubs->completed_urb = NULL; + + state = atomic_read(&capsubs->state); +@@ -214,7 +219,6 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap + return 0; + } + +- + static void i_usx2y_usbpcm_urb_complete(struct urb *urb) + { + struct snd_usx2y_substream *subs = urb->context; +@@ -249,7 +253,6 @@ static void i_usx2y_usbpcm_urb_complete(struct urb *urb) + } + } + +- + static void usx2y_hwdep_urb_release(struct urb **urb) + { + usb_kill_urb(*urb); +@@ -263,12 +266,13 @@ static void usx2y_hwdep_urb_release(struct urb **urb) + static void usx2y_usbpcm_urbs_release(struct snd_usx2y_substream *subs) + { + int i; ++ + snd_printdd("snd_usx2y_urbs_release() %i\n", subs->endpoint); + for (i = 0; i < NRURBS; i++) + usx2y_hwdep_urb_release(subs->urb + i); + } + +-static void usx2y_usbpcm_subs_startup_finish(struct usx2ydev * usx2y) ++static void usx2y_usbpcm_subs_startup_finish(struct usx2ydev *usx2y) + { + usx2y_urbs_set_complete(usx2y, i_usx2y_usbpcm_urb_complete); + usx2y->prepare_subs = NULL; +@@ -279,11 +283,13 @@ static void i_usx2y_usbpcm_subs_startup(struct urb *urb) + struct snd_usx2y_substream *subs = urb->context; + struct usx2ydev *usx2y = subs->usx2y; + struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs; ++ + if (NULL != prepare_subs && + urb->start_frame == prepare_subs->urb[0]->start_frame) { + atomic_inc(&prepare_subs->state); + if (prepare_subs == usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]) { + struct snd_usx2y_substream *cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; ++ + if (cap_subs2 != NULL) + atomic_inc(&cap_subs2->state); + } +@@ -313,6 +319,7 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs) + /* allocate and initialize data urbs */ + for (i = 0; i < NRURBS; i++) { + struct urb **purb = subs->urb + i; ++ + if (*purb) { + usb_kill_urb(*purb); + continue; +@@ -346,11 +353,13 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream) + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_usx2y_substream *subs = runtime->private_data, + *cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; ++ + mutex_lock(&subs->usx2y->pcm_mutex); + snd_printdd("snd_usx2y_usbpcm_hw_free(%p)\n", substream); + + if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { + struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; ++ + atomic_set(&subs->state, STATE_STOPPED); + usx2y_usbpcm_urbs_release(subs); + if (!cap_subs->pcm_substream || +@@ -366,6 +375,7 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream) + } + } else { + struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]; ++ + if (atomic_read(&playback_subs->state) < STATE_PREPARED) { + atomic_set(&subs->state, STATE_STOPPED); + if (NULL != cap_subs2) +@@ -381,7 +391,8 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream) + + static void usx2y_usbpcm_subs_startup(struct snd_usx2y_substream *subs) + { +- struct usx2ydev * usx2y = subs->usx2y; ++ struct usx2ydev *usx2y = subs->usx2y; ++ + usx2y->prepare_subs = subs; + subs->urb[0]->start_frame = -1; + smp_wmb(); // Make sure above modifications are seen by i_usx2y_subs_startup() +@@ -390,8 +401,7 @@ static void usx2y_usbpcm_subs_startup(struct snd_usx2y_substream *subs) + + static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + { +- int p, u, err, +- stream = subs->pcm_substream->stream; ++ int p, u, err, stream = subs->pcm_substream->stream; + struct usx2ydev *usx2y = subs->usx2y; + + if (SNDRV_PCM_STREAM_CAPTURE == stream) { +@@ -410,6 +420,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + + for (p = 0; p < 4; p++) { + struct snd_usx2y_substream *subs = usx2y->subs[p]; ++ + if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED) + goto start; + } +@@ -419,10 +430,13 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + for (u = 0; u < NRURBS; u++) { + for (p = 0; 3 >= (stream + p); p += 2) { + struct snd_usx2y_substream *subs = usx2y->subs[stream + p]; ++ + if (subs != NULL) { + struct urb *urb = subs->urb[u]; ++ + if (usb_pipein(urb->pipe)) { + unsigned long pack; ++ + if (0 == u) + atomic_set(&subs->state, STATE_STARTING3); + urb->dev = usx2y->dev; +@@ -430,9 +444,9 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); + urb->iso_frame_desc[pack].length = subs->maxpacksize; + } +- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); ++ urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); + if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) { +- snd_printk (KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err); ++ snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err); + err = -EPIPE; + goto cleanup; + } else { +@@ -444,7 +458,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + } else { + atomic_set(&subs->state, STATE_STARTING1); + break; +- } ++ } + } + } + } +@@ -452,11 +466,11 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) + wait_event(usx2y->prepare_wait_queue, NULL == usx2y->prepare_subs); + if (atomic_read(&subs->state) != STATE_PREPARED) + err = -EPIPE; +- ++ + cleanup: + if (err) { + usx2y_subs_startup_finish(usx2y); // Call it now +- usx2y_clients_stop(usx2y); // something is completely wroong > stop evrything ++ usx2y_clients_stop(usx2y); // something is completely wroong > stop evrything + } + return err; + } +@@ -473,6 +487,7 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + struct usx2ydev *usx2y = subs->usx2y; + struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]; + int err = 0; ++ + snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream); + + if (NULL == usx2y->hwdep_pcm_shm) { +@@ -485,8 +500,8 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + + mutex_lock(&usx2y->pcm_mutex); + usx2y_subs_prepare(subs); +-// Start hardware streams +-// SyncStream first.... ++ // Start hardware streams ++ // SyncStream first.... + if (atomic_read(&capsubs->state) < STATE_PREPARED) { + if (usx2y->format != runtime->format) + if ((err = usx2y_format_set(usx2y, runtime->format)) < 0) +@@ -505,15 +520,14 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + if (atomic_read(&subs->state) < STATE_PREPARED) { + while (usx2y_iso_frames_per_buffer(runtime, usx2y) > + usx2y->hwdep_pcm_shm->captured_iso_frames) { +- snd_printdd("Wait: iso_frames_per_buffer=%i," +- "captured_iso_frames=%i\n", ++ snd_printdd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", + usx2y_iso_frames_per_buffer(runtime, usx2y), + usx2y->hwdep_pcm_shm->captured_iso_frames); + if (msleep_interruptible(10)) { + err = -ERESTARTSYS; + goto up_prepare_mutex; + } +- } ++ } + if (0 > (err = usx2y_usbpcm_urbs_start(subs))) + goto up_prepare_mutex; + } +@@ -528,8 +542,7 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream) + return err; + } + +-static const struct snd_pcm_hardware snd_usx2y_4c = +-{ ++static const struct snd_pcm_hardware snd_usx2y_4c = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID), +@@ -547,8 +560,6 @@ static const struct snd_pcm_hardware snd_usx2y_4c = + .fifo_size = 0 + }; + +- +- + static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream) + { + struct snd_usx2y_substream *subs = ((struct snd_usx2y_substream **) +@@ -566,7 +577,6 @@ static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream) + return 0; + } + +- + static int snd_usx2y_usbpcm_close(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; +@@ -576,9 +586,7 @@ static int snd_usx2y_usbpcm_close(struct snd_pcm_substream *substream) + return 0; + } + +- +-static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = +-{ ++static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = { + .open = snd_usx2y_usbpcm_open, + .close = snd_usx2y_usbpcm_close, + .hw_params = snd_usx2y_pcm_hw_params, +@@ -588,7 +596,6 @@ static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = + .pointer = snd_usx2y_pcm_pointer, + }; + +- + static int usx2y_pcms_busy_check(struct snd_card *card) + { + struct usx2ydev *dev = usx2y(card); +@@ -596,6 +603,7 @@ static int usx2y_pcms_busy_check(struct snd_card *card) + + for (i = 0; i < dev->pcm_devs * 2; i++) { + struct snd_usx2y_substream *subs = dev->subs[i]; ++ + if (subs && subs->pcm_substream && + SUBSTREAM_BUSY(subs->pcm_substream)) + return -EBUSY; +@@ -616,7 +624,6 @@ static int snd_usx2y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file) + return err; + } + +- + static int snd_usx2y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file) + { + struct snd_card *card = hw->card; +@@ -630,17 +637,14 @@ static int snd_usx2y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file) + return err; + } + +- + static void snd_usx2y_hwdep_pcm_vm_open(struct vm_area_struct *area) + { + } + +- + static void snd_usx2y_hwdep_pcm_vm_close(struct vm_area_struct *area) + { + } + +- + static vm_fault_t snd_usx2y_hwdep_pcm_vm_fault(struct vm_fault *vmf) + { + unsigned long offset; +@@ -653,15 +657,13 @@ static vm_fault_t snd_usx2y_hwdep_pcm_vm_fault(struct vm_fault *vmf) + return 0; + } + +- + static const struct vm_operations_struct snd_usx2y_hwdep_pcm_vm_ops = { + .open = snd_usx2y_hwdep_pcm_vm_open, + .close = snd_usx2y_hwdep_pcm_vm_close, + .fault = snd_usx2y_hwdep_pcm_vm_fault, + }; + +- +-static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area) ++static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep *hw, struct file *filp, struct vm_area_struct *area) + { + unsigned long size = (unsigned long)(area->vm_end - area->vm_start); + struct usx2ydev *usx2y = hw->private_data; +@@ -669,9 +671,9 @@ static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st + if (!(usx2y->chip_status & USX2Y_STAT_CHIP_INIT)) + return -EBUSY; + +- /* if userspace tries to mmap beyond end of our buffer, fail */ ++ /* if userspace tries to mmap beyond end of our buffer, fail */ + if (size > PAGE_ALIGN(sizeof(struct snd_usx2y_hwdep_pcm_shm))) { +- snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usx2y_hwdep_pcm_shm)); ++ snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usx2y_hwdep_pcm_shm)); + return -EINVAL; + } + +@@ -684,21 +686,21 @@ static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st + return 0; + } + +- + static void snd_usx2y_hwdep_pcm_private_free(struct snd_hwdep *hwdep) + { + struct usx2ydev *usx2y = hwdep->private_data; ++ + if (NULL != usx2y->hwdep_pcm_shm) + free_pages_exact(usx2y->hwdep_pcm_shm, sizeof(struct snd_usx2y_hwdep_pcm_shm)); + } + +- + int usx2y_hwdep_pcm_new(struct snd_card *card) + { + int err; + struct snd_hwdep *hw; + struct snd_pcm *pcm; + struct usb_device *dev = usx2y(card)->dev; ++ + if (1 != nr_of_packs()) + return 0; + +-- +2.43.0 + diff --git a/queue-5.10/alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch b/queue-5.10/alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch new file mode 100644 index 00000000000..c7dd1e6c33f --- /dev/null +++ b/queue-5.10/alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch @@ -0,0 +1,46 @@ +From b146c74b4c01b457ce96df7d55ac3d4c700ff2c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2024 12:10:35 +0100 +Subject: ALSA: usx2y: Use snd_card_free_when_closed() at disconnection + +From: Takashi Iwai + +[ Upstream commit dafb28f02be407e07a6f679e922a626592b481b0 ] + +The USB disconnect callback is supposed to be short and not too-long +waiting. OTOH, the current code uses snd_card_free() at +disconnection, but this waits for the close of all used fds, hence it +can take long. It eventually blocks the upper layer USB ioctls, which +may trigger a soft lockup. + +An easy workaround is to replace snd_card_free() with +snd_card_free_when_closed(). This variant returns immediately while +the release of resources is done asynchronously by the card device +release at the last close. + +Fixes: 230cd5e24853 ("[ALSA] prevent oops & dead keyboard on usb unplugging while the device is be ing used") +Reported-by: syzbot+73582d08864d8268b6fd@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=73582d08864d8268b6fd +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20241113111042.15058-2-tiwai@suse.de +Signed-off-by: Sasha Levin +--- + sound/usb/usx2y/usbusx2y.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c +index 9d5a33c4ff2f3..c567e58ceb4fd 100644 +--- a/sound/usb/usx2y/usbusx2y.c ++++ b/sound/usb/usx2y/usbusx2y.c +@@ -396,7 +396,7 @@ static void snd_usx2y_disconnect(struct usb_interface *intf) + } + if (usx2y->us428ctls_sharedmem) + wake_up(&usx2y->us428ctls_wait_queue_head); +- snd_card_free(card); ++ snd_card_free_when_closed(card); + } + + static int snd_usx2y_probe(struct usb_interface *intf, +-- +2.43.0 + diff --git a/queue-5.10/apparmor-fix-do-simple-duplicate-message-elimination.patch b/queue-5.10/apparmor-fix-do-simple-duplicate-message-elimination.patch new file mode 100644 index 00000000000..1a806eecafb --- /dev/null +++ b/queue-5.10/apparmor-fix-do-simple-duplicate-message-elimination.patch @@ -0,0 +1,35 @@ +From a23ae483e5ee5942b4cef3b39a1e5bfa50b5bc71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Jun 2023 10:03:16 +0800 +Subject: apparmor: fix 'Do simple duplicate message elimination' + +From: chao liu + +[ Upstream commit 9b897132424fe76bf6c61f22f9cf12af7f1d1e6a ] + +Multiple profiles shared 'ent->caps', so some logs missed. + +Fixes: 0ed3b28ab8bf ("AppArmor: mediation of non file objects") +Signed-off-by: chao liu +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/capability.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c +index deccea8654ad8..1b13fd89d5a9f 100644 +--- a/security/apparmor/capability.c ++++ b/security/apparmor/capability.c +@@ -94,6 +94,8 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, + return error; + } else { + aa_put_profile(ent->profile); ++ if (profile != ent->profile) ++ cap_clear(ent->caps); + ent->profile = aa_get_profile(profile); + cap_raise(ent->caps, cap); + } +-- +2.43.0 + diff --git a/queue-5.10/arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch b/queue-5.10/arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch new file mode 100644 index 00000000000..0d9bb82f193 --- /dev/null +++ b/queue-5.10/arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch @@ -0,0 +1,56 @@ +From 0eab979807dd498d6142b3d0b0fe27724effaf51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2024 23:29:16 +0100 +Subject: ARM: dts: cubieboard4: Fix DCDC5 regulator constraints + +From: Andre Przywara + +[ Upstream commit dd36ad71ad65968f97630808bc8d605c929b128e ] + +The DCDC5 voltage rail in the X-Powers AXP809 PMIC has a resolution of +50mV, so the currently enforced limits of 1.475 and 1.525 volts cannot +be set, when the existing regulator value is beyond this range. + +This will lead to the whole regulator driver to give up and fail +probing, which in turn will hang the system, as essential devices depend +on the PMIC. +In this case a bug in U-Boot set the voltage to 1.75V (meant for DCDC4), +and the AXP driver's attempt to correct this lead to this error: +================== +[ 4.447653] axp20x-rsb sunxi-rsb-3a3: AXP20X driver loaded +[ 4.450066] vcc-dram: Bringing 1750000uV into 1575000-1575000uV +[ 4.460272] vcc-dram: failed to apply 1575000-1575000uV constraint: -EINVAL +[ 4.474788] axp20x-regulator axp20x-regulator.0: Failed to register dcdc5 +[ 4.482276] axp20x-regulator axp20x-regulator.0: probe with driver axp20x-regulator failed with error -22 +================== + +Set the limits to values that can be programmed, so any correction will +be successful. + +Signed-off-by: Andre Przywara +Fixes: 1e1dea72651b ("ARM: dts: sun9i: cubieboard4: Add AXP809 PMIC device node and regulators") +Link: https://patch.msgid.link/20241007222916.19013-1-andre.przywara@arm.com +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/sun9i-a80-cubieboard4.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts +index 484b93df20cb6..c7a3bf3cc3407 100644 +--- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts ++++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts +@@ -280,8 +280,8 @@ reg_dcdc4: dcdc4 { + + reg_dcdc5: dcdc5 { + regulator-always-on; +- regulator-min-microvolt = <1425000>; +- regulator-max-microvolt = <1575000>; ++ regulator-min-microvolt = <1450000>; ++ regulator-max-microvolt = <1550000>; + regulator-name = "vcc-dram"; + }; + +-- +2.43.0 + diff --git a/queue-5.10/arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch b/queue-5.10/arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch new file mode 100644 index 00000000000..e72aee73d00 --- /dev/null +++ b/queue-5.10/arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch @@ -0,0 +1,50 @@ +From 4a237cd3d0266305ddb1eb8783d90d0535ee8f67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 16:20:00 +0800 +Subject: arm64: dts: mediatek: mt8173-elm-hana: Add vdd-supply to second + source trackpad + +From: Chen-Yu Tsai + +[ Upstream commit f766fae08f6a2eaeb45d8d2c053724c91526835c ] + +The Hana device has a second source option trackpad, but it is missing +its regulator supply. It only works because the regulator is marked as +always-on. + +Add the regulator supply, but leave out the post-power-on delay. Instead, +document the post-power-on delay along with the reason for not adding +it in a comment. + +Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20241018082001.1296963-1-wenst@chromium.org +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +index bdcd35cecad90..fd6230352f4fd 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi +@@ -43,6 +43,14 @@ trackpad2: trackpad@2c { + interrupts = <117 IRQ_TYPE_LEVEL_LOW>; + reg = <0x2c>; + hid-descr-addr = <0x0020>; ++ /* ++ * The trackpad needs a post-power-on delay of 100ms, ++ * but at time of writing, the power supply for it on ++ * this board is always on. The delay is therefore not ++ * added to avoid impacting the readiness of the ++ * trackpad. ++ */ ++ vdd-supply = <&mt6397_vgp6_reg>; + wakeup-source; + }; + }; +-- +2.43.0 + diff --git a/queue-5.10/arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch b/queue-5.10/arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch new file mode 100644 index 00000000000..e0e84427a07 --- /dev/null +++ b/queue-5.10/arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch @@ -0,0 +1,41 @@ +From a12eaa3d7f09abc829f0c11c22ffe2b217622b3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Sep 2024 08:33:46 +0000 +Subject: arm64: dts: mt8183: krane: Fix the address of eeprom at i2c4 + +From: Hsin-Te Yuan + +[ Upstream commit e9c60c34948662b5d47573490ee538439b29e462 ] + +The address of eeprom should be 50. + +Fixes: cd894e274b74 ("arm64: dts: mt8183: Add krane-sku176 board") +Signed-off-by: Hsin-Te Yuan +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Matthias Brugger +Link: https://lore.kernel.org/r/20240909-eeprom-v1-1-1ed2bc5064f4@chromium.org +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi +index fbc471ccf805f..e61ec0229992e 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi +@@ -85,9 +85,9 @@ &i2c4 { + status = "okay"; + clock-frequency = <400000>; + +- eeprom@54 { ++ eeprom@50 { + compatible = "atmel,24c32"; +- reg = <0x54>; ++ reg = <0x50>; + pagesize = <32>; + }; + }; +-- +2.43.0 + diff --git a/queue-5.10/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch b/queue-5.10/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch new file mode 100644 index 00000000000..79b8cd7f357 --- /dev/null +++ b/queue-5.10/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch @@ -0,0 +1,56 @@ +From 37b7b178802f9ad94ee1ada3ac5c1883fe83679f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2024 01:18:42 +0900 +Subject: arm64: fix .data.rel.ro size assertion when CONFIG_LTO_CLANG + +From: Masahiro Yamada + +[ Upstream commit 340fd66c856651d8c1d29f392dd26ad674d2db0e ] + +Commit be2881824ae9 ("arm64/build: Assert for unwanted sections") +introduced an assertion to ensure that the .data.rel.ro section does +not exist. + +However, this check does not work when CONFIG_LTO_CLANG is enabled, +because .data.rel.ro matches the .data.[0-9a-zA-Z_]* pattern in the +DATA_MAIN macro. + +Move the ASSERT() above the RW_DATA() line. + +Fixes: be2881824ae9 ("arm64/build: Assert for unwanted sections") +Signed-off-by: Masahiro Yamada +Acked-by: Will Deacon +Link: https://lore.kernel.org/r/20241106161843.189927-1-masahiroy@kernel.org +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/kernel/vmlinux.lds.S | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S +index 71f4b5f24d15f..6922c4b3e974f 100644 +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -228,6 +228,9 @@ SECTIONS + __initdata_end = .; + __init_end = .; + ++ .data.rel.ro : { *(.data.rel.ro) } ++ ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!") ++ + _data = .; + _sdata = .; + RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) +@@ -279,9 +282,6 @@ SECTIONS + *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt) + } + ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") +- +- .data.rel.ro : { *(.data.rel.ro) } +- ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!") + } + + #include "image-vars.h" +-- +2.43.0 + diff --git a/queue-5.10/asoc-dt-bindings-mt6359-update-generic-node-name-and.patch b/queue-5.10/asoc-dt-bindings-mt6359-update-generic-node-name-and.patch new file mode 100644 index 00000000000..62cc82f9047 --- /dev/null +++ b/queue-5.10/asoc-dt-bindings-mt6359-update-generic-node-name-and.patch @@ -0,0 +1,77 @@ +From 2708266f8ccacba54c90b9a60f3aa189d5d6841b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 15:54:50 +0800 +Subject: ASoC: dt-bindings: mt6359: Update generic node name and dmic-mode + +From: Macpaul Lin + +[ Upstream commit 4649cbd97fdae5069e9a71cd7669b62b90e03669 ] + +Some fix and updates in the following items: +1. examples: + Update generic node name to 'audio-codec' to comply with the + coming change in 'mt6359.dtsi'. This change is necessary to fix the + dtbs_check error: + pmic: 'mt6359codec' does not match any of the regexes: 'pinctrl-[0-9]+' + +2. mediatek,dmic-mode: + After inspecting the .dts and .dtsi files using 'mt6359-codec', it was + discovered that the definitions of 'two wires' and 'one wire' are + inverted compared to the DT schema. + For example, the following boards using MT6359 PMIC: + - mt8192-asurada.dtsi + - mt8195-cherry.dtsi + These boards use the same definitions of 'dmic-mode' as other boards + using MT6358 PMIC. The meaning of '0' or '1' has been noted as comments + in the device trees. + + Upon examining the code in [1] and [2], it was confirmed that the + definitions of 'dmic-mode' are consistent between "MT6359 PMIC" and + "MT6358 PMIC". Therefore, the DT Schema should be correct as is. + +References: +[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/codecs/mt6358.c#n1875 +[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/codecs/mt6359.c#L1515 + +Fixes: 539237d1c609 ("dt-bindings: mediatek: mt6359: add codec document") +Signed-off-by: Jiaxin Yu +Signed-off-by: Macpaul Lin +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20240930075451.14196-1-macpaul.lin@mediatek.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/sound/mt6359.yaml | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/Documentation/devicetree/bindings/sound/mt6359.yaml b/Documentation/devicetree/bindings/sound/mt6359.yaml +index a54f466f769d4..74330f54d6db4 100644 +--- a/Documentation/devicetree/bindings/sound/mt6359.yaml ++++ b/Documentation/devicetree/bindings/sound/mt6359.yaml +@@ -23,8 +23,8 @@ properties: + Indicates how many data pins are used to transmit two channels of PDM + signal. 0 means two wires, 1 means one wire. Default value is 0. + enum: +- - 0 # one wire +- - 1 # two wires ++ - 0 # two wires ++ - 1 # one wire + + mediatek,mic-type-0: + $ref: /schemas/types.yaml#/definitions/uint32 +@@ -53,9 +53,9 @@ additionalProperties: false + + examples: + - | +- mt6359codec: mt6359codec { +- mediatek,dmic-mode = <0>; +- mediatek,mic-type-0 = <2>; ++ mt6359codec: audio-codec { ++ mediatek,dmic-mode = <0>; ++ mediatek,mic-type-0 = <2>; + }; + + ... +-- +2.43.0 + diff --git a/queue-5.10/asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch b/queue-5.10/asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch new file mode 100644 index 00000000000..a8c2019bb29 --- /dev/null +++ b/queue-5.10/asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch @@ -0,0 +1,275 @@ +From eed7e7dd8def432c060dd1aaa018f71f090b1d0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Apr 2022 18:22:32 +0200 +Subject: ASoC: fsl_micfil: do not define SHIFT/MASK for single bits + +From: Sascha Hauer + +[ Upstream commit bd2cffd10d79eb9280cb8f5b7cb441f206c1e6ac ] + +No need to have defines for the mask of single bits. Also shift is +unused. Drop all these unnecessary defines. + +Signed-off-by: Sascha Hauer +Acked-by: Shengjiu Wang +Link: https://lore.kernel.org/r/20220414162249.3934543-5-s.hauer@pengutronix.de +Signed-off-by: Mark Brown +Stable-dep-of: 06df673d2023 ("ASoC: fsl_micfil: fix regmap_write_bits usage") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_micfil.c | 18 +++--- + sound/soc/fsl/fsl_micfil.h | 125 +++++++++---------------------------- + 2 files changed, 40 insertions(+), 103 deletions(-) + +diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c +index fe6d6c87a1c42..13d963a840333 100644 +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -172,7 +172,7 @@ static int fsl_micfil_reset(struct device *dev) + + ret = regmap_update_bits(micfil->regmap, + REG_MICFIL_CTRL1, +- MICFIL_CTRL1_MDIS_MASK, ++ MICFIL_CTRL1_MDIS, + 0); + if (ret) { + dev_err(dev, "failed to clear MDIS bit %d\n", ret); +@@ -181,7 +181,7 @@ static int fsl_micfil_reset(struct device *dev) + + ret = regmap_update_bits(micfil->regmap, + REG_MICFIL_CTRL1, +- MICFIL_CTRL1_SRES_MASK, ++ MICFIL_CTRL1_SRES, + MICFIL_CTRL1_SRES); + if (ret) { + dev_err(dev, "failed to reset MICFIL: %d\n", ret); +@@ -274,7 +274,7 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, + + /* Enable the module */ + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, +- MICFIL_CTRL1_PDMIEN_MASK, ++ MICFIL_CTRL1_PDMIEN, + MICFIL_CTRL1_PDMIEN); + if (ret) { + dev_err(dev, "failed to enable the module\n"); +@@ -287,7 +287,7 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + /* Disable the module */ + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, +- MICFIL_CTRL1_PDMIEN_MASK, ++ MICFIL_CTRL1_PDMIEN, + 0); + if (ret) { + dev_err(dev, "failed to enable the module\n"); +@@ -353,7 +353,7 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, + + /* 1. Disable the module */ + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, +- MICFIL_CTRL1_PDMIEN_MASK, 0); ++ MICFIL_CTRL1_PDMIEN, 0); + if (ret) { + dev_err(dev, "failed to disable the module\n"); + return ret; +@@ -636,16 +636,16 @@ static irqreturn_t micfil_err_isr(int irq, void *devid) + + regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg); + +- if (stat_reg & MICFIL_STAT_BSY_FIL_MASK) ++ if (stat_reg & MICFIL_STAT_BSY_FIL) + dev_dbg(&pdev->dev, "isr: Decimation Filter is running\n"); + +- if (stat_reg & MICFIL_STAT_FIR_RDY_MASK) ++ if (stat_reg & MICFIL_STAT_FIR_RDY) + dev_dbg(&pdev->dev, "isr: FIR Filter Data ready\n"); + +- if (stat_reg & MICFIL_STAT_LOWFREQF_MASK) { ++ if (stat_reg & MICFIL_STAT_LOWFREQF) { + dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n"); + regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, +- MICFIL_STAT_LOWFREQF_MASK, 1); ++ MICFIL_STAT_LOWFREQF, 1); + } + + return IRQ_HANDLED; +diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h +index bac825c3135a0..11ccc08523b2e 100644 +--- a/sound/soc/fsl/fsl_micfil.h ++++ b/sound/soc/fsl/fsl_micfil.h +@@ -33,33 +33,17 @@ + #define REG_MICFIL_VAD0_ZCD 0xA8 + + /* MICFIL Control Register 1 -- REG_MICFILL_CTRL1 0x00 */ +-#define MICFIL_CTRL1_MDIS_SHIFT 31 +-#define MICFIL_CTRL1_MDIS_MASK BIT(MICFIL_CTRL1_MDIS_SHIFT) +-#define MICFIL_CTRL1_MDIS BIT(MICFIL_CTRL1_MDIS_SHIFT) +-#define MICFIL_CTRL1_DOZEN_SHIFT 30 +-#define MICFIL_CTRL1_DOZEN_MASK BIT(MICFIL_CTRL1_DOZEN_SHIFT) +-#define MICFIL_CTRL1_DOZEN BIT(MICFIL_CTRL1_DOZEN_SHIFT) +-#define MICFIL_CTRL1_PDMIEN_SHIFT 29 +-#define MICFIL_CTRL1_PDMIEN_MASK BIT(MICFIL_CTRL1_PDMIEN_SHIFT) +-#define MICFIL_CTRL1_PDMIEN BIT(MICFIL_CTRL1_PDMIEN_SHIFT) +-#define MICFIL_CTRL1_DBG_SHIFT 28 +-#define MICFIL_CTRL1_DBG_MASK BIT(MICFIL_CTRL1_DBG_SHIFT) +-#define MICFIL_CTRL1_DBG BIT(MICFIL_CTRL1_DBG_SHIFT) +-#define MICFIL_CTRL1_SRES_SHIFT 27 +-#define MICFIL_CTRL1_SRES_MASK BIT(MICFIL_CTRL1_SRES_SHIFT) +-#define MICFIL_CTRL1_SRES BIT(MICFIL_CTRL1_SRES_SHIFT) +-#define MICFIL_CTRL1_DBGE_SHIFT 26 +-#define MICFIL_CTRL1_DBGE_MASK BIT(MICFIL_CTRL1_DBGE_SHIFT) +-#define MICFIL_CTRL1_DBGE BIT(MICFIL_CTRL1_DBGE_SHIFT) ++#define MICFIL_CTRL1_MDIS BIT(31) ++#define MICFIL_CTRL1_DOZEN BIT(30) ++#define MICFIL_CTRL1_PDMIEN BIT(29) ++#define MICFIL_CTRL1_DBG BIT(28) ++#define MICFIL_CTRL1_SRES BIT(27) ++#define MICFIL_CTRL1_DBGE BIT(26) + #define MICFIL_CTRL1_DISEL_SHIFT 24 + #define MICFIL_CTRL1_DISEL_WIDTH 2 + #define MICFIL_CTRL1_DISEL_MASK ((BIT(MICFIL_CTRL1_DISEL_WIDTH) - 1) \ + << MICFIL_CTRL1_DISEL_SHIFT) +-#define MICFIL_CTRL1_DISEL(v) (((v) << MICFIL_CTRL1_DISEL_SHIFT) \ +- & MICFIL_CTRL1_DISEL_MASK) +-#define MICFIL_CTRL1_ERREN_SHIFT 23 +-#define MICFIL_CTRL1_ERREN_MASK BIT(MICFIL_CTRL1_ERREN_SHIFT) +-#define MICFIL_CTRL1_ERREN BIT(MICFIL_CTRL1_ERREN_SHIFT) ++#define MICFIL_CTRL1_ERREN BIT(23) + #define MICFIL_CTRL1_CHEN_SHIFT 0 + #define MICFIL_CTRL1_CHEN_WIDTH 8 + #define MICFIL_CTRL1_CHEN_MASK(x) (BIT(x) << MICFIL_CTRL1_CHEN_SHIFT) +@@ -91,15 +75,9 @@ + & MICFIL_CTRL2_CLKDIV_MASK) + + /* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */ +-#define MICFIL_STAT_BSY_FIL_SHIFT 31 +-#define MICFIL_STAT_BSY_FIL_MASK BIT(MICFIL_STAT_BSY_FIL_SHIFT) +-#define MICFIL_STAT_BSY_FIL BIT(MICFIL_STAT_BSY_FIL_SHIFT) +-#define MICFIL_STAT_FIR_RDY_SHIFT 30 +-#define MICFIL_STAT_FIR_RDY_MASK BIT(MICFIL_STAT_FIR_RDY_SHIFT) +-#define MICFIL_STAT_FIR_RDY BIT(MICFIL_STAT_FIR_RDY_SHIFT) +-#define MICFIL_STAT_LOWFREQF_SHIFT 29 +-#define MICFIL_STAT_LOWFREQF_MASK BIT(MICFIL_STAT_LOWFREQF_SHIFT) +-#define MICFIL_STAT_LOWFREQF BIT(MICFIL_STAT_LOWFREQF_SHIFT) ++#define MICFIL_STAT_BSY_FIL BIT(31) ++#define MICFIL_STAT_FIR_RDY BIT(30) ++#define MICFIL_STAT_LOWFREQF BIT(29) + #define MICFIL_STAT_CHXF_SHIFT(v) (v) + #define MICFIL_STAT_CHXF_MASK(v) BIT(MICFIL_STAT_CHXF_SHIFT(v)) + #define MICFIL_STAT_CHXF(v) BIT(MICFIL_STAT_CHXF_SHIFT(v)) +@@ -137,32 +115,16 @@ + << MICFIL_VAD0_CTRL1_INITT_SHIFT) + #define MICFIL_VAD0_CTRL1_INITT(v) (((v) << MICFIL_VAD0_CTRL1_INITT_SHIFT) \ + & MICFIL_VAD0_CTRL1_INITT_MASK) +-#define MICFIL_VAD0_CTRL1_ST10_SHIFT 4 +-#define MICFIL_VAD0_CTRL1_ST10_MASK BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT) +-#define MICFIL_VAD0_CTRL1_ST10 BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT) +-#define MICFIL_VAD0_CTRL1_ERIE_SHIFT 3 +-#define MICFIL_VAD0_CTRL1_ERIE_MASK BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT) +-#define MICFIL_VAD0_CTRL1_ERIE BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT) +-#define MICFIL_VAD0_CTRL1_IE_SHIFT 2 +-#define MICFIL_VAD0_CTRL1_IE_MASK BIT(MICFIL_VAD0_CTRL1_IE_SHIFT) +-#define MICFIL_VAD0_CTRL1_IE BIT(MICFIL_VAD0_CTRL1_IE_SHIFT) +-#define MICFIL_VAD0_CTRL1_RST_SHIFT 1 +-#define MICFIL_VAD0_CTRL1_RST_MASK BIT(MICFIL_VAD0_CTRL1_RST_SHIFT) +-#define MICFIL_VAD0_CTRL1_RST BIT(MICFIL_VAD0_CTRL1_RST_SHIFT) +-#define MICFIL_VAD0_CTRL1_EN_SHIFT 0 +-#define MICFIL_VAD0_CTRL1_EN_MASK BIT(MICFIL_VAD0_CTRL1_EN_SHIFT) +-#define MICFIL_VAD0_CTRL1_EN BIT(MICFIL_VAD0_CTRL1_EN_SHIFT) ++#define MICFIL_VAD0_CTRL1_ST10 BIT(4) ++#define MICFIL_VAD0_CTRL1_ERIE BIT(3) ++#define MICFIL_VAD0_CTRL1_IE BIT(2) ++#define MICFIL_VAD0_CTRL1_RST BIT(1) ++#define MICFIL_VAD0_CTRL1_EN BIT(0) + + /* MICFIL HWVAD0 Control 2 Register -- REG_MICFIL_VAD0_CTRL2*/ +-#define MICFIL_VAD0_CTRL2_FRENDIS_SHIFT 31 +-#define MICFIL_VAD0_CTRL2_FRENDIS_MASK BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT) +-#define MICFIL_VAD0_CTRL2_FRENDIS BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT) +-#define MICFIL_VAD0_CTRL2_PREFEN_SHIFT 30 +-#define MICFIL_VAD0_CTRL2_PREFEN_MASK BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT) +-#define MICFIL_VAD0_CTRL2_PREFEN BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT) +-#define MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT 28 +-#define MICFIL_VAD0_CTRL2_FOUTDIS_MASK BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT) +-#define MICFIL_VAD0_CTRL2_FOUTDIS BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT) ++#define MICFIL_VAD0_CTRL2_FRENDIS BIT(31) ++#define MICFIL_VAD0_CTRL2_PREFEN BIT(30) ++#define MICFIL_VAD0_CTRL2_FOUTDIS BIT(28) + #define MICFIL_VAD0_CTRL2_FRAMET_SHIFT 16 + #define MICFIL_VAD0_CTRL2_FRAMET_WIDTH 6 + #define MICFIL_VAD0_CTRL2_FRAMET_MASK ((BIT(MICFIL_VAD0_CTRL2_FRAMET_WIDTH) - 1) \ +@@ -183,12 +145,8 @@ + & MICFIL_VAD0_CTRL2_HPF_MASK) + + /* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */ +-#define MICFIL_VAD0_SCONFIG_SFILEN_SHIFT 31 +-#define MICFIL_VAD0_SCONFIG_SFILEN_MASK BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT) +-#define MICFIL_VAD0_SCONFIG_SFILEN BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT) +-#define MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT 30 +-#define MICFIL_VAD0_SCONFIG_SMAXEN_MASK BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT) +-#define MICFIL_VAD0_SCONFIG_SMAXEN BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT) ++#define MICFIL_VAD0_SCONFIG_SFILEN BIT(31) ++#define MICFIL_VAD0_SCONFIG_SMAXEN BIT(30) + #define MICFIL_VAD0_SCONFIG_SGAIN_SHIFT 0 + #define MICFIL_VAD0_SCONFIG_SGAIN_WIDTH 4 + #define MICFIL_VAD0_SCONFIG_SGAIN_MASK ((BIT(MICFIL_VAD0_SCONFIG_SGAIN_WIDTH) - 1) \ +@@ -197,17 +155,10 @@ + & MICFIL_VAD0_SCONFIG_SGAIN_MASK) + + /* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */ +-#define MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT 31 +-#define MICFIL_VAD0_NCONFIG_NFILAUT_MASK BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NFILAUT BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NMINEN_SHIFT 30 +-#define MICFIL_VAD0_NCONFIG_NMINEN_MASK BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NMINEN BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NDECEN_SHIFT 29 +-#define MICFIL_VAD0_NCONFIG_NDECEN_MASK BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NDECEN BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NOREN_SHIFT 28 +-#define MICFIL_VAD0_NCONFIG_NOREN BIT(MICFIL_VAD0_NCONFIG_NOREN_SHIFT) ++#define MICFIL_VAD0_NCONFIG_NFILAUT BIT(31) ++#define MICFIL_VAD0_NCONFIG_NMINEN BIT(30) ++#define MICFIL_VAD0_NCONFIG_NDECEN BIT(29) ++#define MICFIL_VAD0_NCONFIG_NOREN BIT(28) + #define MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT 8 + #define MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH 5 + #define MICFIL_VAD0_NCONFIG_NFILADJ_MASK ((BIT(MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH) - 1) \ +@@ -234,29 +185,15 @@ + << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT) + #define MICFIL_VAD0_ZCD_ZCDADJ(v) (((v) << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)\ + & MICFIL_VAD0_ZCD_ZCDADJ_MASK) +-#define MICFIL_VAD0_ZCD_ZCDAND_SHIFT 4 +-#define MICFIL_VAD0_ZCD_ZCDAND_MASK BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDAND BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDAUT_SHIFT 2 +-#define MICFIL_VAD0_ZCD_ZCDAUT_MASK BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDAUT BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDEN_SHIFT 0 +-#define MICFIL_VAD0_ZCD_ZCDEN_MASK BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDEN BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT) ++#define MICFIL_VAD0_ZCD_ZCDAND BIT(4) ++#define MICFIL_VAD0_ZCD_ZCDAUT BIT(2) ++#define MICFIL_VAD0_ZCD_ZCDEN BIT(0) + + /* MICFIL HWVAD0 Status Register - REG_MICFIL_VAD0_STAT */ +-#define MICFIL_VAD0_STAT_INITF_SHIFT 31 +-#define MICFIL_VAD0_STAT_INITF_MASK BIT(MICFIL_VAD0_STAT_INITF_SHIFT) +-#define MICFIL_VAD0_STAT_INITF BIT(MICFIL_VAD0_STAT_INITF_SHIFT) +-#define MICFIL_VAD0_STAT_INSATF_SHIFT 16 +-#define MICFIL_VAD0_STAT_INSATF_MASK BIT(MICFIL_VAD0_STAT_INSATF_SHIFT) +-#define MICFIL_VAD0_STAT_INSATF BIT(MICFIL_VAD0_STAT_INSATF_SHIFT) +-#define MICFIL_VAD0_STAT_EF_SHIFT 15 +-#define MICFIL_VAD0_STAT_EF_MASK BIT(MICFIL_VAD0_STAT_EF_SHIFT) +-#define MICFIL_VAD0_STAT_EF BIT(MICFIL_VAD0_STAT_EF_SHIFT) +-#define MICFIL_VAD0_STAT_IF_SHIFT 0 +-#define MICFIL_VAD0_STAT_IF_MASK BIT(MICFIL_VAD0_STAT_IF_SHIFT) +-#define MICFIL_VAD0_STAT_IF BIT(MICFIL_VAD0_STAT_IF_SHIFT) ++#define MICFIL_VAD0_STAT_INITF BIT(31) ++#define MICFIL_VAD0_STAT_INSATF BIT(16) ++#define MICFIL_VAD0_STAT_EF BIT(15) ++#define MICFIL_VAD0_STAT_IF BIT(0) + + /* MICFIL Output Control Register */ + #define MICFIL_OUTGAIN_CHX_SHIFT(v) (4 * (v)) +-- +2.43.0 + diff --git a/queue-5.10/asoc-fsl_micfil-drop-unnecessary-register-read.patch b/queue-5.10/asoc-fsl_micfil-drop-unnecessary-register-read.patch new file mode 100644 index 00000000000..a78763cc067 --- /dev/null +++ b/queue-5.10/asoc-fsl_micfil-drop-unnecessary-register-read.patch @@ -0,0 +1,37 @@ +From b5802445b960a6ebba764b39ab30f72e30934fbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Apr 2022 18:22:29 +0200 +Subject: ASoC: fsl_micfil: Drop unnecessary register read + +From: Sascha Hauer + +[ Upstream commit c808e277bcdfce37aed80a443be305ac1aec1623 ] + +in get_pdm_clk() REG_MICFIL_CTRL2 is read twice. Drop second read. + +Signed-off-by: Sascha Hauer +Acked-by: Shengjiu Wang +Link: https://lore.kernel.org/r/20220414162249.3934543-2-s.hauer@pengutronix.de +Signed-off-by: Mark Brown +Stable-dep-of: 06df673d2023 ("ASoC: fsl_micfil: fix regmap_write_bits usage") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_micfil.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c +index 826829e3ff7a2..fe6d6c87a1c42 100644 +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -117,8 +117,6 @@ static inline int get_pdm_clk(struct fsl_micfil *micfil, + regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg); + osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK) + >> MICFIL_CTRL2_CICOSR_SHIFT); +- +- regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg); + qsel = ctrl2_reg & MICFIL_CTRL2_QSEL_MASK; + + switch (qsel) { +-- +2.43.0 + diff --git a/queue-5.10/asoc-fsl_micfil-fix-regmap_write_bits-usage.patch b/queue-5.10/asoc-fsl_micfil-fix-regmap_write_bits-usage.patch new file mode 100644 index 00000000000..02c4b572a5b --- /dev/null +++ b/queue-5.10/asoc-fsl_micfil-fix-regmap_write_bits-usage.patch @@ -0,0 +1,47 @@ +From 769e417c9a6314ae8e83522da2349c00777f233d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Sep 2024 16:00:29 +0800 +Subject: ASoC: fsl_micfil: fix regmap_write_bits usage + +From: Shengjiu Wang + +[ Upstream commit 06df673d20230afb0e383e39235a4fa8b9a62464 ] + +The last parameter 1 means BIT(0), which should be the +correct BIT(X). + +Fixes: 47a70e6fc9a8 ("ASoC: Add MICFIL SoC Digital Audio Interface driver.") +Signed-off-by: Shengjiu Wang +Reviewed-by: Daniel Baluta +Link: https://patch.msgid.link/1727424031-19551-2-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_micfil.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c +index 20215303fa34b..9c781d874c309 100644 +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -610,7 +610,7 @@ static irqreturn_t micfil_isr(int irq, void *devid) + regmap_write_bits(micfil->regmap, + REG_MICFIL_STAT, + MICFIL_STAT_CHXF(i), +- 1); ++ MICFIL_STAT_CHXF(i)); + } + + for (i = 0; i < MICFIL_FIFO_NUM; i++) { +@@ -645,7 +645,7 @@ static irqreturn_t micfil_err_isr(int irq, void *devid) + if (stat_reg & MICFIL_STAT_LOWFREQF) { + dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n"); + regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, +- MICFIL_STAT_LOWFREQF, 1); ++ MICFIL_STAT_LOWFREQF, MICFIL_STAT_LOWFREQF); + } + + return IRQ_HANDLED; +-- +2.43.0 + diff --git a/queue-5.10/asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch b/queue-5.10/asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch new file mode 100644 index 00000000000..9b8d58ddedc --- /dev/null +++ b/queue-5.10/asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch @@ -0,0 +1,382 @@ +From c3762b3026edcd296e43f04c2a53f11857b03097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Apr 2022 18:22:33 +0200 +Subject: ASoC: fsl_micfil: use GENMASK to define register bit fields + +From: Sascha Hauer + +[ Upstream commit 17f2142bae4b6f2e27f19ce57d79fc42ba5ef659 ] + +Use GENMASK along with FIELD_PREP and FIELD_GET to access bitfields in +registers to straighten register access and to drop a lot of defines. + +Signed-off-by: Sascha Hauer +Acked-by: Shengjiu Wang +Link: https://lore.kernel.org/r/20220414162249.3934543-6-s.hauer@pengutronix.de +Signed-off-by: Mark Brown +Stable-dep-of: 06df673d2023 ("ASoC: fsl_micfil: fix regmap_write_bits usage") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_micfil.c | 52 ++++++------- + sound/soc/fsl/fsl_micfil.h | 147 ++++++++----------------------------- + 2 files changed, 58 insertions(+), 141 deletions(-) + +diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c +index 13d963a840333..20215303fa34b 100644 +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + // Copyright 2018 NXP + ++#include + #include + #include + #include +@@ -115,23 +116,22 @@ static inline int get_pdm_clk(struct fsl_micfil *micfil, + int bclk; + + regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg); +- osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK) +- >> MICFIL_CTRL2_CICOSR_SHIFT); +- qsel = ctrl2_reg & MICFIL_CTRL2_QSEL_MASK; ++ osr = 16 - FIELD_GET(MICFIL_CTRL2_CICOSR, ctrl2_reg); ++ qsel = FIELD_GET(MICFIL_CTRL2_QSEL, ctrl2_reg); + + switch (qsel) { +- case MICFIL_HIGH_QUALITY: ++ case MICFIL_QSEL_HIGH_QUALITY: + bclk = rate * 8 * osr / 2; /* kfactor = 0.5 */ + break; +- case MICFIL_MEDIUM_QUALITY: +- case MICFIL_VLOW0_QUALITY: ++ case MICFIL_QSEL_MEDIUM_QUALITY: ++ case MICFIL_QSEL_VLOW0_QUALITY: + bclk = rate * 4 * osr * 1; /* kfactor = 1 */ + break; +- case MICFIL_LOW_QUALITY: +- case MICFIL_VLOW1_QUALITY: ++ case MICFIL_QSEL_LOW_QUALITY: ++ case MICFIL_QSEL_VLOW1_QUALITY: + bclk = rate * 2 * osr * 2; /* kfactor = 2 */ + break; +- case MICFIL_VLOW2_QUALITY: ++ case MICFIL_QSEL_VLOW2_QUALITY: + bclk = rate * osr * 4; /* kfactor = 4 */ + break; + default: +@@ -265,8 +265,8 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, + * 11 - reserved + */ + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, +- MICFIL_CTRL1_DISEL_MASK, +- (1 << MICFIL_CTRL1_DISEL_SHIFT)); ++ MICFIL_CTRL1_DISEL, ++ FIELD_PREP(MICFIL_CTRL1_DISEL, MICFIL_CTRL1_DISEL_DMA)); + if (ret) { + dev_err(dev, "failed to update DISEL bits\n"); + return ret; +@@ -295,8 +295,8 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, + } + + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1, +- MICFIL_CTRL1_DISEL_MASK, +- (0 << MICFIL_CTRL1_DISEL_SHIFT)); ++ MICFIL_CTRL1_DISEL, ++ FIELD_PREP(MICFIL_CTRL1_DISEL, MICFIL_CTRL1_DISEL_DISABLE)); + if (ret) { + dev_err(dev, "failed to update DISEL bits\n"); + return ret; +@@ -321,8 +321,8 @@ static int fsl_set_clock_params(struct device *dev, unsigned int rate) + + /* set CICOSR */ + ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, +- MICFIL_CTRL2_CICOSR_MASK, +- MICFIL_CTRL2_OSR_DEFAULT); ++ MICFIL_CTRL2_CICOSR, ++ FIELD_PREP(MICFIL_CTRL2_CICOSR, MICFIL_CTRL2_CICOSR_DEFAULT)); + if (ret) + dev_err(dev, "failed to set CICOSR in reg 0x%X\n", + REG_MICFIL_CTRL2); +@@ -333,7 +333,8 @@ static int fsl_set_clock_params(struct device *dev, unsigned int rate) + ret = -EINVAL; + + ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, +- MICFIL_CTRL2_CLKDIV_MASK, clk_div); ++ MICFIL_CTRL2_CLKDIV, ++ FIELD_PREP(MICFIL_CTRL2_CLKDIV, clk_div)); + if (ret) + dev_err(dev, "failed to set CLKDIV in reg 0x%X\n", + REG_MICFIL_CTRL2); +@@ -409,13 +410,13 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) + { + struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev); + struct device *dev = cpu_dai->dev; +- unsigned int val; + int ret; + int i; + + /* set qsel to medium */ + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, +- MICFIL_CTRL2_QSEL_MASK, MICFIL_MEDIUM_QUALITY); ++ MICFIL_CTRL2_QSEL, ++ FIELD_PREP(MICFIL_CTRL2_QSEL, MICFIL_QSEL_MEDIUM_QUALITY)); + if (ret) { + dev_err(dev, "failed to set quality mode bits, reg 0x%X\n", + REG_MICFIL_CTRL2); +@@ -431,10 +432,9 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) + &micfil->dma_params_rx); + + /* FIFO Watermark Control - FIFOWMK*/ +- val = MICFIL_FIFO_CTRL_FIFOWMK(micfil->soc->fifo_depth) - 1; + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_FIFO_CTRL, +- MICFIL_FIFO_CTRL_FIFOWMK_MASK, +- val); ++ MICFIL_FIFO_CTRL_FIFOWMK, ++ FIELD_PREP(MICFIL_FIFO_CTRL_FIFOWMK, micfil->soc->fifo_depth - 1)); + if (ret) { + dev_err(dev, "failed to set FIFOWMK\n"); + return ret; +@@ -596,11 +596,11 @@ static irqreturn_t micfil_isr(int irq, void *devid) + regmap_read(micfil->regmap, REG_MICFIL_CTRL1, &ctrl1_reg); + regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg); + +- dma_enabled = MICFIL_DMA_ENABLED(ctrl1_reg); ++ dma_enabled = FIELD_GET(MICFIL_CTRL1_DISEL, ctrl1_reg) == MICFIL_CTRL1_DISEL_DMA; + + /* Channel 0-7 Output Data Flags */ + for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) { +- if (stat_reg & MICFIL_STAT_CHXF_MASK(i)) ++ if (stat_reg & MICFIL_STAT_CHXF(i)) + dev_dbg(&pdev->dev, + "Data available in Data Channel %d\n", i); + /* if DMA is not enabled, field must be written with 1 +@@ -609,17 +609,17 @@ static irqreturn_t micfil_isr(int irq, void *devid) + if (!dma_enabled) + regmap_write_bits(micfil->regmap, + REG_MICFIL_STAT, +- MICFIL_STAT_CHXF_MASK(i), ++ MICFIL_STAT_CHXF(i), + 1); + } + + for (i = 0; i < MICFIL_FIFO_NUM; i++) { +- if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER_MASK(i)) ++ if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER(i)) + dev_dbg(&pdev->dev, + "FIFO Overflow Exception flag for channel %d\n", + i); + +- if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(i)) ++ if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER(i)) + dev_dbg(&pdev->dev, + "FIFO Underflow Exception flag for channel %d\n", + i); +diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h +index 11ccc08523b2e..5cecae2519795 100644 +--- a/sound/soc/fsl/fsl_micfil.h ++++ b/sound/soc/fsl/fsl_micfil.h +@@ -39,82 +39,45 @@ + #define MICFIL_CTRL1_DBG BIT(28) + #define MICFIL_CTRL1_SRES BIT(27) + #define MICFIL_CTRL1_DBGE BIT(26) +-#define MICFIL_CTRL1_DISEL_SHIFT 24 +-#define MICFIL_CTRL1_DISEL_WIDTH 2 +-#define MICFIL_CTRL1_DISEL_MASK ((BIT(MICFIL_CTRL1_DISEL_WIDTH) - 1) \ +- << MICFIL_CTRL1_DISEL_SHIFT) ++ ++#define MICFIL_CTRL1_DISEL_DISABLE 0 ++#define MICFIL_CTRL1_DISEL_DMA 1 ++#define MICFIL_CTRL1_DISEL_IRQ 2 ++#define MICFIL_CTRL1_DISEL GENMASK(25, 24) + #define MICFIL_CTRL1_ERREN BIT(23) +-#define MICFIL_CTRL1_CHEN_SHIFT 0 +-#define MICFIL_CTRL1_CHEN_WIDTH 8 +-#define MICFIL_CTRL1_CHEN_MASK(x) (BIT(x) << MICFIL_CTRL1_CHEN_SHIFT) +-#define MICFIL_CTRL1_CHEN(x) (MICFIL_CTRL1_CHEN_MASK(x)) ++#define MICFIL_CTRL1_CHEN(ch) BIT(ch) + + /* MICFIL Control Register 2 -- REG_MICFILL_CTRL2 0x04 */ + #define MICFIL_CTRL2_QSEL_SHIFT 25 +-#define MICFIL_CTRL2_QSEL_WIDTH 3 +-#define MICFIL_CTRL2_QSEL_MASK ((BIT(MICFIL_CTRL2_QSEL_WIDTH) - 1) \ +- << MICFIL_CTRL2_QSEL_SHIFT) +-#define MICFIL_HIGH_QUALITY BIT(MICFIL_CTRL2_QSEL_SHIFT) +-#define MICFIL_MEDIUM_QUALITY (0 << MICFIL_CTRL2_QSEL_SHIFT) +-#define MICFIL_LOW_QUALITY (7 << MICFIL_CTRL2_QSEL_SHIFT) +-#define MICFIL_VLOW0_QUALITY (6 << MICFIL_CTRL2_QSEL_SHIFT) +-#define MICFIL_VLOW1_QUALITY (5 << MICFIL_CTRL2_QSEL_SHIFT) +-#define MICFIL_VLOW2_QUALITY (4 << MICFIL_CTRL2_QSEL_SHIFT) +- +-#define MICFIL_CTRL2_CICOSR_SHIFT 16 +-#define MICFIL_CTRL2_CICOSR_WIDTH 4 +-#define MICFIL_CTRL2_CICOSR_MASK ((BIT(MICFIL_CTRL2_CICOSR_WIDTH) - 1) \ +- << MICFIL_CTRL2_CICOSR_SHIFT) +-#define MICFIL_CTRL2_CICOSR(v) (((v) << MICFIL_CTRL2_CICOSR_SHIFT) \ +- & MICFIL_CTRL2_CICOSR_MASK) +-#define MICFIL_CTRL2_CLKDIV_SHIFT 0 +-#define MICFIL_CTRL2_CLKDIV_WIDTH 8 +-#define MICFIL_CTRL2_CLKDIV_MASK ((BIT(MICFIL_CTRL2_CLKDIV_WIDTH) - 1) \ +- << MICFIL_CTRL2_CLKDIV_SHIFT) +-#define MICFIL_CTRL2_CLKDIV(v) (((v) << MICFIL_CTRL2_CLKDIV_SHIFT) \ +- & MICFIL_CTRL2_CLKDIV_MASK) ++#define MICFIL_CTRL2_QSEL GENMASK(27, 25) ++#define MICFIL_QSEL_MEDIUM_QUALITY 0 ++#define MICFIL_QSEL_HIGH_QUALITY 1 ++#define MICFIL_QSEL_LOW_QUALITY 7 ++#define MICFIL_QSEL_VLOW0_QUALITY 6 ++#define MICFIL_QSEL_VLOW1_QUALITY 5 ++#define MICFIL_QSEL_VLOW2_QUALITY 4 ++ ++#define MICFIL_CTRL2_CICOSR GENMASK(19, 16) ++#define MICFIL_CTRL2_CICOSR_DEFAULT 0 ++#define MICFIL_CTRL2_CLKDIV GENMASK(7, 0) + + /* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */ + #define MICFIL_STAT_BSY_FIL BIT(31) + #define MICFIL_STAT_FIR_RDY BIT(30) + #define MICFIL_STAT_LOWFREQF BIT(29) +-#define MICFIL_STAT_CHXF_SHIFT(v) (v) +-#define MICFIL_STAT_CHXF_MASK(v) BIT(MICFIL_STAT_CHXF_SHIFT(v)) +-#define MICFIL_STAT_CHXF(v) BIT(MICFIL_STAT_CHXF_SHIFT(v)) ++#define MICFIL_STAT_CHXF(ch) BIT(ch) + + /* MICFIL FIFO Control Register -- REG_MICFIL_FIFO_CTRL 0x10 */ +-#define MICFIL_FIFO_CTRL_FIFOWMK_SHIFT 0 +-#define MICFIL_FIFO_CTRL_FIFOWMK_WIDTH 3 +-#define MICFIL_FIFO_CTRL_FIFOWMK_MASK ((BIT(MICFIL_FIFO_CTRL_FIFOWMK_WIDTH) - 1) \ +- << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT) +-#define MICFIL_FIFO_CTRL_FIFOWMK(v) (((v) << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT) \ +- & MICFIL_FIFO_CTRL_FIFOWMK_MASK) ++#define MICFIL_FIFO_CTRL_FIFOWMK GENMASK(2, 0) + + /* MICFIL FIFO Status Register -- REG_MICFIL_FIFO_STAT 0x14 */ +-#define MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v) (v) +-#define MICFIL_FIFO_STAT_FIFOX_OVER_MASK(v) BIT(MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v)) +-#define MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v) ((v) + 8) +-#define MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(v) BIT(MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v)) ++#define MICFIL_FIFO_STAT_FIFOX_OVER(ch) BIT(ch) ++#define MICFIL_FIFO_STAT_FIFOX_UNDER(ch) BIT((ch) + 8) + + /* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/ +-#define MICFIL_VAD0_CTRL1_CHSEL_SHIFT 24 +-#define MICFIL_VAD0_CTRL1_CHSEL_WIDTH 3 +-#define MICFIL_VAD0_CTRL1_CHSEL_MASK ((BIT(MICFIL_VAD0_CTRL1_CHSEL_WIDTH) - 1) \ +- << MICFIL_VAD0_CTRL1_CHSEL_SHIFT) +-#define MICFIL_VAD0_CTRL1_CHSEL(v) (((v) << MICFIL_VAD0_CTRL1_CHSEL_SHIFT) \ +- & MICFIL_VAD0_CTRL1_CHSEL_MASK) +-#define MICFIL_VAD0_CTRL1_CICOSR_SHIFT 16 +-#define MICFIL_VAD0_CTRL1_CICOSR_WIDTH 4 +-#define MICFIL_VAD0_CTRL1_CICOSR_MASK ((BIT(MICFIL_VAD0_CTRL1_CICOSR_WIDTH) - 1) \ +- << MICFIL_VAD0_CTRL1_CICOSR_SHIFT) +-#define MICFIL_VAD0_CTRL1_CICOSR(v) (((v) << MICFIL_VAD0_CTRL1_CICOSR_SHIFT) \ +- & MICFIL_VAD0_CTRL1_CICOSR_MASK) +-#define MICFIL_VAD0_CTRL1_INITT_SHIFT 8 +-#define MICFIL_VAD0_CTRL1_INITT_WIDTH 5 +-#define MICFIL_VAD0_CTRL1_INITT_MASK ((BIT(MICFIL_VAD0_CTRL1_INITT_WIDTH) - 1) \ +- << MICFIL_VAD0_CTRL1_INITT_SHIFT) +-#define MICFIL_VAD0_CTRL1_INITT(v) (((v) << MICFIL_VAD0_CTRL1_INITT_SHIFT) \ +- & MICFIL_VAD0_CTRL1_INITT_MASK) ++#define MICFIL_VAD0_CTRL1_CHSEL_SHIFT GENMASK(26, 24) ++#define MICFIL_VAD0_CTRL1_CICOSR_SHIFT GENMASK(19, 16) ++#define MICFIL_VAD0_CTRL1_INITT_SHIFT GENMASK(12, 8) + #define MICFIL_VAD0_CTRL1_ST10 BIT(4) + #define MICFIL_VAD0_CTRL1_ERIE BIT(3) + #define MICFIL_VAD0_CTRL1_IE BIT(2) +@@ -125,66 +88,26 @@ + #define MICFIL_VAD0_CTRL2_FRENDIS BIT(31) + #define MICFIL_VAD0_CTRL2_PREFEN BIT(30) + #define MICFIL_VAD0_CTRL2_FOUTDIS BIT(28) +-#define MICFIL_VAD0_CTRL2_FRAMET_SHIFT 16 +-#define MICFIL_VAD0_CTRL2_FRAMET_WIDTH 6 +-#define MICFIL_VAD0_CTRL2_FRAMET_MASK ((BIT(MICFIL_VAD0_CTRL2_FRAMET_WIDTH) - 1) \ +- << MICFIL_VAD0_CTRL2_FRAMET_SHIFT) +-#define MICFIL_VAD0_CTRL2_FRAMET(v) (((v) << MICFIL_VAD0_CTRL2_FRAMET_SHIFT) \ +- & MICFIL_VAD0_CTRL2_FRAMET_MASK) +-#define MICFIL_VAD0_CTRL2_INPGAIN_SHIFT 8 +-#define MICFIL_VAD0_CTRL2_INPGAIN_WIDTH 4 +-#define MICFIL_VAD0_CTRL2_INPGAIN_MASK ((BIT(MICFIL_VAD0_CTRL2_INPGAIN_WIDTH) - 1) \ +- << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT) +-#define MICFIL_VAD0_CTRL2_INPGAIN(v) (((v) << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT) \ +- & MICFIL_VAD0_CTRL2_INPGAIN_MASK) +-#define MICFIL_VAD0_CTRL2_HPF_SHIFT 0 +-#define MICFIL_VAD0_CTRL2_HPF_WIDTH 2 +-#define MICFIL_VAD0_CTRL2_HPF_MASK ((BIT(MICFIL_VAD0_CTRL2_HPF_WIDTH) - 1) \ +- << MICFIL_VAD0_CTRL2_HPF_SHIFT) +-#define MICFIL_VAD0_CTRL2_HPF(v) (((v) << MICFIL_VAD0_CTRL2_HPF_SHIFT) \ +- & MICFIL_VAD0_CTRL2_HPF_MASK) ++#define MICFIL_VAD0_CTRL2_FRAMET GENMASK(21, 16) ++#define MICFIL_VAD0_CTRL2_INPGAIN GENMASK(11, 8) ++#define MICFIL_VAD0_CTRL2_HPF GENMASK(1, 0) + + /* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */ + #define MICFIL_VAD0_SCONFIG_SFILEN BIT(31) + #define MICFIL_VAD0_SCONFIG_SMAXEN BIT(30) +-#define MICFIL_VAD0_SCONFIG_SGAIN_SHIFT 0 +-#define MICFIL_VAD0_SCONFIG_SGAIN_WIDTH 4 +-#define MICFIL_VAD0_SCONFIG_SGAIN_MASK ((BIT(MICFIL_VAD0_SCONFIG_SGAIN_WIDTH) - 1) \ +- << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT) +-#define MICFIL_VAD0_SCONFIG_SGAIN(v) (((v) << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT) \ +- & MICFIL_VAD0_SCONFIG_SGAIN_MASK) ++#define MICFIL_VAD0_SCONFIG_SGAIN GENMASK(3, 0) + + /* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */ + #define MICFIL_VAD0_NCONFIG_NFILAUT BIT(31) + #define MICFIL_VAD0_NCONFIG_NMINEN BIT(30) + #define MICFIL_VAD0_NCONFIG_NDECEN BIT(29) + #define MICFIL_VAD0_NCONFIG_NOREN BIT(28) +-#define MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT 8 +-#define MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH 5 +-#define MICFIL_VAD0_NCONFIG_NFILADJ_MASK ((BIT(MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH) - 1) \ +- << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NFILADJ(v) (((v) << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT) \ +- & MICFIL_VAD0_NCONFIG_NFILADJ_MASK) +-#define MICFIL_VAD0_NCONFIG_NGAIN_SHIFT 0 +-#define MICFIL_VAD0_NCONFIG_NGAIN_WIDTH 4 +-#define MICFIL_VAD0_NCONFIG_NGAIN_MASK ((BIT(MICFIL_VAD0_NCONFIG_NGAIN_WIDTH) - 1) \ +- << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT) +-#define MICFIL_VAD0_NCONFIG_NGAIN(v) (((v) << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT) \ +- & MICFIL_VAD0_NCONFIG_NGAIN_MASK) ++#define MICFIL_VAD0_NCONFIG_NFILADJ GENMASK(12, 8) ++#define MICFIL_VAD0_NCONFIG_NGAIN GENMASK(3, 0) + + /* MICFIL HWVAD0 Zero-Crossing Detector - REG_MICFIL_VAD0_ZCD */ +-#define MICFIL_VAD0_ZCD_ZCDTH_SHIFT 16 +-#define MICFIL_VAD0_ZCD_ZCDTH_WIDTH 10 +-#define MICFIL_VAD0_ZCD_ZCDTH_MASK ((BIT(MICFIL_VAD0_ZCD_ZCDTH_WIDTH) - 1) \ +- << MICFIL_VAD0_ZCD_ZCDTH_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDTH(v) (((v) << MICFIL_VAD0_ZCD_ZCDTH_SHIFT)\ +- & MICFIL_VAD0_ZCD_ZCDTH_MASK) +-#define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT 8 +-#define MICFIL_VAD0_ZCD_ZCDADJ_WIDTH 4 +-#define MICFIL_VAD0_ZCD_ZCDADJ_MASK ((BIT(MICFIL_VAD0_ZCD_ZCDADJ_WIDTH) - 1)\ +- << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT) +-#define MICFIL_VAD0_ZCD_ZCDADJ(v) (((v) << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)\ +- & MICFIL_VAD0_ZCD_ZCDADJ_MASK) ++#define MICFIL_VAD0_ZCD_ZCDTH GENMASK(25, 16) ++#define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT GENMASK(11, 8) + #define MICFIL_VAD0_ZCD_ZCDAND BIT(4) + #define MICFIL_VAD0_ZCD_ZCDAUT BIT(2) + #define MICFIL_VAD0_ZCD_ZCDEN BIT(0) +@@ -199,11 +122,6 @@ + #define MICFIL_OUTGAIN_CHX_SHIFT(v) (4 * (v)) + + /* Constants */ +-#define MICFIL_DMA_IRQ_DISABLED(v) ((v) & MICFIL_CTRL1_DISEL_MASK) +-#define MICFIL_DMA_ENABLED(v) ((0x1 << MICFIL_CTRL1_DISEL_SHIFT) \ +- == ((v) & MICFIL_CTRL1_DISEL_MASK)) +-#define MICFIL_IRQ_ENABLED(v) ((0x2 << MICFIL_CTRL1_DISEL_SHIFT) \ +- == ((v) & MICFIL_CTRL1_DISEL_MASK)) + #define MICFIL_OUTPUT_CHANNELS 8 + #define MICFIL_FIFO_NUM 8 + +@@ -215,6 +133,5 @@ + #define MICFIL_SLEEP_MIN 90000 /* in us */ + #define MICFIL_SLEEP_MAX 100000 /* in us */ + #define MICFIL_DMA_MAXBURST_RX 6 +-#define MICFIL_CTRL2_OSR_DEFAULT (0 << MICFIL_CTRL2_CICOSR_SHIFT) + + #endif /* _FSL_MICFIL_H */ +-- +2.43.0 + diff --git a/queue-5.10/bluetooth-fix-use-after-free-in-device_for_each_chil.patch b/queue-5.10/bluetooth-fix-use-after-free-in-device_for_each_chil.patch new file mode 100644 index 00000000000..25e1df57451 --- /dev/null +++ b/queue-5.10/bluetooth-fix-use-after-free-in-device_for_each_chil.patch @@ -0,0 +1,150 @@ +From 34f70e4d88b7ce406521458dc9c174cb788dfa97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Nov 2024 14:44:10 +0300 +Subject: Bluetooth: fix use-after-free in device_for_each_child() + +From: Dmitry Antipov + +[ Upstream commit 27aabf27fd014ae037cc179c61b0bee7cff55b3d ] + +Syzbot has reported the following KASAN splat: + +BUG: KASAN: slab-use-after-free in device_for_each_child+0x18f/0x1a0 +Read of size 8 at addr ffff88801f605308 by task kbnepd bnep0/4980 + +CPU: 0 UID: 0 PID: 4980 Comm: kbnepd bnep0 Not tainted 6.12.0-rc4-00161-gae90f6a6170d #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 +Call Trace: + + dump_stack_lvl+0x100/0x190 + ? device_for_each_child+0x18f/0x1a0 + print_report+0x13a/0x4cb + ? __virt_addr_valid+0x5e/0x590 + ? __phys_addr+0xc6/0x150 + ? device_for_each_child+0x18f/0x1a0 + kasan_report+0xda/0x110 + ? device_for_each_child+0x18f/0x1a0 + ? __pfx_dev_memalloc_noio+0x10/0x10 + device_for_each_child+0x18f/0x1a0 + ? __pfx_device_for_each_child+0x10/0x10 + pm_runtime_set_memalloc_noio+0xf2/0x180 + netdev_unregister_kobject+0x1ed/0x270 + unregister_netdevice_many_notify+0x123c/0x1d80 + ? __mutex_trylock_common+0xde/0x250 + ? __pfx_unregister_netdevice_many_notify+0x10/0x10 + ? trace_contention_end+0xe6/0x140 + ? __mutex_lock+0x4e7/0x8f0 + ? __pfx_lock_acquire.part.0+0x10/0x10 + ? rcu_is_watching+0x12/0xc0 + ? unregister_netdev+0x12/0x30 + unregister_netdevice_queue+0x30d/0x3f0 + ? __pfx_unregister_netdevice_queue+0x10/0x10 + ? __pfx_down_write+0x10/0x10 + unregister_netdev+0x1c/0x30 + bnep_session+0x1fb3/0x2ab0 + ? __pfx_bnep_session+0x10/0x10 + ? __pfx_lock_release+0x10/0x10 + ? __pfx_woken_wake_function+0x10/0x10 + ? __kthread_parkme+0x132/0x200 + ? __pfx_bnep_session+0x10/0x10 + ? kthread+0x13a/0x370 + ? __pfx_bnep_session+0x10/0x10 + kthread+0x2b7/0x370 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x48/0x80 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1a/0x30 + + +Allocated by task 4974: + kasan_save_stack+0x30/0x50 + kasan_save_track+0x14/0x30 + __kasan_kmalloc+0xaa/0xb0 + __kmalloc_noprof+0x1d1/0x440 + hci_alloc_dev_priv+0x1d/0x2820 + __vhci_create_device+0xef/0x7d0 + vhci_write+0x2c7/0x480 + vfs_write+0x6a0/0xfc0 + ksys_write+0x12f/0x260 + do_syscall_64+0xc7/0x250 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Freed by task 4979: + kasan_save_stack+0x30/0x50 + kasan_save_track+0x14/0x30 + kasan_save_free_info+0x3b/0x60 + __kasan_slab_free+0x4f/0x70 + kfree+0x141/0x490 + hci_release_dev+0x4d9/0x600 + bt_host_release+0x6a/0xb0 + device_release+0xa4/0x240 + kobject_put+0x1ec/0x5a0 + put_device+0x1f/0x30 + vhci_release+0x81/0xf0 + __fput+0x3f6/0xb30 + task_work_run+0x151/0x250 + do_exit+0xa79/0x2c30 + do_group_exit+0xd5/0x2a0 + get_signal+0x1fcd/0x2210 + arch_do_signal_or_restart+0x93/0x780 + syscall_exit_to_user_mode+0x140/0x290 + do_syscall_64+0xd4/0x250 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +In 'hci_conn_del_sysfs()', 'device_unregister()' may be called when +an underlying (kobject) reference counter is greater than 1. This +means that reparenting (happened when the device is actually freed) +is delayed and, during that delay, parent controller device (hciX) +may be deleted. Since the latter may create a dangling pointer to +freed parent, avoid that scenario by reparenting to NULL explicitly. + +Reported-by: syzbot+6cf5652d3df49fae2e3f@syzkaller.appspotmail.com +Tested-by: syzbot+6cf5652d3df49fae2e3f@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=6cf5652d3df49fae2e3f +Fixes: a85fb91e3d72 ("Bluetooth: Fix double free in hci_conn_cleanup") +Signed-off-by: Dmitry Antipov +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_sysfs.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c +index 266112c960ee8..1b4d81ffb4b5e 100644 +--- a/net/bluetooth/hci_sysfs.c ++++ b/net/bluetooth/hci_sysfs.c +@@ -19,16 +19,6 @@ static const struct device_type bt_link = { + .release = bt_link_release, + }; + +-/* +- * The rfcomm tty device will possibly retain even when conn +- * is down, and sysfs doesn't support move zombie device, +- * so we should move the device before conn device is destroyed. +- */ +-static int __match_tty(struct device *dev, void *data) +-{ +- return !strncmp(dev_name(dev), "rfcomm", 6); +-} +- + void hci_conn_init_sysfs(struct hci_conn *conn) + { + struct hci_dev *hdev = conn->hdev; +@@ -71,10 +61,13 @@ void hci_conn_del_sysfs(struct hci_conn *conn) + return; + } + ++ /* If there are devices using the connection as parent reset it to NULL ++ * before unregistering the device. ++ */ + while (1) { + struct device *dev; + +- dev = device_find_child(&conn->dev, NULL, __match_tty); ++ dev = device_find_any_child(&conn->dev); + if (!dev) + break; + device_move(dev, NULL, DPM_ORDER_DEV_LAST); +-- +2.43.0 + diff --git a/queue-5.10/bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch b/queue-5.10/bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch new file mode 100644 index 00000000000..6f0f48c0abb --- /dev/null +++ b/queue-5.10/bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch @@ -0,0 +1,54 @@ +From e22afc5de7a54bc63db5601f7e5088366bd0a0a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 14:45:41 -0800 +Subject: bnxt_en: Reserve rings after PCIe AER recovery if NIC interface is + down + +From: Saravanan Vajravel + +[ Upstream commit 5311598f7f3293683cdc761df71ae3469327332c ] + +After successful PCIe AER recovery, FW will reset all resource +reservations. If it is IF_UP, the driver will call bnxt_open() and +all resources will be reserved again. It it is IF_DOWN, we should +call bnxt_reserve_rings() so that we can reserve resources including +RoCE resources to allow RoCE to resume after AER. Without this +patch, RoCE fails to resume in this IF_DOWN scenario. + +Later, if it becomes IF_UP, bnxt_open() will see that resources have +been reserved and will not reserve again. + +Fixes: fb1e6e562b37 ("bnxt_en: Fix AER recovery.") +Reviewed-by: Somnath Kotur +Reviewed-by: Pavan Chebbi +Reviewed-by: Kashyap Desai +Signed-off-by: Saravanan Vajravel +Signed-off-by: Michael Chan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 059552f4154d1..40c53404bccbb 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -13107,8 +13107,12 @@ static void bnxt_io_resume(struct pci_dev *pdev) + rtnl_lock(); + + err = bnxt_hwrm_func_qcaps(bp); +- if (!err && netif_running(netdev)) +- err = bnxt_open(netdev); ++ if (!err) { ++ if (netif_running(netdev)) ++ err = bnxt_open(netdev); ++ else ++ err = bnxt_reserve_rings(bp, true); ++ } + + bnxt_ulp_start(bp, err); + if (!err) { +-- +2.43.0 + diff --git a/queue-5.10/bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch b/queue-5.10/bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch new file mode 100644 index 00000000000..53dae822368 --- /dev/null +++ b/queue-5.10/bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch @@ -0,0 +1,41 @@ +From 2a7f254ced814fe40e9a6e4e4d387797c214433b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 10:41:15 +0800 +Subject: bpf: Fix the xdp_adjust_tail sample prog issue + +From: Yuan Chen + +[ Upstream commit 4236f114a3ffbbfd217436c08852e94cae372f57 ] + +During the xdp_adjust_tail test, probabilistic failure occurs and SKB package +is discarded by the kernel. After checking the issues by tracking SKB package, +it is identified that they were caused by checksum errors. Refer to checksum +of the arch/arm64/include/asm/checksum.h for fixing. + +v2: Based on Alexei Starovoitov's suggestions, it is necessary to keep the code + implementation consistent. + +Fixes: c6ffd1ff7856 (bpf: add bpf_xdp_adjust_tail sample prog) +Signed-off-by: Yuan Chen +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20240930024115.52841-1-chenyuan_fl@163.com +Signed-off-by: Sasha Levin +--- + samples/bpf/xdp_adjust_tail_kern.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/samples/bpf/xdp_adjust_tail_kern.c b/samples/bpf/xdp_adjust_tail_kern.c +index ffdd548627f0a..da67bcad1c638 100644 +--- a/samples/bpf/xdp_adjust_tail_kern.c ++++ b/samples/bpf/xdp_adjust_tail_kern.c +@@ -57,6 +57,7 @@ static __always_inline void swap_mac(void *data, struct ethhdr *orig_eth) + + static __always_inline __u16 csum_fold_helper(__u32 csum) + { ++ csum = (csum & 0xffff) + (csum >> 16); + return ~((csum & 0xffff) + (csum >> 16)); + } + +-- +2.43.0 + diff --git a/queue-5.10/bpf-sockmap-fix-sk_msg_reset_curr.patch b/queue-5.10/bpf-sockmap-fix-sk_msg_reset_curr.patch new file mode 100644 index 00000000000..daf52ff5051 --- /dev/null +++ b/queue-5.10/bpf-sockmap-fix-sk_msg_reset_curr.patch @@ -0,0 +1,70 @@ +From 67ec108ab8ba5d76050751216a9b5836345dbb35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:20 +0000 +Subject: bpf, sockmap: Fix sk_msg_reset_curr + +From: Zijian Zhang + +[ Upstream commit 955afd57dc4bf7e8c620a0a9e3af3c881c2c6dff ] + +Found in the test_txmsg_pull in test_sockmap, +``` +txmsg_cork = 512; // corking is importrant here +opt->iov_length = 3; +opt->iov_count = 1; +opt->rate = 512; // sendmsg will be invoked 512 times +``` +The first sendmsg will send an sk_msg with size 3, and bpf_msg_pull_data +will be invoked the first time. sk_msg_reset_curr will reset the copybreak +from 3 to 0. In the second sendmsg, since we are in the stage of corking, +psock->cork will be reused in func sk_msg_alloc. msg->sg.copybreak is 0 +now, the second msg will overwrite the first msg. As a result, we could +not pass the data integrity test. + +The same problem happens in push and pop test. Thus, fix sk_msg_reset_curr +to restore the correct copybreak. + +Fixes: bb9aefde5bba ("bpf: sockmap, updating the sg structure should also update curr") +Signed-off-by: Zijian Zhang +Link: https://lore.kernel.org/r/20241106222520.527076-9-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 345e6c5c71f06..0b61575df86ee 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2600,18 +2600,16 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes) + + static void sk_msg_reset_curr(struct sk_msg *msg) + { +- u32 i = msg->sg.start; +- u32 len = 0; +- +- do { +- len += sk_msg_elem(msg, i)->length; +- sk_msg_iter_var_next(i); +- if (len >= msg->sg.size) +- break; +- } while (i != msg->sg.end); ++ if (!msg->sg.size) { ++ msg->sg.curr = msg->sg.start; ++ msg->sg.copybreak = 0; ++ } else { ++ u32 i = msg->sg.end; + +- msg->sg.curr = i; +- msg->sg.copybreak = 0; ++ sk_msg_iter_var_prev(i); ++ msg->sg.curr = i; ++ msg->sg.copybreak = msg->sg.data[i].length; ++ } + } + + static const struct bpf_func_proto bpf_msg_cork_bytes_proto = { +-- +2.43.0 + diff --git a/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch b/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch new file mode 100644 index 00000000000..54807332f8e --- /dev/null +++ b/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch @@ -0,0 +1,104 @@ +From d46d712c5139f3a3f97a82ba4998985c68d0c1a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:19 +0000 +Subject: bpf, sockmap: Several fixes to bpf_msg_pop_data + +From: Zijian Zhang + +[ Upstream commit 5d609ba262475db450ba69b8e8a557bd768ac07a ] + +Several fixes to bpf_msg_pop_data, +1. In sk_msg_shift_left, we should put_page +2. if (len == 0), return early is better +3. pop the entire sk_msg (last == msg->sg.size) should be supported +4. Fix for the value of variable "a" +5. In sk_msg_shift_left, after shifting, i has already pointed to the next +element. Addtional sk_msg_iter_var_next may result in BUG. + +Fixes: 7246d8ed4dcc ("bpf: helper to pop data from messages") +Signed-off-by: Zijian Zhang +Reviewed-by: John Fastabend +Link: https://lore.kernel.org/r/20241106222520.527076-8-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 0ef77fb72af78..345e6c5c71f06 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2900,8 +2900,10 @@ static const struct bpf_func_proto bpf_msg_push_data_proto = { + + static void sk_msg_shift_left(struct sk_msg *msg, int i) + { ++ struct scatterlist *sge = sk_msg_elem(msg, i); + int prev; + ++ put_page(sg_page(sge)); + do { + prev = i; + sk_msg_iter_var_next(i); +@@ -2938,6 +2940,9 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + if (unlikely(flags)) + return -EINVAL; + ++ if (unlikely(len == 0)) ++ return 0; ++ + /* First find the starting scatterlist element */ + i = msg->sg.start; + do { +@@ -2950,7 +2955,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + } while (i != msg->sg.end); + + /* Bounds checks: start and pop must be inside message */ +- if (start >= offset + l || last >= msg->sg.size) ++ if (start >= offset + l || last > msg->sg.size) + return -EINVAL; + + space = MAX_MSG_FRAGS - sk_msg_elem_used(msg); +@@ -2979,12 +2984,12 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + */ + if (start != offset) { + struct scatterlist *nsge, *sge = sk_msg_elem(msg, i); +- int a = start; ++ int a = start - offset; + int b = sge->length - pop - a; + + sk_msg_iter_var_next(i); + +- if (pop < sge->length - a) { ++ if (b > 0) { + if (space) { + sge->length = a; + sk_msg_shift_right(msg, i); +@@ -3003,7 +3008,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + if (unlikely(!page)) + return -ENOMEM; + +- sge->length = a; + orig = sg_page(sge); + from = sg_virt(sge); + to = page_address(page); +@@ -3013,7 +3017,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + put_page(orig); + } + pop = 0; +- } else if (pop >= sge->length - a) { ++ } else { + pop -= (sge->length - a); + sge->length = a; + } +@@ -3047,7 +3051,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, + pop -= sge->length; + sk_msg_shift_left(msg, i); + } +- sk_msg_iter_var_next(i); + } + + sk_mem_uncharge(msg->sk, len - pop); +-- +2.43.0 + diff --git a/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch b/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch new file mode 100644 index 00000000000..433f48a27fa --- /dev/null +++ b/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch @@ -0,0 +1,132 @@ +From 7e741fd88f8e01cc0bbfcbf410983c9892fc432e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:18 +0000 +Subject: bpf, sockmap: Several fixes to bpf_msg_push_data + +From: Zijian Zhang + +[ Upstream commit 15ab0548e3107665c34579ae523b2b6e7c22082a ] + +Several fixes to bpf_msg_push_data, +1. test_sockmap has tests where bpf_msg_push_data is invoked to push some +data at the end of a message, but -EINVAL is returned. In this case, in +bpf_msg_push_data, after the first loop, i will be set to msg->sg.end, add +the logic to handle it. +2. In the code block of "if (start - offset)", it's possible that "i" +points to the last of sk_msg_elem. In this case, "sk_msg_iter_next(msg, +end)" might still be called twice, another invoking is in "if (!copy)" +code block, but actually only one is needed. Add the logic to handle it, +and reconstruct the code to make the logic more clear. + +Fixes: 6fff607e2f14 ("bpf: sk_msg program helper bpf_msg_push_data") +Signed-off-by: Zijian Zhang +Link: https://lore.kernel.org/r/20241106222520.527076-7-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 53 +++++++++++++++++++++++++++++------------------ + 1 file changed, 33 insertions(+), 20 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 99fdd8afeeda3..0ef77fb72af78 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2774,7 +2774,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, + sk_msg_iter_var_next(i); + } while (i != msg->sg.end); + +- if (start >= offset + l) ++ if (start > offset + l) + return -EINVAL; + + space = MAX_MSG_FRAGS - sk_msg_elem_used(msg); +@@ -2799,6 +2799,8 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, + + raw = page_address(page); + ++ if (i == msg->sg.end) ++ sk_msg_iter_var_prev(i); + psge = sk_msg_elem(msg, i); + front = start - offset; + back = psge->length - front; +@@ -2815,7 +2817,13 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, + } + + put_page(sg_page(psge)); +- } else if (start - offset) { ++ new = i; ++ goto place_new; ++ } ++ ++ if (start - offset) { ++ if (i == msg->sg.end) ++ sk_msg_iter_var_prev(i); + psge = sk_msg_elem(msg, i); + rsge = sk_msg_elem_cpy(msg, i); + +@@ -2826,39 +2834,44 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, + sk_msg_iter_var_next(i); + sg_unmark_end(psge); + sg_unmark_end(&rsge); +- sk_msg_iter_next(msg, end); + } + + /* Slot(s) to place newly allocated data */ ++ sk_msg_iter_next(msg, end); + new = i; ++ sk_msg_iter_var_next(i); ++ ++ if (i == msg->sg.end) { ++ if (!rsge.length) ++ goto place_new; ++ sk_msg_iter_next(msg, end); ++ goto place_new; ++ } + + /* Shift one or two slots as needed */ +- if (!copy) { +- sge = sk_msg_elem_cpy(msg, i); ++ sge = sk_msg_elem_cpy(msg, new); ++ sg_unmark_end(&sge); + ++ nsge = sk_msg_elem_cpy(msg, i); ++ if (rsge.length) { + sk_msg_iter_var_next(i); +- sg_unmark_end(&sge); ++ nnsge = sk_msg_elem_cpy(msg, i); + sk_msg_iter_next(msg, end); ++ } + +- nsge = sk_msg_elem_cpy(msg, i); ++ while (i != msg->sg.end) { ++ msg->sg.data[i] = sge; ++ sge = nsge; ++ sk_msg_iter_var_next(i); + if (rsge.length) { +- sk_msg_iter_var_next(i); ++ nsge = nnsge; + nnsge = sk_msg_elem_cpy(msg, i); +- } +- +- while (i != msg->sg.end) { +- msg->sg.data[i] = sge; +- sge = nsge; +- sk_msg_iter_var_next(i); +- if (rsge.length) { +- nsge = nnsge; +- nnsge = sk_msg_elem_cpy(msg, i); +- } else { +- nsge = sk_msg_elem_cpy(msg, i); +- } ++ } else { ++ nsge = sk_msg_elem_cpy(msg, i); + } + } + ++place_new: + /* Place newly allocated data buffer */ + sk_mem_charge(msg->sk, len); + msg->sg.size += len; +-- +2.43.0 + diff --git a/queue-5.10/cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch b/queue-5.10/cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch new file mode 100644 index 00000000000..6f573797012 --- /dev/null +++ b/queue-5.10/cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch @@ -0,0 +1,70 @@ +From 08aa2b37f0f4c310180b634aced6b162803cd609 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 08:15:20 +0000 +Subject: cgroup/bpf: only cgroup v2 can be attached by bpf programs + +From: Chen Ridong + +[ Upstream commit 2190df6c91373fdec6db9fc07e427084f232f57e ] + +Only cgroup v2 can be attached by bpf programs, so this patch introduces +that cgroup_bpf_inherit and cgroup_bpf_offline can only be called in +cgroup v2, and this can fix the memleak mentioned by commit 04f8ef5643bc +("cgroup: Fix memory leak caused by missing cgroup_bpf_offline"), which +has been reverted. + +Fixes: 2b0d3d3e4fcf ("percpu_ref: reduce memory footprint of percpu_ref in fast path") +Fixes: 4bfc0bb2c60e ("bpf: decouple the lifetime of cgroup_bpf from cgroup itself") +Link: https://lore.kernel.org/cgroups/aka2hk5jsel5zomucpwlxsej6iwnfw4qu5jkrmjhyfhesjlfdw@46zxhg5bdnr7/ +Signed-off-by: Chen Ridong +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cgroup.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index c5e51bad62473..efeb0b7427501 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -2018,8 +2018,10 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask) + if (ret) + goto destroy_root; + +- ret = cgroup_bpf_inherit(root_cgrp); +- WARN_ON_ONCE(ret); ++ if (root == &cgrp_dfl_root) { ++ ret = cgroup_bpf_inherit(root_cgrp); ++ WARN_ON_ONCE(ret); ++ } + + trace_cgroup_setup_root(root); + +@@ -5355,9 +5357,11 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, + if (ret) + goto out_kernfs_remove; + +- ret = cgroup_bpf_inherit(cgrp); +- if (ret) +- goto out_psi_free; ++ if (cgrp->root == &cgrp_dfl_root) { ++ ret = cgroup_bpf_inherit(cgrp); ++ if (ret) ++ goto out_psi_free; ++ } + + /* + * New cgroup inherits effective freeze counter, and +@@ -5676,7 +5680,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) + + cgroup1_check_for_release(parent); + +- cgroup_bpf_offline(cgrp); ++ if (cgrp->root == &cgrp_dfl_root) ++ cgroup_bpf_offline(cgrp); + + /* put the base reference */ + percpu_ref_kill(&cgrp->self.refcnt); +-- +2.43.0 + diff --git a/queue-5.10/clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch b/queue-5.10/clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch new file mode 100644 index 00000000000..9edb356241e --- /dev/null +++ b/queue-5.10/clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch @@ -0,0 +1,47 @@ +From 7e6df323d0511605bd750c6016a8a2afbbe44aaa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Feb 2021 17:12:45 +0200 +Subject: clk: axi-clkgen: use devm_platform_ioremap_resource() short-hand + +From: Alexandru Ardelean + +[ Upstream commit 6ba7ea7630fb03c1ce01508bdf89f5bb39b38e54 ] + +No major functional change. Noticed while checking the driver code that +this could be used. +Saves two lines. + +Signed-off-by: Alexandru Ardelean +Link: https://lore.kernel.org/r/20210201151245.21845-5-alexandru.ardelean@analog.com +Signed-off-by: Stephen Boyd +Stable-dep-of: c64ef7e4851d ("clk: clk-axi-clkgen: make sure to enable the AXI bus clock") +Signed-off-by: Sasha Levin +--- + drivers/clk/clk-axi-clkgen.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c +index 14d803e6af623..1aa3d9fd8d0ac 100644 +--- a/drivers/clk/clk-axi-clkgen.c ++++ b/drivers/clk/clk-axi-clkgen.c +@@ -497,7 +497,6 @@ static int axi_clkgen_probe(struct platform_device *pdev) + struct clk_init_data init; + const char *parent_names[2]; + const char *clk_name; +- struct resource *mem; + unsigned int i; + int ret; + +@@ -512,8 +511,7 @@ static int axi_clkgen_probe(struct platform_device *pdev) + if (!axi_clkgen) + return -ENOMEM; + +- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); ++ axi_clkgen->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(axi_clkgen->base)) + return PTR_ERR(axi_clkgen->base); + +-- +2.43.0 + diff --git a/queue-5.10/clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch b/queue-5.10/clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch new file mode 100644 index 00000000000..64d7d9239db --- /dev/null +++ b/queue-5.10/clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch @@ -0,0 +1,82 @@ +From bb5ca78ce0ee4e6fb3da5731b726a44cb4b9d668 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 14:59:42 +0100 +Subject: clk: clk-axi-clkgen: make sure to enable the AXI bus clock + +From: Nuno Sa + +[ Upstream commit c64ef7e4851d1a9abbb7f7833e4936973ac5ba79 ] + +In order to access the registers of the HW, we need to make sure that +the AXI bus clock is enabled. Hence let's increase the number of clocks +by one. + +In order to keep backward compatibility and make sure old DTs still work +we check if clock-names is available or not. If it is, then we can +disambiguate between really having the AXI clock or a parent clock and +so we can enable the bus clock. If not, we fallback to what was done +before and don't explicitly enable the AXI bus clock. + +Note that if clock-names is given, the axi clock must be the last one in +the phandle array (also enforced in the DT bindings) so that we can reuse +as much code as possible. + +Fixes: 0e646c52cf0e ("clk: Add axi-clkgen driver") +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20241029-axi-clkgen-fix-axiclk-v2-2-bc5e0733ad76@analog.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/clk-axi-clkgen.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c +index 1aa3d9fd8d0ac..3e2cf1fad262e 100644 +--- a/drivers/clk/clk-axi-clkgen.c ++++ b/drivers/clk/clk-axi-clkgen.c +@@ -7,6 +7,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -497,6 +498,7 @@ static int axi_clkgen_probe(struct platform_device *pdev) + struct clk_init_data init; + const char *parent_names[2]; + const char *clk_name; ++ struct clk *axi_clk; + unsigned int i; + int ret; + +@@ -516,8 +518,24 @@ static int axi_clkgen_probe(struct platform_device *pdev) + return PTR_ERR(axi_clkgen->base); + + init.num_parents = of_clk_get_parent_count(pdev->dev.of_node); +- if (init.num_parents < 1 || init.num_parents > 2) +- return -EINVAL; ++ ++ axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); ++ if (!IS_ERR(axi_clk)) { ++ if (init.num_parents < 2 || init.num_parents > 3) ++ return -EINVAL; ++ ++ init.num_parents -= 1; ++ } else { ++ /* ++ * Legacy... So that old DTs which do not have clock-names still ++ * work. In this case we don't explicitly enable the AXI bus ++ * clock. ++ */ ++ if (PTR_ERR(axi_clk) != -ENOENT) ++ return PTR_ERR(axi_clk); ++ if (init.num_parents < 1 || init.num_parents > 2) ++ return -EINVAL; ++ } + + for (i = 0; i < init.num_parents; i++) { + parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i); +-- +2.43.0 + diff --git a/queue-5.10/clkdev-remove-config_clkdev_lookup.patch b/queue-5.10/clkdev-remove-config_clkdev_lookup.patch new file mode 100644 index 00000000000..f6851134eaa --- /dev/null +++ b/queue-5.10/clkdev-remove-config_clkdev_lookup.patch @@ -0,0 +1,286 @@ +From 1480321fd75393ab5c065a8b5aa424b228597e23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 May 2021 11:48:49 +0200 +Subject: clkdev: remove CONFIG_CLKDEV_LOOKUP + +From: Arnd Bergmann + +[ Upstream commit 2f4574dd6dd19eb3e8ab0415a3ae960d04be3a65 ] + +This option is now synonymous with CONFIG_HAVE_CLK, so use +the latter globally. Any out-of-tree platform ports that +still use a private clk_get()/clk_put() implementation should +move to CONFIG_COMMON_CLK. + +Signed-off-by: Arnd Bergmann +Stable-dep-of: 0309f714a090 ("clocksource/drivers:sp804: Make user selectable") +Signed-off-by: Sasha Levin +--- + arch/arm/Kconfig | 2 -- + arch/mips/Kconfig | 3 --- + arch/mips/pic32/Kconfig | 1 - + arch/sh/Kconfig | 1 - + drivers/clk/Kconfig | 6 +----- + drivers/clk/Makefile | 3 +-- + drivers/clocksource/Kconfig | 6 +++--- + drivers/mmc/host/Kconfig | 4 ++-- + drivers/staging/board/Kconfig | 2 +- + sound/soc/dwc/Kconfig | 2 +- + sound/soc/rockchip/Kconfig | 14 +++++++------- + 11 files changed, 16 insertions(+), 28 deletions(-) + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 335308aff6ce0..27db1bddfb6c5 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -366,7 +366,6 @@ config ARCH_EP93XX + imply ARM_PATCH_PHYS_VIRT + select ARM_VIC + select AUTO_ZRELADDR +- select CLKDEV_LOOKUP + select CLKSRC_MMIO + select CPU_ARM920T + select GENERIC_CLOCKEVENTS +@@ -523,7 +522,6 @@ config ARCH_OMAP1 + bool "TI OMAP1" + depends on MMU + select ARCH_OMAP +- select CLKDEV_LOOKUP + select CLKSRC_MMIO + select GENERIC_CLOCKEVENTS + select GENERIC_IRQ_CHIP +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index 57839f63074f7..7aeb3a7d4926d 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -327,7 +327,6 @@ config BCM63XX + select SWAP_IO_SPACE + select GPIOLIB + select MIPS_L1_CACHE_SHIFT_4 +- select CLKDEV_LOOKUP + select HAVE_LEGACY_CLK + help + Support for BCM63XX based boards +@@ -442,7 +441,6 @@ config LANTIQ + select GPIOLIB + select SWAP_IO_SPACE + select BOOT_RAW +- select CLKDEV_LOOKUP + select HAVE_LEGACY_CLK + select USE_OF + select PINCTRL +@@ -627,7 +625,6 @@ config RALINK + select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_ZBOOT + select SYS_HAS_EARLY_PRINTK +- select CLKDEV_LOOKUP + select ARCH_HAS_RESET_CONTROLLER + select RESET_CONTROLLER + +diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig +index 7acbb50c1dcd5..bb6ab1f3e80dc 100644 +--- a/arch/mips/pic32/Kconfig ++++ b/arch/mips/pic32/Kconfig +@@ -17,7 +17,6 @@ config PIC32MZDA + select SYS_SUPPORTS_LITTLE_ENDIAN + select GPIOLIB + select COMMON_CLK +- select CLKDEV_LOOKUP + select LIBFDT + select USE_OF + select PINCTRL +diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig +index 44dffe7ce50ad..51f9ca675c416 100644 +--- a/arch/sh/Kconfig ++++ b/arch/sh/Kconfig +@@ -13,7 +13,6 @@ config SUPERH + select ARCH_HIBERNATION_POSSIBLE if MMU + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_WANT_IPC_PARSE_VERSION +- select CLKDEV_LOOKUP + select CPU_NO_EFFICIENT_FFS + select DMA_DECLARE_COHERENT + select GENERIC_ATOMIC64 +diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig +index df739665f2063..1a4cd684a4371 100644 +--- a/drivers/clk/Kconfig ++++ b/drivers/clk/Kconfig +@@ -6,10 +6,6 @@ config HAVE_CLK + The calls support software clock gating and + thus are a key power management tool on many systems. + +-config CLKDEV_LOOKUP +- bool +- select HAVE_CLK +- + config HAVE_CLK_PREPARE + bool + +@@ -26,7 +22,7 @@ menuconfig COMMON_CLK + bool "Common Clock Framework" + depends on !HAVE_LEGACY_CLK + select HAVE_CLK_PREPARE +- select CLKDEV_LOOKUP ++ select HAVE_CLK + select SRCU + select RATIONAL + help +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index da8fcf147eb13..707b592333918 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -1,7 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + # common clock types +-obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o +-obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o ++obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o + obj-$(CONFIG_COMMON_CLK) += clk.o + obj-$(CONFIG_COMMON_CLK) += clk-divider.o + obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o +diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig +index a0c6e88bebe08..be4bb4008d6e6 100644 +--- a/drivers/clocksource/Kconfig ++++ b/drivers/clocksource/Kconfig +@@ -399,7 +399,7 @@ config ARM_GLOBAL_TIMER + + config ARM_TIMER_SP804 + bool "Support for Dual Timer SP804 module" if COMPILE_TEST +- depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP ++ depends on GENERIC_SCHED_CLOCK && HAVE_CLK + select CLKSRC_MMIO + select TIMER_OF if OF + +@@ -617,12 +617,12 @@ config H8300_TPU + + config CLKSRC_IMX_GPT + bool "Clocksource using i.MX GPT" if COMPILE_TEST +- depends on (ARM || ARM64) && CLKDEV_LOOKUP ++ depends on (ARM || ARM64) && HAVE_CLK + select CLKSRC_MMIO + + config CLKSRC_IMX_TPM + bool "Clocksource using i.MX TPM" if COMPILE_TEST +- depends on (ARM || ARM64) && CLKDEV_LOOKUP ++ depends on (ARM || ARM64) && HAVE_CLK + select CLKSRC_MMIO + select TIMER_OF + help +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 8fe4a0fd6ef18..9a6a94d5bdbdb 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -326,7 +326,7 @@ config MMC_SDHCI_SIRF + + config MMC_SDHCI_PXAV3 + tristate "Marvell MMP2 SD Host Controller support (PXAV3)" +- depends on CLKDEV_LOOKUP ++ depends on HAVE_CLK + depends on MMC_SDHCI_PLTFM + depends on ARCH_BERLIN || ARCH_MMP || ARCH_MVEBU || COMPILE_TEST + default CPU_MMP2 +@@ -339,7 +339,7 @@ config MMC_SDHCI_PXAV3 + + config MMC_SDHCI_PXAV2 + tristate "Marvell PXA9XX SD Host Controller support (PXAV2)" +- depends on CLKDEV_LOOKUP ++ depends on HAVE_CLK + depends on MMC_SDHCI_PLTFM + depends on ARCH_MMP || COMPILE_TEST + default CPU_PXA910 +diff --git a/drivers/staging/board/Kconfig b/drivers/staging/board/Kconfig +index d0c6e42eadda4..ff5e417dd8528 100644 +--- a/drivers/staging/board/Kconfig ++++ b/drivers/staging/board/Kconfig +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + config STAGING_BOARD + bool "Staging Board Support" +- depends on OF_ADDRESS && OF_IRQ && CLKDEV_LOOKUP ++ depends on OF_ADDRESS && OF_IRQ && HAVE_CLK + help + Select to enable per-board staging support code. + +diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig +index 0cd1a15f40aae..71a58f7ac13a9 100644 +--- a/sound/soc/dwc/Kconfig ++++ b/sound/soc/dwc/Kconfig +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0-only + config SND_DESIGNWARE_I2S + tristate "Synopsys I2S Device Driver" +- depends on CLKDEV_LOOKUP ++ depends on HAVE_CLK + select SND_SOC_GENERIC_DMAENGINE_PCM + help + Say Y or M if you want to add support for I2S driver for +diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig +index d610b553ea3b2..053097b73e28d 100644 +--- a/sound/soc/rockchip/Kconfig ++++ b/sound/soc/rockchip/Kconfig +@@ -9,7 +9,7 @@ config SND_SOC_ROCKCHIP + + config SND_SOC_ROCKCHIP_I2S + tristate "Rockchip I2S Device Driver" +- depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP ++ depends on HAVE_CLK && SND_SOC_ROCKCHIP + select SND_SOC_GENERIC_DMAENGINE_PCM + help + Say Y or M if you want to add support for I2S driver for +@@ -18,7 +18,7 @@ config SND_SOC_ROCKCHIP_I2S + + config SND_SOC_ROCKCHIP_PDM + tristate "Rockchip PDM Controller Driver" +- depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP ++ depends on HAVE_CLK && SND_SOC_ROCKCHIP + select SND_SOC_GENERIC_DMAENGINE_PCM + select RATIONAL + help +@@ -28,7 +28,7 @@ config SND_SOC_ROCKCHIP_PDM + + config SND_SOC_ROCKCHIP_SPDIF + tristate "Rockchip SPDIF Device Driver" +- depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP ++ depends on HAVE_CLK && SND_SOC_ROCKCHIP + select SND_SOC_GENERIC_DMAENGINE_PCM + help + Say Y or M if you want to add support for SPDIF driver for +@@ -36,7 +36,7 @@ config SND_SOC_ROCKCHIP_SPDIF + + config SND_SOC_ROCKCHIP_MAX98090 + tristate "ASoC support for Rockchip boards using a MAX98090 codec" +- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP ++ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK + select SND_SOC_ROCKCHIP_I2S + select SND_SOC_MAX98090 + select SND_SOC_TS3A227E +@@ -47,7 +47,7 @@ config SND_SOC_ROCKCHIP_MAX98090 + + config SND_SOC_ROCKCHIP_RT5645 + tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec" +- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP ++ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK + select SND_SOC_ROCKCHIP_I2S + select SND_SOC_RT5645 + help +@@ -56,7 +56,7 @@ config SND_SOC_ROCKCHIP_RT5645 + + config SND_SOC_RK3288_HDMI_ANALOG + tristate "ASoC support multiple codecs for Rockchip RK3288 boards" +- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP ++ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK + select SND_SOC_ROCKCHIP_I2S + select SND_SOC_HDMI_CODEC + select SND_SOC_ES8328_I2C +@@ -68,7 +68,7 @@ config SND_SOC_RK3288_HDMI_ANALOG + + config SND_SOC_RK3399_GRU_SOUND + tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards" +- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI ++ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK && SPI + select SND_SOC_ROCKCHIP_I2S + select SND_SOC_MAX98357A + select SND_SOC_RT5514 +-- +2.43.0 + diff --git a/queue-5.10/clocksource-drivers-sp804-make-user-selectable.patch b/queue-5.10/clocksource-drivers-sp804-make-user-selectable.patch new file mode 100644 index 00000000000..8d41df95cfa --- /dev/null +++ b/queue-5.10/clocksource-drivers-sp804-make-user-selectable.patch @@ -0,0 +1,49 @@ +From a22a96cf7601952f4618faa58820296e17905cc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 12:23:56 +0100 +Subject: clocksource/drivers:sp804: Make user selectable + +From: Mark Brown + +[ Upstream commit 0309f714a0908e947af1c902cf6a330cb593e75e ] + +The sp804 is currently only user selectable if COMPILE_TEST, this was +done by commit dfc82faad725 ("clocksource/drivers/sp804: Add +COMPILE_TEST to CONFIG_ARM_TIMER_SP804") in order to avoid it being +spuriously offered on platforms that won't have the hardware since it's +generally only seen on Arm based platforms. This config is overly +restrictive, while platforms that rely on the SP804 do select it in +their Kconfig there are others such as the Arm fast models which have a +SP804 available but currently unused by Linux. Relax the dependency to +allow it to be user selectable on arm and arm64 to avoid surprises and +in case someone comes up with a use for extra timer hardware. + +Fixes: dfc82faad725 ("clocksource/drivers/sp804: Add COMPILE_TEST to CONFIG_ARM_TIMER_SP804") +Reported-by: Ross Burton +Reviewed-by: Sudeep Holla +Acked-by: Mark Rutland +Signed-off-by: Mark Brown +Link: https://lore.kernel.org/r/20241001-arm64-vexpress-sp804-v3-1-0a2d3f7883e4@kernel.org +Signed-off-by: Daniel Lezcano +Signed-off-by: Sasha Levin +--- + drivers/clocksource/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig +index be4bb4008d6e6..8206158e637dc 100644 +--- a/drivers/clocksource/Kconfig ++++ b/drivers/clocksource/Kconfig +@@ -398,7 +398,8 @@ config ARM_GLOBAL_TIMER + This option enables support for the ARM global timer unit. + + config ARM_TIMER_SP804 +- bool "Support for Dual Timer SP804 module" if COMPILE_TEST ++ bool "Support for Dual Timer SP804 module" ++ depends on ARM || ARM64 || COMPILE_TEST + depends on GENERIC_SCHED_CLOCK && HAVE_CLK + select CLKSRC_MMIO + select TIMER_OF if OF +-- +2.43.0 + diff --git a/queue-5.10/clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch b/queue-5.10/clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch new file mode 100644 index 00000000000..32c69e800a6 --- /dev/null +++ b/queue-5.10/clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch @@ -0,0 +1,46 @@ +From 4be1996a4a9494744cb506b8563e3a8ba3961312 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Oct 2024 13:54:23 +0100 +Subject: clocksource/drivers/timer-ti-dm: Fix child node refcount handling + +From: Javier Carrasco + +[ Upstream commit e5cfc0989d9a2849c51c720a16b90b2c061a1aeb ] + +of_find_compatible_node() increments the node's refcount, and it must be +decremented again with a call to of_node_put() when the pointer is no +longer required to avoid leaking the resource. + +Instead of adding the missing calls to of_node_put() in all execution +paths, use the cleanup attribute for 'arm_timer' by means of the +__free() macro, which automatically calls of_node_put() when the +variable goes out of scope. + +Fixes: 25de4ce5ed02 ("clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940") +Signed-off-by: Javier Carrasco +Link: https://lore.kernel.org/r/20241031-timer-ti-dm-systimer-of_node_put-v3-1-063ee822b73a@gmail.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-ti-dm-systimer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c +index 632523c1232f6..734920e8c5759 100644 +--- a/drivers/clocksource/timer-ti-dm-systimer.c ++++ b/drivers/clocksource/timer-ti-dm-systimer.c +@@ -688,9 +688,9 @@ subsys_initcall(dmtimer_percpu_timer_startup); + + static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa) + { +- struct device_node *arm_timer; ++ struct device_node *arm_timer __free(device_node) = ++ of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); + +- arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); + if (of_device_is_available(arm_timer)) { + pr_warn_once("ARM architected timer wrap issue i940 detected\n"); + return 0; +-- +2.43.0 + diff --git a/queue-5.10/cpufreq-loongson2-unregister-platform_driver-on-fail.patch b/queue-5.10/cpufreq-loongson2-unregister-platform_driver-on-fail.patch new file mode 100644 index 00000000000..6f2cbd09b74 --- /dev/null +++ b/queue-5.10/cpufreq-loongson2-unregister-platform_driver-on-fail.patch @@ -0,0 +1,39 @@ +From 2faf29d851fda4496050ff92892f9a965250f3b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 17:06:15 +0800 +Subject: cpufreq: loongson2: Unregister platform_driver on failure + +From: Yuan Can + +[ Upstream commit 5f856d71ccdf89b4bac0ff70ebb0bb582e7f7f18 ] + +When cpufreq_register_driver() returns error, the cpufreq_init() returns +without unregister platform_driver, fix by add missing +platform_driver_unregister() when cpufreq_register_driver() failed. + +Fixes: f8ede0f700f5 ("MIPS: Loongson 2F: Add CPU frequency scaling support") +Signed-off-by: Yuan Can +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/loongson2_cpufreq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c +index d05e761d95721..e1893e33b1a94 100644 +--- a/drivers/cpufreq/loongson2_cpufreq.c ++++ b/drivers/cpufreq/loongson2_cpufreq.c +@@ -155,7 +155,9 @@ static int __init cpufreq_init(void) + + ret = cpufreq_register_driver(&loongson2_cpufreq_driver); + +- if (!ret && !nowait) { ++ if (ret) { ++ platform_driver_unregister(&platform_driver); ++ } else if (!nowait) { + saved_cpu_wait = cpu_wait; + cpu_wait = loongson2_cpu_wait; + } +-- +2.43.0 + diff --git a/queue-5.10/crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch b/queue-5.10/crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch new file mode 100644 index 00000000000..702317b2784 --- /dev/null +++ b/queue-5.10/crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch @@ -0,0 +1,47 @@ +From 287c630fb7372b9204d9afb0ccf816f84322a7f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Nov 2024 12:17:45 +0000 +Subject: crypto: bcm - add error check in the ahash_hmac_init function + +From: Chen Ridong + +[ Upstream commit 19630cf57233e845b6ac57c9c969a4888925467b ] + +The ahash_init functions may return fails. The ahash_hmac_init should +not return ok when ahash_init returns error. For an example, ahash_init +will return -ENOMEM when allocation memory is error. + +Fixes: 9d12ba86f818 ("crypto: brcm - Add Broadcom SPU driver") +Signed-off-by: Chen Ridong +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/bcm/cipher.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c +index 1cb310a133b3f..b13e33b88d68a 100644 +--- a/drivers/crypto/bcm/cipher.c ++++ b/drivers/crypto/bcm/cipher.c +@@ -2417,6 +2417,7 @@ static int ahash_hmac_setkey(struct crypto_ahash *ahash, const u8 *key, + + static int ahash_hmac_init(struct ahash_request *req) + { ++ int ret; + struct iproc_reqctx_s *rctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct iproc_ctx_s *ctx = crypto_ahash_ctx(tfm); +@@ -2426,7 +2427,9 @@ static int ahash_hmac_init(struct ahash_request *req) + flow_log("ahash_hmac_init()\n"); + + /* init the context as a hash */ +- ahash_init(req); ++ ret = ahash_init(req); ++ if (ret) ++ return ret; + + if (!spu_no_incr_hash(ctx)) { + /* SPU-M can do incr hashing but needs sw for outer HMAC */ +-- +2.43.0 + diff --git a/queue-5.10/crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch b/queue-5.10/crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch new file mode 100644 index 00000000000..495d2ba1692 --- /dev/null +++ b/queue-5.10/crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch @@ -0,0 +1,78 @@ +From e9f85f21da0c8037a9befeb1a9c4ccf547e7244d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Nov 2024 12:15:11 +0000 +Subject: crypto: caam - add error check to caam_rsa_set_priv_key_form +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Chen Ridong + +[ Upstream commit b64140c74e954f1db6eae5548ca3a1f41b6fad79 ] + +The caam_rsa_set_priv_key_form did not check for memory allocation errors. +Add the checks to the caam_rsa_set_priv_key_form functions. + +Fixes: 52e26d77b8b3 ("crypto: caam - add support for RSA key form 2") +Signed-off-by: Chen Ridong +Reviewed-by: Gaurav Jain +Reviewed-by: Horia Geantă +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/caam/caampkc.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c +index 5bd70a59f4ce2..c3c47756f25fe 100644 +--- a/drivers/crypto/caam/caampkc.c ++++ b/drivers/crypto/caam/caampkc.c +@@ -975,7 +975,7 @@ static int caam_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, + return -ENOMEM; + } + +-static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, ++static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, + struct rsa_key *raw_key) + { + struct caam_rsa_key *rsa_key = &ctx->key; +@@ -984,7 +984,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, + + rsa_key->p = caam_read_raw_data(raw_key->p, &p_sz); + if (!rsa_key->p) +- return; ++ return -ENOMEM; + rsa_key->p_sz = p_sz; + + rsa_key->q = caam_read_raw_data(raw_key->q, &q_sz); +@@ -1017,7 +1017,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, + + rsa_key->priv_form = FORM3; + +- return; ++ return 0; + + free_dq: + kfree_sensitive(rsa_key->dq); +@@ -1031,6 +1031,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, + kfree_sensitive(rsa_key->q); + free_p: + kfree_sensitive(rsa_key->p); ++ return -ENOMEM; + } + + static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, +@@ -1076,7 +1077,9 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, + rsa_key->e_sz = raw_key.e_sz; + rsa_key->n_sz = raw_key.n_sz; + +- caam_rsa_set_priv_key_form(ctx, &raw_key); ++ ret = caam_rsa_set_priv_key_form(ctx, &raw_key); ++ if (ret) ++ goto err; + + return 0; + +-- +2.43.0 + diff --git a/queue-5.10/crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch b/queue-5.10/crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch new file mode 100644 index 00000000000..71bc2e4b415 --- /dev/null +++ b/queue-5.10/crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch @@ -0,0 +1,40 @@ +From 6f4eba739f56c2f8e7271e66af63a25a6fa48f48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Sep 2024 12:22:12 +0200 +Subject: crypto: caam - Fix the pointer passed to caam_qi_shutdown() + +From: Christophe JAILLET + +[ Upstream commit ad980b04f51f7fb503530bd1cb328ba5e75a250e ] + +The type of the last parameter given to devm_add_action_or_reset() is +"struct caam_drv_private *", but in caam_qi_shutdown(), it is casted to +"struct device *". + +Pass the correct parameter to devm_add_action_or_reset() so that the +resources are released as expected. + +Fixes: f414de2e2fff ("crypto: caam - use devres to de-initialize QI") +Signed-off-by: Christophe JAILLET +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/caam/qi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c +index ec53528d82058..8e9f6097114e3 100644 +--- a/drivers/crypto/caam/qi.c ++++ b/drivers/crypto/caam/qi.c +@@ -768,7 +768,7 @@ int caam_qi_init(struct platform_device *caam_pdev) + + caam_debugfs_qi_init(ctrlpriv); + +- err = devm_add_action_or_reset(qidev, caam_qi_shutdown, ctrlpriv); ++ err = devm_add_action_or_reset(qidev, caam_qi_shutdown, qidev); + if (err) + return err; + +-- +2.43.0 + diff --git a/queue-5.10/crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch b/queue-5.10/crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch new file mode 100644 index 00000000000..24c98dfa950 --- /dev/null +++ b/queue-5.10/crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch @@ -0,0 +1,38 @@ +From 7cd9d445b1cca31a5bd60be20eeb389b0a3a9197 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2024 18:22:27 +0100 +Subject: crypto: cavium - Fix an error handling path in cpt_ucode_load_fw() + +From: Christophe JAILLET + +[ Upstream commit 572b7cf08403b6c67dfe0dc3e0f2efb42443254f ] + +If do_cpt_init() fails, a previous dma_alloc_coherent() call needs to be +undone. + +Add the needed dma_free_coherent() before returning. + +Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine") +Signed-off-by: Christophe JAILLET +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/cavium/cpt/cptpf_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c +index b3db27b142afb..52101755d0ddf 100644 +--- a/drivers/crypto/cavium/cpt/cptpf_main.c ++++ b/drivers/crypto/cavium/cpt/cptpf_main.c +@@ -303,6 +303,8 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) + + ret = do_cpt_init(cpt, mcode); + if (ret) { ++ dma_free_coherent(&cpt->pdev->dev, mcode->code_size, ++ mcode->code, mcode->phys_base); + dev_err(dev, "do_cpt_init failed with ret: %d\n", ret); + goto fw_release; + } +-- +2.43.0 + diff --git a/queue-5.10/crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch b/queue-5.10/crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch new file mode 100644 index 00000000000..005360f7938 --- /dev/null +++ b/queue-5.10/crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch @@ -0,0 +1,53 @@ +From 9ea13ad38db8e09529846893cc4c8e0a7dacb843 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 10:23:10 -0600 +Subject: crypto: cavium - Fix the if condition to exit loop after timeout + +From: Everest K.C + +[ Upstream commit 53d91ca76b6c426c546542a44c78507b42008c9e ] + +The while loop breaks in the first run because of incorrect +if condition. It also causes the statements after the if to +appear dead. +Fix this by changing the condition from if(timeout--) to +if(!timeout--). + +This bug was reported by Coverity Scan. +Report: +CID 1600859: (#1 of 1): Logically dead code (DEADCODE) +dead_error_line: Execution cannot reach this statement: udelay(30UL); + +Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine") +Signed-off-by: Everest K.C. +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/cavium/cpt/cptpf_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c +index d9362199423f2..b3db27b142afb 100644 +--- a/drivers/crypto/cavium/cpt/cptpf_main.c ++++ b/drivers/crypto/cavium/cpt/cptpf_main.c +@@ -45,7 +45,7 @@ static void cpt_disable_cores(struct cpt_device *cpt, u64 coremask, + dev_err(dev, "Cores still busy %llx", coremask); + grp = cpt_read_csr64(cpt->reg_base, + CPTX_PF_EXEC_BUSY(0)); +- if (timeout--) ++ if (!timeout--) + break; + + udelay(CSR_DELAY); +@@ -395,7 +395,7 @@ static void cpt_disable_all_cores(struct cpt_device *cpt) + dev_err(dev, "Cores still busy"); + grp = cpt_read_csr64(cpt->reg_base, + CPTX_PF_EXEC_BUSY(0)); +- if (timeout--) ++ if (!timeout--) + break; + + udelay(CSR_DELAY); +-- +2.43.0 + diff --git a/queue-5.10/crypto-pcrypt-call-crypto-layer-directly-when-padata.patch b/queue-5.10/crypto-pcrypt-call-crypto-layer-directly-when-padata.patch new file mode 100644 index 00000000000..e579c0481b1 --- /dev/null +++ b/queue-5.10/crypto-pcrypt-call-crypto-layer-directly-when-padata.patch @@ -0,0 +1,59 @@ +From eb17901b606aafb42c5f7364dbd3bf9660593790 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Oct 2024 02:09:35 +0000 +Subject: crypto: pcrypt - Call crypto layer directly when padata_do_parallel() + return -EBUSY + +From: Yi Yang + +[ Upstream commit 662f2f13e66d3883b9238b0b96b17886179e60e2 ] + +Since commit 8f4f68e788c3 ("crypto: pcrypt - Fix hungtask for +PADATA_RESET"), the pcrypt encryption and decryption operations return +-EAGAIN when the CPU goes online or offline. In alg_test(), a WARN is +generated when pcrypt_aead_decrypt() or pcrypt_aead_encrypt() returns +-EAGAIN, the unnecessary panic will occur when panic_on_warn set 1. +Fix this issue by calling crypto layer directly without parallelization +in that case. + +Fixes: 8f4f68e788c3 ("crypto: pcrypt - Fix hungtask for PADATA_RESET") +Signed-off-by: Yi Yang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/pcrypt.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c +index 005a36cb21bc4..2d7f98709e97c 100644 +--- a/crypto/pcrypt.c ++++ b/crypto/pcrypt.c +@@ -117,8 +117,10 @@ static int pcrypt_aead_encrypt(struct aead_request *req) + err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu); + if (!err) + return -EINPROGRESS; +- if (err == -EBUSY) +- return -EAGAIN; ++ if (err == -EBUSY) { ++ /* try non-parallel mode */ ++ return crypto_aead_encrypt(creq); ++ } + + return err; + } +@@ -166,8 +168,10 @@ static int pcrypt_aead_decrypt(struct aead_request *req) + err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu); + if (!err) + return -EINPROGRESS; +- if (err == -EBUSY) +- return -EAGAIN; ++ if (err == -EBUSY) { ++ /* try non-parallel mode */ ++ return crypto_aead_decrypt(creq); ++ } + + return err; + } +-- +2.43.0 + diff --git a/queue-5.10/driver-core-introduce-device_find_any_child-helper.patch b/queue-5.10/driver-core-introduce-device_find_any_child-helper.patch new file mode 100644 index 00000000000..ab782fb39d3 --- /dev/null +++ b/queue-5.10/driver-core-introduce-device_find_any_child-helper.patch @@ -0,0 +1,70 @@ +From 8e6b2d291e48d0f3a16cbf609269e4306801a0f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jun 2022 15:02:18 +0300 +Subject: driver core: Introduce device_find_any_child() helper + +From: Andy Shevchenko + +[ Upstream commit 82b070beae1ef55b0049768c8dc91d87565bb191 ] + +There are several places in the kernel where this kind of functionality is +being used. Provide a generic helper for such cases. + +Reviewed-by: Rafael J. Wysocki +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220610120219.18988-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 27aabf27fd01 ("Bluetooth: fix use-after-free in device_for_each_child()") +Signed-off-by: Sasha Levin +--- + drivers/base/core.c | 20 ++++++++++++++++++++ + include/linux/device.h | 2 ++ + 2 files changed, 22 insertions(+) + +diff --git a/drivers/base/core.c b/drivers/base/core.c +index b13a60de5a863..82eb25ad1c72e 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -3419,6 +3419,26 @@ struct device *device_find_child_by_name(struct device *parent, + } + EXPORT_SYMBOL_GPL(device_find_child_by_name); + ++static int match_any(struct device *dev, void *unused) ++{ ++ return 1; ++} ++ ++/** ++ * device_find_any_child - device iterator for locating a child device, if any. ++ * @parent: parent struct device ++ * ++ * This is similar to the device_find_child() function above, but it ++ * returns a reference to a child device, if any. ++ * ++ * NOTE: you will need to drop the reference with put_device() after use. ++ */ ++struct device *device_find_any_child(struct device *parent) ++{ ++ return device_find_child(parent, NULL, match_any); ++} ++EXPORT_SYMBOL_GPL(device_find_any_child); ++ + int __init devices_init(void) + { + devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); +diff --git a/include/linux/device.h b/include/linux/device.h +index 9c9ce573c737f..d615719b19d4d 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -834,6 +834,8 @@ struct device *device_find_child(struct device *dev, void *data, + int (*match)(struct device *dev, void *data)); + struct device *device_find_child_by_name(struct device *parent, + const char *name); ++struct device *device_find_any_child(struct device *parent); ++ + int device_rename(struct device *dev, const char *new_name); + int device_move(struct device *dev, struct device *new_parent, + enum dpm_order dpm_order); +-- +2.43.0 + diff --git a/queue-5.10/drm-amdkfd-fix-wrong-usage-of-init_work.patch b/queue-5.10/drm-amdkfd-fix-wrong-usage-of-init_work.patch new file mode 100644 index 00000000000..2a4d7f93096 --- /dev/null +++ b/queue-5.10/drm-amdkfd-fix-wrong-usage-of-init_work.patch @@ -0,0 +1,49 @@ +From f4ac7800da912b82f1c74fc029b29dfb471a13d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 09:35:41 +0800 +Subject: drm/amdkfd: Fix wrong usage of INIT_WORK() + +From: Yuan Can + +[ Upstream commit 21cae8debc6a1d243f64fa82cd1b41cb612b5c61 ] + +In kfd_procfs_show(), the sdma_activity_work_handler is a local variable +and the sdma_activity_work_handler.sdma_activity_work should initialize +with INIT_WORK_ONSTACK() instead of INIT_WORK(). + +Fixes: 32cb59f31362 ("drm/amdkfd: Track SDMA utilization per process") +Signed-off-by: Yuan Can +Signed-off-by: Felix Kuehling +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_process.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +index 534f2dec6356f..184527afe2bd5 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +@@ -312,8 +312,8 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr, + attr_sdma); + struct kfd_sdma_activity_handler_workarea sdma_activity_work_handler; + +- INIT_WORK(&sdma_activity_work_handler.sdma_activity_work, +- kfd_sdma_activity_worker); ++ INIT_WORK_ONSTACK(&sdma_activity_work_handler.sdma_activity_work, ++ kfd_sdma_activity_worker); + + sdma_activity_work_handler.pdd = pdd; + sdma_activity_work_handler.sdma_activity_counter = 0; +@@ -321,6 +321,7 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr, + schedule_work(&sdma_activity_work_handler.sdma_activity_work); + + flush_work(&sdma_activity_work_handler.sdma_activity_work); ++ destroy_work_on_stack(&sdma_activity_work_handler.sdma_activity_work); + + return snprintf(buffer, PAGE_SIZE, "%llu\n", + (sdma_activity_work_handler.sdma_activity_counter)/ +-- +2.43.0 + diff --git a/queue-5.10/drm-bridge-tc358767-fix-link-properties-discovery.patch b/queue-5.10/drm-bridge-tc358767-fix-link-properties-discovery.patch new file mode 100644 index 00000000000..4a34400f022 --- /dev/null +++ b/queue-5.10/drm-bridge-tc358767-fix-link-properties-discovery.patch @@ -0,0 +1,60 @@ +From f8c00b1b345f50b43800fb1574c463f9d8eefded Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Nov 2023 13:27:23 +0200 +Subject: drm/bridge: tc358767: Fix link properties discovery + +From: Tomi Valkeinen + +[ Upstream commit 2d343723c7e1f9f6d64f721f07cfdfc2993758d1 ] + +When a display controller driver uses DRM_BRIDGE_ATTACH_NO_CONNECTOR, +tc358767 will behave properly and skip the creation of the connector. + +However, tc_get_display_props(), which is used to find out about the DP +monitor and link, is only called from two places: .atomic_enable() and +tc_connector_get_modes(). The latter is only used when tc358767 creates +its own connector, i.e. when DRM_BRIDGE_ATTACH_NO_CONNECTOR is _not_ +set. + +Thus, the driver never finds out the link properties before get_edid() +is called. With num_lanes of 0 and link_rate of 0 there are not many +valid modes... + +Fix this by adding tc_get_display_props() call at the beginning of +get_edid(), so that we have up to date information before looking at the +modes. + +Reported-by: Jan Kiszka +Closes: https://lore.kernel.org/all/24282420-b4dd-45b3-bb1c-fc37fe4a8205@siemens.com/ +Fixes: de5e6c027ae6 ("drm/bridge: tc358767: add drm_panel_bridge support") +Reviewed-by: Aradhya Bhatia +Tested-by: Jan Kiszka +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20231108-tc358767-v2-2-25c5f70a2159@ideasonboard.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/tc358767.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c +index 9c905634fec79..1c7dafb5dc088 100644 +--- a/drivers/gpu/drm/bridge/tc358767.c ++++ b/drivers/gpu/drm/bridge/tc358767.c +@@ -1319,6 +1319,13 @@ static struct edid *tc_get_edid(struct drm_bridge *bridge, + struct drm_connector *connector) + { + struct tc_data *tc = bridge_to_tc(bridge); ++ int ret; ++ ++ ret = tc_get_display_props(tc); ++ if (ret < 0) { ++ dev_err(tc->dev, "failed to read display props: %d\n", ret); ++ return 0; ++ } + + return drm_get_edid(connector, &tc->aux.ddc); + } +-- +2.43.0 + diff --git a/queue-5.10/drm-etnaviv-dump-fix-sparse-warnings.patch b/queue-5.10/drm-etnaviv-dump-fix-sparse-warnings.patch new file mode 100644 index 00000000000..7db4954423d --- /dev/null +++ b/queue-5.10/drm-etnaviv-dump-fix-sparse-warnings.patch @@ -0,0 +1,67 @@ +From 3f0abfdf1165257c70e5589cedf59c40034ca3ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Dec 2020 20:51:10 +0100 +Subject: drm/etnaviv: dump: fix sparse warnings + +From: Marc Kleine-Budde + +[ Upstream commit 03a2753936e85beb8239fd20ae3fb2ce90209212 ] + +This patch fixes the following sparse warnings, by adding the missing endianess +conversion functions. + +| etnaviv/etnaviv_dump.c:78:26: warning: restricted __le32 degrades to integer +| etnaviv/etnaviv_dump.c:88:26: warning: incorrect type in assignment (different base types) +| etnaviv/etnaviv_dump.c:88:26: expected restricted __le32 [usertype] reg +| etnaviv/etnaviv_dump.c:88:26: got unsigned short const +| etnaviv/etnaviv_dump.c:89:28: warning: incorrect type in assignment (different base types) +| etnaviv/etnaviv_dump.c:89:28: expected restricted __le32 [usertype] value +| etnaviv/etnaviv_dump.c:89:28: got unsigned int +| etnaviv/etnaviv_dump.c:210:43: warning: incorrect type in assignment (different base types) +| etnaviv/etnaviv_dump.c:210:43: expected restricted __le32 +| etnaviv/etnaviv_dump.c:210:43: got long + +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Lucas Stach +Stable-dep-of: 37dc4737447a ("drm/etnaviv: hold GPU lock across perfmon sampling") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/etnaviv/etnaviv_dump.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c +index 7b57d01ba865b..0edcf8ceb4a78 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c +@@ -75,7 +75,7 @@ static void etnaviv_core_dump_header(struct core_dump_iterator *iter, + hdr->file_size = cpu_to_le32(data_end - iter->data); + + iter->hdr++; +- iter->data += hdr->file_size; ++ iter->data += le32_to_cpu(hdr->file_size); + } + + static void etnaviv_core_dump_registers(struct core_dump_iterator *iter, +@@ -85,8 +85,8 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter, + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) { +- reg->reg = etnaviv_dump_registers[i]; +- reg->value = gpu_read(gpu, etnaviv_dump_registers[i]); ++ reg->reg = cpu_to_le32(etnaviv_dump_registers[i]); ++ reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i])); + } + + etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg); +@@ -207,7 +207,7 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit) + if (!IS_ERR(pages)) { + int j; + +- iter.hdr->data[0] = bomap - bomap_start; ++ iter.hdr->data[0] = cpu_to_le32((bomap - bomap_start)); + + for (j = 0; j < obj->base.size >> PAGE_SHIFT; j++) + *bomap++ = cpu_to_le64(page_to_phys(*pages++)); +-- +2.43.0 + diff --git a/queue-5.10/drm-etnaviv-fix-power-register-offset-on-gc300.patch b/queue-5.10/drm-etnaviv-fix-power-register-offset-on-gc300.patch new file mode 100644 index 00000000000..db7deae9eee --- /dev/null +++ b/queue-5.10/drm-etnaviv-fix-power-register-offset-on-gc300.patch @@ -0,0 +1,158 @@ +From 3d153227946c2bd68524b32bff9b1ca0dade1c5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 10 Sep 2022 13:29:39 -0700 +Subject: drm/etnaviv: fix power register offset on GC300 + +From: Doug Brown + +[ Upstream commit 61a6920bb604df3a0e389a2a9479e1e233e4461d ] + +Older GC300 revisions have their power registers at an offset of 0x200 +rather than 0x100. Add new gpu_read_power and gpu_write_power functions +to encapsulate accesses to the power addresses and fix the addresses. + +Signed-off-by: Doug Brown +Signed-off-by: Lucas Stach +Stable-dep-of: 37dc4737447a ("drm/etnaviv: hold GPU lock across perfmon sampling") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/etnaviv/etnaviv_dump.c | 7 ++++++- + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 20 ++++++++++---------- + drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 21 +++++++++++++++++++++ + 3 files changed, 37 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c +index 0edcf8ceb4a78..898f84a0fc30c 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c +@@ -83,10 +83,15 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter, + { + struct etnaviv_dump_registers *reg = iter->data; + unsigned int i; ++ u32 read_addr; + + for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) { ++ read_addr = etnaviv_dump_registers[i]; ++ if (read_addr >= VIVS_PM_POWER_CONTROLS && ++ read_addr <= VIVS_PM_PULSE_EATER) ++ read_addr = gpu_fix_power_address(gpu, read_addr); + reg->reg = cpu_to_le32(etnaviv_dump_registers[i]); +- reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i])); ++ reg->value = cpu_to_le32(gpu_read(gpu, read_addr)); + } + + etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg); +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index 5fb1d62ec5950..e944bcd30a2ba 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -578,7 +578,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu) + u32 pmc, ppc; + + /* enable clock gating */ +- ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); ++ ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); + ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; + + /* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */ +@@ -586,9 +586,9 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu) + gpu->identity.revision == 0x4302) + ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING; + +- gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc); ++ gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc); + +- pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS); ++ pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS); + + /* Disable PA clock gating for GC400+ without bugfix except for GC420 */ + if (gpu->identity.model >= chipModel_GC400 && +@@ -617,7 +617,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu) + pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ; + pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ; + +- gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc); ++ gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc); + } + + void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch) +@@ -677,11 +677,11 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu) + (gpu->identity.features & chipFeatures_PIPE_3D)) + { + /* Performance fix: disable internal DFS */ +- pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER); ++ pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER); + pulse_eater |= BIT(18); + } + +- gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater); ++ gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); + } + + static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) +@@ -1275,9 +1275,9 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu, + u32 val; + + /* disable clock gating */ +- val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); ++ val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); + val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; +- gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); ++ gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val); + + /* enable debug register */ + val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); +@@ -1308,9 +1308,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val); + + /* enable clock gating */ +- val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); ++ val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); + val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; +- gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); ++ gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val); + } + + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +index 85eddd492774d..39f1e83d3cc7d 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +@@ -10,6 +10,7 @@ + #include "etnaviv_gem.h" + #include "etnaviv_mmu.h" + #include "etnaviv_drv.h" ++#include "common.xml.h" + + struct etnaviv_gem_submit; + struct etnaviv_vram_mapping; +@@ -159,6 +160,26 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg) + return readl(gpu->mmio + reg); + } + ++static inline u32 gpu_fix_power_address(struct etnaviv_gpu *gpu, u32 reg) ++{ ++ /* Power registers in GC300 < 2.0 are offset by 0x100 */ ++ if (gpu->identity.model == chipModel_GC300 && ++ gpu->identity.revision < 0x2000) ++ reg += 0x100; ++ ++ return reg; ++} ++ ++static inline void gpu_write_power(struct etnaviv_gpu *gpu, u32 reg, u32 data) ++{ ++ writel(data, gpu->mmio + gpu_fix_power_address(gpu, reg)); ++} ++ ++static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg) ++{ ++ return readl(gpu->mmio + gpu_fix_power_address(gpu, reg)); ++} ++ + int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); + + int etnaviv_gpu_init(struct etnaviv_gpu *gpu); +-- +2.43.0 + diff --git a/queue-5.10/drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch b/queue-5.10/drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch new file mode 100644 index 00000000000..c7818e59df0 --- /dev/null +++ b/queue-5.10/drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch @@ -0,0 +1,78 @@ +From 4c92ec6260e88843a574ee30da6be0ac269abde4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Jul 2024 22:00:09 +0200 +Subject: drm/etnaviv: hold GPU lock across perfmon sampling + +From: Lucas Stach + +[ Upstream commit 37dc4737447a7667f8e9ec790dac251da057eb27 ] + +The perfmon sampling mutates shared GPU state (e.g. VIVS_HI_CLOCK_CONTROL +to select the pipe for the perf counter reads). To avoid clashing with +other functions mutating the same state (e.g. etnaviv_gpu_update_clock) +the perfmon sampling needs to hold the GPU lock. + +Fixes: 68dc0b295dcb ("drm/etnaviv: use 'sync points' for performance monitor requests") +Reviewed-by: Christian Gmeiner +Signed-off-by: Lucas Stach +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index e944bcd30a2ba..407a15e1469f2 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -1274,6 +1274,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu, + { + u32 val; + ++ mutex_lock(&gpu->lock); ++ + /* disable clock gating */ + val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); + val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; +@@ -1285,6 +1287,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu, + gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val); + + sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE); ++ ++ mutex_unlock(&gpu->lock); + } + + static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, +@@ -1294,13 +1298,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, + unsigned int i; + u32 val; + +- sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST); +- +- for (i = 0; i < submit->nr_pmrs; i++) { +- const struct etnaviv_perfmon_request *pmr = submit->pmrs + i; ++ mutex_lock(&gpu->lock); + +- *pmr->bo_vma = pmr->sequence; +- } ++ sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST); + + /* disable debug register */ + val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); +@@ -1311,6 +1311,14 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, + val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); + val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; + gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val); ++ ++ mutex_unlock(&gpu->lock); ++ ++ for (i = 0; i < submit->nr_pmrs; i++) { ++ const struct etnaviv_perfmon_request *pmr = submit->pmrs + i; ++ ++ *pmr->bo_vma = pmr->sequence; ++ } + } + + +-- +2.43.0 + diff --git a/queue-5.10/drm-etnaviv-request-pages-from-dma32-zone-on-address.patch b/queue-5.10/drm-etnaviv-request-pages-from-dma32-zone-on-address.patch new file mode 100644 index 00000000000..8ecde164085 --- /dev/null +++ b/queue-5.10/drm-etnaviv-request-pages-from-dma32-zone-on-address.patch @@ -0,0 +1,68 @@ +From 297b8b75d71e1b7227dbb31f39e46cfc87bff77c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Oct 2024 07:34:30 +0800 +Subject: drm/etnaviv: Request pages from DMA32 zone on addressing_limited + +From: Xiaolei Wang + +[ Upstream commit 13c96ac9a3f0f1c7ba1ff0656ea508e7fa065e7e ] + +Remove __GFP_HIGHMEM when requesting a page from DMA32 zone, +and since all vivante GPUs in the system will share the same +DMA constraints, move the check of whether to get a page from +DMA32 to etnaviv_bind(). + +Fixes: b72af445cd38 ("drm/etnaviv: request pages from DMA32 zone when needed") +Suggested-by: Sui Jingfeng +Signed-off-by: Xiaolei Wang +Reviewed-by: Christian Gmeiner +Signed-off-by: Lucas Stach +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/etnaviv/etnaviv_drv.c | 10 ++++++++++ + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 8 -------- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c +index edf9387069cdc..b7225d863f684 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c +@@ -543,6 +543,16 @@ static int etnaviv_bind(struct device *dev) + priv->num_gpus = 0; + priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN; + ++ /* ++ * If the GPU is part of a system with DMA addressing limitations, ++ * request pages for our SHM backend buffers from the DMA32 zone to ++ * hopefully avoid performance killing SWIOTLB bounce buffering. ++ */ ++ if (dma_addressing_limited(dev)) { ++ priv->shm_gfp_mask |= GFP_DMA32; ++ priv->shm_gfp_mask &= ~__GFP_HIGHMEM; ++ } ++ + priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev); + if (IS_ERR(priv->cmdbuf_suballoc)) { + dev_err(drm->dev, "Failed to create cmdbuf suballocator\n"); +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index 8baa59fb32f2d..5fb1d62ec5950 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -780,14 +780,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) + if (ret) + goto fail; + +- /* +- * If the GPU is part of a system with DMA addressing limitations, +- * request pages for our SHM backend buffers from the DMA32 zone to +- * hopefully avoid performance killing SWIOTLB bounce buffering. +- */ +- if (dma_addressing_limited(gpu->dev)) +- priv->shm_gfp_mask |= GFP_DMA32; +- + /* Create buffer: */ + ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer, + PAGE_SIZE); +-- +2.43.0 + diff --git a/queue-5.10/drm-etnaviv-rework-linear-window-offset-calculation.patch b/queue-5.10/drm-etnaviv-rework-linear-window-offset-calculation.patch new file mode 100644 index 00000000000..f0713892f54 --- /dev/null +++ b/queue-5.10/drm-etnaviv-rework-linear-window-offset-calculation.patch @@ -0,0 +1,113 @@ +From 17e1e5a0875e09716c7baa234c85d1c38f814510 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 May 2021 12:24:22 +0200 +Subject: drm/etnaviv: rework linear window offset calculation + +From: Lucas Stach + +[ Upstream commit 4bfdd2aa67fbfba09d7c32a4c7fd4c5eb1052bce ] + +The current calculation based on the required_dma mask can be significantly +off, so that the linear window only overlaps a small part of the DRAM +address space. This can lead to the command buffer being unmappable, which +is obviously bad. + +Rework the linear window offset calculation to be based on the command buffer +physical address, making sure that the command buffer is always mappable. + +Tested-by: Primoz Fiser +Reviewed-by: Christian Gmeiner +Signed-off-by: Lucas Stach +Stable-dep-of: 13c96ac9a3f0 ("drm/etnaviv: Request pages from DMA32 zone on addressing_limited") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 52 +++++++++++++-------------- + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +index f3281d56b1d82..8baa59fb32f2d 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -27,10 +27,6 @@ + #include "state_hi.xml.h" + #include "cmdstream.xml.h" + +-#ifndef PHYS_OFFSET +-#define PHYS_OFFSET 0 +-#endif +- + static const struct platform_device_id gpu_ids[] = { + { .name = "etnaviv-gpu,2d" }, + { }, +@@ -741,6 +737,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) + int etnaviv_gpu_init(struct etnaviv_gpu *gpu) + { + struct etnaviv_drm_private *priv = gpu->drm->dev_private; ++ dma_addr_t cmdbuf_paddr; + int ret, i; + + ret = pm_runtime_get_sync(gpu->dev); +@@ -783,28 +780,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) + if (ret) + goto fail; + +- /* +- * Set the GPU linear window to be at the end of the DMA window, where +- * the CMA area is likely to reside. This ensures that we are able to +- * map the command buffers while having the linear window overlap as +- * much RAM as possible, so we can optimize mappings for other buffers. +- * +- * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads +- * to different views of the memory on the individual engines. +- */ +- if (!(gpu->identity.features & chipFeatures_PIPE_3D) || +- (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { +- u32 dma_mask = (u32)dma_get_required_mask(gpu->dev); +- if (dma_mask < PHYS_OFFSET + SZ_2G) +- priv->mmu_global->memory_base = PHYS_OFFSET; +- else +- priv->mmu_global->memory_base = dma_mask - SZ_2G + 1; +- } else if (PHYS_OFFSET >= SZ_2G) { +- dev_info(gpu->dev, "Need to move linear window on MC1.0, disabling TS\n"); +- priv->mmu_global->memory_base = PHYS_OFFSET; +- gpu->identity.features &= ~chipFeatures_FAST_CLEAR; +- } +- + /* + * If the GPU is part of a system with DMA addressing limitations, + * request pages for our SHM backend buffers from the DMA32 zone to +@@ -821,6 +796,31 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) + goto fail; + } + ++ /* ++ * Set the GPU linear window to cover the cmdbuf region, as the GPU ++ * won't be able to start execution otherwise. The alignment to 128M is ++ * chosen arbitrarily but helps in debugging, as the MMU offset ++ * calculations are much more straight forward this way. ++ * ++ * On MC1.0 cores the linear window offset is ignored by the TS engine, ++ * leading to inconsistent memory views. Avoid using the offset on those ++ * cores if possible, otherwise disable the TS feature. ++ */ ++ cmdbuf_paddr = ALIGN_DOWN(etnaviv_cmdbuf_get_pa(&gpu->buffer), SZ_128M); ++ ++ if (!(gpu->identity.features & chipFeatures_PIPE_3D) || ++ (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) { ++ if (cmdbuf_paddr >= SZ_2G) ++ priv->mmu_global->memory_base = SZ_2G; ++ else ++ priv->mmu_global->memory_base = cmdbuf_paddr; ++ } else if (cmdbuf_paddr + SZ_128M >= SZ_2G) { ++ dev_info(gpu->dev, ++ "Need to move linear window on MC1.0, disabling TS\n"); ++ gpu->identity.features &= ~chipFeatures_FAST_CLEAR; ++ priv->mmu_global->memory_base = SZ_2G; ++ } ++ + /* Setup event management */ + spin_lock_init(&gpu->event_spinlock); + init_completion(&gpu->event_free); +-- +2.43.0 + diff --git a/queue-5.10/drm-fsl-dcu-convert-to-linux-irq-interfaces.patch b/queue-5.10/drm-fsl-dcu-convert-to-linux-irq-interfaces.patch new file mode 100644 index 00000000000..95676152606 --- /dev/null +++ b/queue-5.10/drm-fsl-dcu-convert-to-linux-irq-interfaces.patch @@ -0,0 +1,167 @@ +From 5a610c95ac9f2b72671a2c1f8f270081f4a416bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Aug 2021 11:06:54 +0200 +Subject: drm/fsl-dcu: Convert to Linux IRQ interfaces + +From: Thomas Zimmermann + +[ Upstream commit 03ac16e584e496230903ba20f2b4bbfd942a16b4 ] + +Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's +IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers +don't benefit from using it. DRM IRQ callbacks are now being called +directly or inlined. + +Signed-off-by: Thomas Zimmermann +Acked-by: Sam Ravnborg +Link: https://patchwork.freedesktop.org/patch/msgid/20210803090704.32152-5-tzimmermann@suse.de +Stable-dep-of: ffcde9e44d3e ("drm: fsl-dcu: enable PIXCLK on LS1021A") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 78 +++++++++++++---------- + 1 file changed, 46 insertions(+), 32 deletions(-) + +diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +index abbc1ddbf27f0..11b4a81bacc68 100644 +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +@@ -23,7 +23,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -51,7 +50,7 @@ static const struct regmap_config fsl_dcu_regmap_config = { + .volatile_reg = fsl_dcu_drm_is_volatile_reg, + }; + +-static void fsl_dcu_irq_uninstall(struct drm_device *dev) ++static void fsl_dcu_irq_reset(struct drm_device *dev) + { + struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; + +@@ -59,6 +58,45 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev) + regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0); + } + ++static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg) ++{ ++ struct drm_device *dev = arg; ++ struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; ++ unsigned int int_status; ++ int ret; ++ ++ ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status); ++ if (ret) { ++ dev_err(dev->dev, "read DCU_INT_STATUS failed\n"); ++ return IRQ_NONE; ++ } ++ ++ if (int_status & DCU_INT_STATUS_VBLANK) ++ drm_handle_vblank(dev, 0); ++ ++ regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status); ++ ++ return IRQ_HANDLED; ++} ++ ++static int fsl_dcu_irq_install(struct drm_device *dev, unsigned int irq) ++{ ++ if (irq == IRQ_NOTCONNECTED) ++ return -ENOTCONN; ++ ++ fsl_dcu_irq_reset(dev); ++ ++ return request_irq(irq, fsl_dcu_drm_irq, 0, dev->driver->name, dev); ++} ++ ++static void fsl_dcu_irq_uninstall(struct drm_device *dev) ++{ ++ struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; ++ ++ fsl_dcu_irq_reset(dev); ++ free_irq(fsl_dev->irq, dev); ++} ++ + static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) + { + struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; +@@ -73,13 +111,13 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize vblank\n"); +- goto done; ++ goto done_vblank; + } + +- ret = drm_irq_install(dev, fsl_dev->irq); ++ ret = fsl_dcu_irq_install(dev, fsl_dev->irq); + if (ret < 0) { + dev_err(dev->dev, "failed to install IRQ handler\n"); +- goto done; ++ goto done_irq; + } + + if (legacyfb_depth != 16 && legacyfb_depth != 24 && +@@ -90,11 +128,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) + } + + return 0; +-done: ++done_irq: + drm_kms_helper_poll_fini(dev); + + drm_mode_config_cleanup(dev); +- drm_irq_uninstall(dev); ++done_vblank: + dev->dev_private = NULL; + + return ret; +@@ -106,41 +144,17 @@ static void fsl_dcu_unload(struct drm_device *dev) + drm_kms_helper_poll_fini(dev); + + drm_mode_config_cleanup(dev); +- drm_irq_uninstall(dev); ++ fsl_dcu_irq_uninstall(dev); + + dev->dev_private = NULL; + } + +-static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg) +-{ +- struct drm_device *dev = arg; +- struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; +- unsigned int int_status; +- int ret; +- +- ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status); +- if (ret) { +- dev_err(dev->dev, "read DCU_INT_STATUS failed\n"); +- return IRQ_NONE; +- } +- +- if (int_status & DCU_INT_STATUS_VBLANK) +- drm_handle_vblank(dev, 0); +- +- regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status); +- +- return IRQ_HANDLED; +-} +- + DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops); + + static struct drm_driver fsl_dcu_drm_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .load = fsl_dcu_load, + .unload = fsl_dcu_unload, +- .irq_handler = fsl_dcu_drm_irq, +- .irq_preinstall = fsl_dcu_irq_uninstall, +- .irq_uninstall = fsl_dcu_irq_uninstall, + DRM_GEM_CMA_DRIVER_OPS, + .fops = &fsl_dcu_drm_fops, + .name = "fsl-dcu-drm", +-- +2.43.0 + diff --git a/queue-5.10/drm-fsl-dcu-enable-pixclk-on-ls1021a.patch b/queue-5.10/drm-fsl-dcu-enable-pixclk-on-ls1021a.patch new file mode 100644 index 00000000000..e71c9f883f6 --- /dev/null +++ b/queue-5.10/drm-fsl-dcu-enable-pixclk-on-ls1021a.patch @@ -0,0 +1,88 @@ +From 1432017045e2b47abbe2c4f839192c1ce52d84ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Sep 2024 07:55:51 +0200 +Subject: drm: fsl-dcu: enable PIXCLK on LS1021A + +From: Matthias Schiffer + +[ Upstream commit ffcde9e44d3e18fde3d18bfff8d9318935413bfd ] + +The PIXCLK needs to be enabled in SCFG before accessing certain DCU +registers, or the access will hang. For simplicity, the PIXCLK is enabled +unconditionally, resulting in increased power consumption. + +Signed-off-by: Matthias Schiffer +Signed-off-by: Alexander Stein +Fixes: 109eee2f2a18 ("drm/layerscape: Add Freescale DCU DRM driver") +Acked-by: Dmitry Baryshkov +Link: https://patchwork.freedesktop.org/patch/msgid/20240926055552.1632448-2-alexander.stein@ew.tq-group.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/fsl-dcu/Kconfig | 1 + + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 15 +++++++++++++++ + drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 3 +++ + 3 files changed, 19 insertions(+) + +diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig +index d7dd8ba90e3af..9e5a35e7c00cc 100644 +--- a/drivers/gpu/drm/fsl-dcu/Kconfig ++++ b/drivers/gpu/drm/fsl-dcu/Kconfig +@@ -8,6 +8,7 @@ config DRM_FSL_DCU + select DRM_PANEL + select REGMAP_MMIO + select VIDEOMODE_HELPERS ++ select MFD_SYSCON if SOC_LS1021A + help + Choose this option if you have an Freescale DCU chipset. + If M is selected the module will be called fsl-dcu-drm. +diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +index 11b4a81bacc68..1065249807323 100644 +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +@@ -100,6 +100,7 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev) + static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) + { + struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; ++ struct regmap *scfg; + int ret; + + ret = fsl_dcu_drm_modeset_init(fsl_dev); +@@ -108,6 +109,20 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags) + return ret; + } + ++ scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg"); ++ if (PTR_ERR(scfg) != -ENODEV) { ++ /* ++ * For simplicity, enable the PIXCLK unconditionally, ++ * resulting in increased power consumption. Disabling ++ * the clock in PM or on unload could be implemented as ++ * a future improvement. ++ */ ++ ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN, ++ SCFG_PIXCLKCR_PXCEN); ++ if (ret < 0) ++ return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n"); ++ } ++ + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret < 0) { + dev_err(dev->dev, "failed to initialize vblank\n"); +diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h +index e2049a0e8a92a..566396013c04a 100644 +--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h ++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h +@@ -160,6 +160,9 @@ + #define FSL_DCU_ARGB4444 12 + #define FSL_DCU_YUV422 14 + ++#define SCFG_PIXCLKCR 0x28 ++#define SCFG_PIXCLKCR_PXCEN BIT(31) ++ + #define VF610_LAYER_REG_NUM 9 + #define LS1021A_LAYER_REG_NUM 10 + +-- +2.43.0 + diff --git a/queue-5.10/drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch new file mode 100644 index 00000000000..8cac92fad0b --- /dev/null +++ b/queue-5.10/drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch @@ -0,0 +1,49 @@ +From dbeaeb14b5b5d6ffb53eb48382ef5344c29c6595 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2024 16:30:16 +0800 +Subject: drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit 1af01e14db7e0b45ae502d822776a58c86688763 ] + +disable_irq() after request_irq() still has a time gap in which +interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will +disable IRQ auto-enable when request IRQ. + +Fixes: 9021c317b770 ("drm/imx: Add initial support for DCSS on iMX8MQ") +Signed-off-by: Jinjie Ruan +Reviewed-by: Laurentiu Palcu +Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-2-ruanjinjie@huawei.com +[DB: fixed the subject] +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/imx/dcss/dcss-crtc.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c +index 36abff0890b28..ec041fcd07d02 100644 +--- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c ++++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c +@@ -201,15 +201,13 @@ int dcss_crtc_init(struct dcss_crtc *crtc, struct drm_device *drm) + if (crtc->irq < 0) + return crtc->irq; + +- ret = request_irq(crtc->irq, dcss_crtc_irq_handler, +- 0, "dcss_drm", crtc); ++ ret = request_irq(crtc->irq, dcss_crtc_irq_handler, IRQF_NO_AUTOEN, ++ "dcss_drm", crtc); + if (ret) { + dev_err(dcss->dev, "irq request failed with %d.\n", ret); + return ret; + } + +- disable_irq(crtc->irq); +- + return 0; + } + +-- +2.43.0 + diff --git a/queue-5.10/drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch new file mode 100644 index 00000000000..21eb155185a --- /dev/null +++ b/queue-5.10/drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch @@ -0,0 +1,48 @@ +From 680e12efd11c12c763df00eea3a175bc199e7a27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2024 16:30:18 +0800 +Subject: drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit 40004709a3d3b07041a473a163ca911ef04ab8bd ] + +disable_irq() after request_irq() still has a time gap in which +interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will +disable IRQ auto-enable when request IRQ. + +Fixes: 47b1be5c0f4e ("staging: imx/drm: request irq only after adding the crtc") +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Jinjie Ruan +Reviewed-by: Philipp Zabel +Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-4-ruanjinjie@huawei.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/imx/ipuv3-crtc.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c +index fd9d8e51837fa..d6e5821c14c1d 100644 +--- a/drivers/gpu/drm/imx/ipuv3-crtc.c ++++ b/drivers/gpu/drm/imx/ipuv3-crtc.c +@@ -406,14 +406,12 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, + } + + ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); +- ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, +- "imx_drm", ipu_crtc); ++ ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, ++ IRQF_NO_AUTOEN, "imx_drm", ipu_crtc); + if (ret < 0) { + dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); + goto err_put_plane1_res; + } +- /* Only enable IRQ when we actually need it to trigger work. */ +- disable_irq(ipu_crtc->irq); + + return 0; + +-- +2.43.0 + diff --git a/queue-5.10/drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch b/queue-5.10/drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch new file mode 100644 index 00000000000..3ebbd90b1aa --- /dev/null +++ b/queue-5.10/drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch @@ -0,0 +1,52 @@ +From d33ffbf39aed3c6e043ff9b318712ef1f2ab462c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 18:46:40 +0300 +Subject: drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused + +From: Andy Shevchenko + +[ Upstream commit 53bd7c1c0077db533472ae32799157758302ef48 ] + +The INTERVAL_TREE_DEFINE() uncoditionally provides a bunch of helper +functions which in some cases may be not used. This, in particular, +prevents kernel builds with clang, `make W=1` and CONFIG_WERROR=y: + +.../drm/drm_mm.c:152:1: error: unused function 'drm_mm_interval_tree_insert' [-Werror,-Wunused-function] + 152 | INTERVAL_TREE_DEFINE(struct drm_mm_node, rb, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 153 | u64, __subtree_last, + | ~~~~~~~~~~~~~~~~~~~~ + 154 | START, LAST, static inline, drm_mm_interval_tree) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fix this by marking drm_mm_interval_tree*() functions with __maybe_unused. + +See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static +inline functions for W=1 build"). + +Fixes: 202b52b7fbf7 ("drm: Track drm_mm nodes with an interval tree") +Signed-off-by: Andy Shevchenko +Reviewed-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20240829154640.1120050-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Jani Nikula +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_mm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c +index a4a04d2461353..7c25a8e38830b 100644 +--- a/drivers/gpu/drm/drm_mm.c ++++ b/drivers/gpu/drm/drm_mm.c +@@ -154,7 +154,7 @@ static void show_leaks(struct drm_mm *mm) { } + + INTERVAL_TREE_DEFINE(struct drm_mm_node, rb, + u64, __subtree_last, +- START, LAST, static inline, drm_mm_interval_tree) ++ START, LAST, static inline __maybe_unused, drm_mm_interval_tree) + + struct drm_mm_node * + __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last) +-- +2.43.0 + diff --git a/queue-5.10/drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch b/queue-5.10/drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch new file mode 100644 index 00000000000..9ea75e94b14 --- /dev/null +++ b/queue-5.10/drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch @@ -0,0 +1,47 @@ +From 8cd3998b71d5409d35b83b6d16870d6e5107e0b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2024 16:30:20 +0800 +Subject: drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit 394679f322649d06fea3c646ba65f5a0887f52c3 ] + +disable_irq() after request_irq() still has a time gap in which +interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will +disable IRQ auto-enable when request IRQ. + +Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support") +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Jinjie Ruan +Patchwork: https://patchwork.freedesktop.org/patch/614075/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index 8d78d95d29fcd..655938df45313 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -1407,15 +1407,13 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev, + + irq = platform_get_irq_byname(pdev, name); + +- ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu); ++ ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, name, gmu); + if (ret) { + DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n", + name, ret); + return ret; + } + +- disable_irq(irq); +- + return irq; + } + +-- +2.43.0 + diff --git a/queue-5.10/drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch b/queue-5.10/drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch new file mode 100644 index 00000000000..7c00d01e098 --- /dev/null +++ b/queue-5.10/drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch @@ -0,0 +1,46 @@ +From fdc6545fe302253a185a7281502928456ab1e3a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 14:42:10 -0500 +Subject: drm/msm/dpu: cast crtc_clk calculation to u64 in + _dpu_core_perf_calc_clk() + +From: Zichen Xie + +[ Upstream commit 20c7b42d9dbd048019bfe0af39229e3014007a98 ] + +There may be a potential integer overflow issue in +_dpu_core_perf_calc_clk(). crtc_clk is defined as u64, while +mode->vtotal, mode->hdisplay, and drm_mode_vrefresh(mode) are defined as +a smaller data type. The result of the calculation will be limited to +"int" in this case without correct casting. In screen with high +resolution and high refresh rate, integer overflow may happen. +So, we recommend adding an extra cast to prevent potential +integer overflow. + +Fixes: c33b7c0389e1 ("drm/msm/dpu: add support for clk and bw scaling for display") +Signed-off-by: Zichen Xie +Reviewed-by: Abhinav Kumar +Patchwork: https://patchwork.freedesktop.org/patch/622206/ +Link: https://lore.kernel.org/r/20241029194209.23684-1-zichenxie0106@gmail.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +index 37c8270681c23..733941fb4078d 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +@@ -79,7 +79,7 @@ static u64 _dpu_core_perf_calc_clk(struct dpu_kms *kms, + + mode = &state->adjusted_mode; + +- crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode); ++ crtc_clk = (u64)mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode); + + drm_atomic_crtc_for_each_plane(plane, crtc) { + pstate = to_dpu_plane_state(plane->state); +-- +2.43.0 + diff --git a/queue-5.10/drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch b/queue-5.10/drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch new file mode 100644 index 00000000000..fe114d03a60 --- /dev/null +++ b/queue-5.10/drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch @@ -0,0 +1,76 @@ +From af145bdc3e4757c39d92a3b813aa976535a47d23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Aug 2024 16:50:29 +0300 +Subject: drm/omap: Fix locking in omap_gem_new_dmabuf() + +From: Tomi Valkeinen + +[ Upstream commit e6a1c4037227539373c8cf484ace83833e2ad6a2 ] + +omap_gem_new_dmabuf() creates the new gem object, and then takes and +holds the omap_obj->lock for the rest of the function. This has two +issues: + +- omap_gem_free_object(), which is called in the error paths, also takes + the same lock, leading to deadlock +- Even if the above wouldn't happen, in the error cases + omap_gem_new_dmabuf() still unlocks omap_obj->lock, even after the + omap_obj has already been freed. + +Furthermore, I don't think there's any reason to take the lock at all, +as the object was just created and not yet shared with anyone else. + +To fix all this, drop taking the lock. + +Fixes: 3cbd0c587b12 ("drm/omap: gem: Replace struct_mutex usage with omap_obj private lock") +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/all/511b99d7-aade-4f92-bd3e-63163a13d617@stanley.mountain/ +Reviewed-by: Sebastian Reichel +Signed-off-by: Tomi Valkeinen +Link: https://patchwork.freedesktop.org/patch/msgid/20240806-omapdrm-misc-fixes-v1-3-15d31aea0831@ideasonboard.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/omapdrm/omap_gem.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c +index f67f223c6479f..662062cdba9d4 100644 +--- a/drivers/gpu/drm/omapdrm/omap_gem.c ++++ b/drivers/gpu/drm/omapdrm/omap_gem.c +@@ -1289,8 +1289,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, + + omap_obj = to_omap_bo(obj); + +- mutex_lock(&omap_obj->lock); +- + omap_obj->sgt = sgt; + + if (sgt->orig_nents == 1) { +@@ -1305,8 +1303,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, + pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); + if (!pages) { + omap_gem_free_object(obj); +- obj = ERR_PTR(-ENOMEM); +- goto done; ++ return ERR_PTR(-ENOMEM); + } + + omap_obj->pages = pages; +@@ -1314,13 +1311,10 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, + npages); + if (ret) { + omap_gem_free_object(obj); +- obj = ERR_PTR(-ENOMEM); +- goto done; ++ return ERR_PTR(-ENOMEM); + } + } + +-done: +- mutex_unlock(&omap_obj->lock); + return obj; + } + +-- +2.43.0 + diff --git a/queue-5.10/drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch b/queue-5.10/drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch new file mode 100644 index 00000000000..58c4b04fe36 --- /dev/null +++ b/queue-5.10/drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch @@ -0,0 +1,35 @@ +From 38437b5d508313856d7cfa6d4b36551758d26c96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Oct 2024 15:00:07 +0100 +Subject: drm/panfrost: Remove unused id_mask from struct panfrost_model + +From: Steven Price + +[ Upstream commit 581d1f8248550f2b67847e6d84f29fbe3751ea0a ] + +The id_mask field of struct panfrost_model has never been used. + +Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver") +Signed-off-by: Steven Price +Reviewed-by: Boris Brezillon +Link: https://patchwork.freedesktop.org/patch/msgid/20241025140008.385081-1-steven.price@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panfrost/panfrost_gpu.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c +index 107ad2d764ec0..bff8cddfc7698 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c +@@ -158,7 +158,6 @@ static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev) + struct panfrost_model { + const char *name; + u32 id; +- u32 id_mask; + u64 features; + u64 issues; + struct { +-- +2.43.0 + diff --git a/queue-5.10/drm-v3d-address-race-condition-in-mmu-flush.patch b/queue-5.10/drm-v3d-address-race-condition-in-mmu-flush.patch new file mode 100644 index 00000000000..ed0f4596f5a --- /dev/null +++ b/queue-5.10/drm-v3d-address-race-condition-in-mmu-flush.patch @@ -0,0 +1,80 @@ +From 0c9c1aa6c3f618817425ea951dd93d853996d3bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Sep 2024 10:55:05 -0300 +Subject: drm/v3d: Address race-condition in MMU flush +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maíra Canal + +[ Upstream commit cf1becb7f996a0a23ea2c270cf6bb0911ec3ca1a ] + +We must first flush the MMU cache and then, flush the TLB, not the other +way around. Currently, we can see a race condition between the MMU cache +and the TLB when running multiple rendering processes at the same time. +This is evidenced by MMU errors triggered by the IRQ. + +Fix the MMU flush order by flushing the MMU cache and then the TLB. +Also, in order to address the race condition, wait for the MMU cache flush +to finish before starting the TLB flush. + +Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") +Signed-off-by: Maíra Canal +Reviewed-by: Iago Toral Quiroga +Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-2-mcanal@igalia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/v3d/v3d_mmu.c | 29 ++++++++++------------------- + 1 file changed, 10 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c +index 5a453532901f1..166d4a88daee5 100644 +--- a/drivers/gpu/drm/v3d/v3d_mmu.c ++++ b/drivers/gpu/drm/v3d/v3d_mmu.c +@@ -34,32 +34,23 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d) + { + int ret; + +- /* Make sure that another flush isn't already running when we +- * start this one. +- */ +- ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & +- V3D_MMU_CTL_TLB_CLEARING), 100); +- if (ret) +- dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n"); +- +- V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) | +- V3D_MMU_CTL_TLB_CLEAR); +- +- V3D_WRITE(V3D_MMUC_CONTROL, +- V3D_MMUC_CONTROL_FLUSH | ++ V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH | + V3D_MMUC_CONTROL_ENABLE); + +- ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & +- V3D_MMU_CTL_TLB_CLEARING), 100); ++ ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) & ++ V3D_MMUC_CONTROL_FLUSHING), 100); + if (ret) { +- dev_err(v3d->drm.dev, "TLB clear wait idle failed\n"); ++ dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); + return ret; + } + +- ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) & +- V3D_MMUC_CONTROL_FLUSHING), 100); ++ V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) | ++ V3D_MMU_CTL_TLB_CLEAR); ++ ++ ret = wait_for(!(V3D_READ(V3D_MMU_CTL) & ++ V3D_MMU_CTL_TLB_CLEARING), 100); + if (ret) +- dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); ++ dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n"); + + return ret; + } +-- +2.43.0 + diff --git a/queue-5.10/dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch b/queue-5.10/dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch new file mode 100644 index 00000000000..9e0b54c85ef --- /dev/null +++ b/queue-5.10/dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch @@ -0,0 +1,127 @@ +From a58d28eced75d00fdad90074a9565b17aeded5d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Oct 2020 17:34:20 +0300 +Subject: dt-bindings: clock: adi,axi-clkgen: convert old binding to yaml + format + +From: Alexandru Ardelean + +[ Upstream commit bd91abb218e0ac4a7402d6c25d383e2a706bb511 ] + +This change converts the old binding for the AXI clkgen driver to a yaml +format. + +As maintainers, added: + - Lars-Peter Clausen - as original author of driver & + binding + - Michael Hennerich - as supporter of + Analog Devices drivers + +Acked-by: Michael Hennerich +Acked-by: Lars-Peter Clausen +Signed-off-by: Alexandru Ardelean +Link: https://lore.kernel.org/r/20201013143421.84188-1-alexandru.ardelean@analog.com +Reviewed-by: Rob Herring +Signed-off-by: Stephen Boyd +Stable-dep-of: 47f3f5a82a31 ("dt-bindings: clock: axi-clkgen: include AXI clk") +Signed-off-by: Sasha Levin +--- + .../bindings/clock/adi,axi-clkgen.yaml | 53 +++++++++++++++++++ + .../devicetree/bindings/clock/axi-clkgen.txt | 25 --------- + 2 files changed, 53 insertions(+), 25 deletions(-) + create mode 100644 Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml + delete mode 100644 Documentation/devicetree/bindings/clock/axi-clkgen.txt + +diff --git a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +new file mode 100644 +index 0000000000000..0d06387184d68 +--- /dev/null ++++ b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +@@ -0,0 +1,53 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/clock/adi,axi-clkgen.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Binding for Analog Devices AXI clkgen pcore clock generator ++ ++maintainers: ++ - Lars-Peter Clausen ++ - Michael Hennerich ++ ++description: | ++ The axi_clkgen IP core is a software programmable clock generator, ++ that can be synthesized on various FPGA platforms. ++ ++ Link: https://wiki.analog.com/resources/fpga/docs/axi_clkgen ++ ++properties: ++ compatible: ++ enum: ++ - adi,axi-clkgen-2.00.a ++ ++ clocks: ++ description: ++ Specifies the reference clock(s) from which the output frequency is ++ derived. This must either reference one clock if only the first clock ++ input is connected or two if both clock inputs are connected. ++ minItems: 1 ++ maxItems: 2 ++ ++ '#clock-cells': ++ const: 0 ++ ++ reg: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ - '#clock-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ clock-controller@ff000000 { ++ compatible = "adi,axi-clkgen-2.00.a"; ++ #clock-cells = <0>; ++ reg = <0xff000000 0x1000>; ++ clocks = <&osc 1>; ++ }; +diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt +deleted file mode 100644 +index aca94fe9416f0..0000000000000 +--- a/Documentation/devicetree/bindings/clock/axi-clkgen.txt ++++ /dev/null +@@ -1,25 +0,0 @@ +-Binding for the axi-clkgen clock generator +- +-This binding uses the common clock binding[1]. +- +-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +- +-Required properties: +-- compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a". +-- #clock-cells : from common clock binding; Should always be set to 0. +-- reg : Address and length of the axi-clkgen register set. +-- clocks : Phandle and clock specifier for the parent clock(s). This must +- either reference one clock if only the first clock input is connected or two +- if both clock inputs are connected. For the later case the clock connected +- to the first input must be specified first. +- +-Optional properties: +-- clock-output-names : From common clock binding. +- +-Example: +- clock@ff000000 { +- compatible = "adi,axi-clkgen"; +- #clock-cells = <0>; +- reg = <0xff000000 0x1000>; +- clocks = <&osc 1>; +- }; +-- +2.43.0 + diff --git a/queue-5.10/dt-bindings-clock-axi-clkgen-include-axi-clk.patch b/queue-5.10/dt-bindings-clock-axi-clkgen-include-axi-clk.patch new file mode 100644 index 00000000000..f8396b62f35 --- /dev/null +++ b/queue-5.10/dt-bindings-clock-axi-clkgen-include-axi-clk.patch @@ -0,0 +1,72 @@ +From a19bac5e58672c5a27cd61114e4b8633bcbfa62d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 14:59:41 +0100 +Subject: dt-bindings: clock: axi-clkgen: include AXI clk + +From: Nuno Sa + +[ Upstream commit 47f3f5a82a31527e027929c5cec3dd1ef5ef30f5 ] + +In order to access the registers of the HW, we need to make sure that +the AXI bus clock is enabled. Hence let's increase the number of clocks +by one and add clock-names to differentiate between parent clocks and +the bus clock. + +Fixes: 0e646c52cf0e ("clk: Add axi-clkgen driver") +Signed-off-by: Nuno Sa +Link: https://lore.kernel.org/r/20241029-axi-clkgen-fix-axiclk-v2-1-bc5e0733ad76@analog.com +Reviewed-by: Conor Dooley +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + .../bindings/clock/adi,axi-clkgen.yaml | 22 +++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +index 0d06387184d68..bb2eec3021a09 100644 +--- a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml ++++ b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +@@ -25,9 +25,21 @@ properties: + description: + Specifies the reference clock(s) from which the output frequency is + derived. This must either reference one clock if only the first clock +- input is connected or two if both clock inputs are connected. +- minItems: 1 +- maxItems: 2 ++ input is connected or two if both clock inputs are connected. The last ++ clock is the AXI bus clock that needs to be enabled so we can access the ++ core registers. ++ minItems: 2 ++ maxItems: 3 ++ ++ clock-names: ++ oneOf: ++ - items: ++ - const: clkin1 ++ - const: s_axi_aclk ++ - items: ++ - const: clkin1 ++ - const: clkin2 ++ - const: s_axi_aclk + + '#clock-cells': + const: 0 +@@ -39,6 +51,7 @@ required: + - compatible + - reg + - clocks ++ - clock-names + - '#clock-cells' + + additionalProperties: false +@@ -49,5 +62,6 @@ examples: + compatible = "adi,axi-clkgen-2.00.a"; + #clock-cells = <0>; + reg = <0xff000000 0x1000>; +- clocks = <&osc 1>; ++ clocks = <&osc 1>, <&clkc 15>; ++ clock-names = "clkin1", "s_axi_aclk"; + }; +-- +2.43.0 + diff --git a/queue-5.10/dt-bindings-vendor-prefixes-add-neofidelity-inc.patch b/queue-5.10/dt-bindings-vendor-prefixes-add-neofidelity-inc.patch new file mode 100644 index 00000000000..82f42ad8cb0 --- /dev/null +++ b/queue-5.10/dt-bindings-vendor-prefixes-add-neofidelity-inc.patch @@ -0,0 +1,36 @@ +From 255dee8d0c4884ee531c6323605ea8389ac4cdb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 17:52:39 +0300 +Subject: dt-bindings: vendor-prefixes: Add NeoFidelity, Inc + +From: Igor Prusov + +[ Upstream commit 5d9e6d6fc1b98c8c22d110ee931b3b233d43cd13 ] + +Add vendor prefix for NeoFidelity, Inc + +Signed-off-by: Igor Prusov +Acked-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20240925-ntp-amps-8918-8835-v3-1-e2459a8191a6@salutedevices.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml +index 2735be1a84709..e04be09dd0291 100644 +--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml ++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml +@@ -718,6 +718,8 @@ patternProperties: + description: National Semiconductor + "^nec,.*": + description: NEC LCD Technologies, Ltd. ++ "^neofidelity,.*": ++ description: Neofidelity Inc. + "^neonode,.*": + description: Neonode Inc. + "^netgear,.*": +-- +2.43.0 + diff --git a/queue-5.10/edac-bluefield-fix-potential-integer-overflow.patch b/queue-5.10/edac-bluefield-fix-potential-integer-overflow.patch new file mode 100644 index 00000000000..e759abd886b --- /dev/null +++ b/queue-5.10/edac-bluefield-fix-potential-integer-overflow.patch @@ -0,0 +1,43 @@ +From 2cb2d90c2a50c56b9408338933baad9d002c9fb5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 11:10:56 -0400 +Subject: EDAC/bluefield: Fix potential integer overflow + +From: David Thompson + +[ Upstream commit 1fe774a93b46bb029b8f6fa9d1f25affa53f06c6 ] + +The 64-bit argument for the "get DIMM info" SMC call consists of mem_ctrl_idx +left-shifted 16 bits and OR-ed with DIMM index. With mem_ctrl_idx defined as +32-bits wide the left-shift operation truncates the upper 16 bits of +information during the calculation of the SMC argument. + +The mem_ctrl_idx stack variable must be defined as 64-bits wide to prevent any +potential integer overflow, i.e. loss of data from upper 16 bits. + +Fixes: 82413e562ea6 ("EDAC, mellanox: Add ECC support for BlueField DDR4") +Signed-off-by: David Thompson +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Shravan Kumar Ramani +Link: https://lore.kernel.org/r/20240930151056.10158-1-davthompson@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/edac/bluefield_edac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c +index e4736eb37bfb3..0ef0489827682 100644 +--- a/drivers/edac/bluefield_edac.c ++++ b/drivers/edac/bluefield_edac.c +@@ -180,7 +180,7 @@ static void bluefield_edac_check(struct mem_ctl_info *mci) + static void bluefield_edac_init_dimms(struct mem_ctl_info *mci) + { + struct bluefield_edac_priv *priv = mci->pvt_info; +- int mem_ctrl_idx = mci->mc_idx; ++ u64 mem_ctrl_idx = mci->mc_idx; + struct dimm_info *dimm; + u64 smc_info, smc_arg; + int is_empty = 1, i; +-- +2.43.0 + diff --git a/queue-5.10/edac-fsl_ddr-fix-bad-bit-shift-operations.patch b/queue-5.10/edac-fsl_ddr-fix-bad-bit-shift-operations.patch new file mode 100644 index 00000000000..40f0ff043e8 --- /dev/null +++ b/queue-5.10/edac-fsl_ddr-fix-bad-bit-shift-operations.patch @@ -0,0 +1,75 @@ +From b5f077f9d8c4678e5969507687d5f564223d7319 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 16:31:11 -0400 +Subject: EDAC/fsl_ddr: Fix bad bit shift operations + +From: Priyanka Singh + +[ Upstream commit 9ec22ac4fe766c6abba845290d5139a3fbe0153b ] + +Fix undefined behavior caused by left-shifting a negative value in the +expression: + + cap_high ^ (1 << (bad_data_bit - 32)) + +The variable bad_data_bit ranges from 0 to 63. When it is less than 32, +bad_data_bit - 32 becomes negative, and left-shifting by a negative +value in C is undefined behavior. + +Fix this by combining cap_high and cap_low into a 64-bit variable. + + [ bp: Massage commit message, simplify error bits handling. ] + +Fixes: ea2eb9a8b620 ("EDAC, fsl-ddr: Separate FSL DDR driver from MPC85xx") +Signed-off-by: Priyanka Singh +Signed-off-by: Li Yang +Signed-off-by: Frank Li +Signed-off-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/20241016-imx95_edac-v3-3-86ae6fc2756a@nxp.com +Signed-off-by: Sasha Levin +--- + drivers/edac/fsl_ddr_edac.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/edac/fsl_ddr_edac.c b/drivers/edac/fsl_ddr_edac.c +index 6d8ea226010d2..61e59341a41f9 100644 +--- a/drivers/edac/fsl_ddr_edac.c ++++ b/drivers/edac/fsl_ddr_edac.c +@@ -331,21 +331,25 @@ static void fsl_mc_check(struct mem_ctl_info *mci) + * TODO: Add support for 32-bit wide buses + */ + if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) { ++ u64 cap = (u64)cap_high << 32 | cap_low; ++ u32 s = syndrome; ++ + sbe_ecc_decode(cap_high, cap_low, syndrome, + &bad_data_bit, &bad_ecc_bit); + +- if (bad_data_bit != -1) +- fsl_mc_printk(mci, KERN_ERR, +- "Faulty Data bit: %d\n", bad_data_bit); +- if (bad_ecc_bit != -1) +- fsl_mc_printk(mci, KERN_ERR, +- "Faulty ECC bit: %d\n", bad_ecc_bit); ++ if (bad_data_bit >= 0) { ++ fsl_mc_printk(mci, KERN_ERR, "Faulty Data bit: %d\n", bad_data_bit); ++ cap ^= 1ULL << bad_data_bit; ++ } ++ ++ if (bad_ecc_bit >= 0) { ++ fsl_mc_printk(mci, KERN_ERR, "Faulty ECC bit: %d\n", bad_ecc_bit); ++ s ^= 1 << bad_ecc_bit; ++ } + + fsl_mc_printk(mci, KERN_ERR, + "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n", +- cap_high ^ (1 << (bad_data_bit - 32)), +- cap_low ^ (1 << bad_data_bit), +- syndrome ^ (1 << bad_ecc_bit)); ++ upper_32_bits(cap), lower_32_bits(cap), s); + } + + fsl_mc_printk(mci, KERN_ERR, +-- +2.43.0 + diff --git a/queue-5.10/f2fs-avoid-using-native-allocate_segment_by_default.patch b/queue-5.10/f2fs-avoid-using-native-allocate_segment_by_default.patch new file mode 100644 index 00000000000..afc3400c97b --- /dev/null +++ b/queue-5.10/f2fs-avoid-using-native-allocate_segment_by_default.patch @@ -0,0 +1,116 @@ +From c245736e3c9105efd360e64be37a1345925839b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Apr 2021 09:54:55 +0800 +Subject: f2fs: avoid using native allocate_segment_by_default() + +From: Chao Yu + +[ Upstream commit 509f1010e4fc55e2dbfc036317afd573ccd0931c ] + +As we did for other cases, in fix_curseg_write_pointer(), let's +use wrapped f2fs_allocate_new_section() instead of native +allocate_segment_by_default(), by this way, it fixes to cover +segment allocation with curseg_lock and sentry_lock. + +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg") +Signed-off-by: Sasha Levin +--- + fs/f2fs/f2fs.h | 2 +- + fs/f2fs/file.c | 2 +- + fs/f2fs/segment.c | 18 ++++++++++-------- + 3 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 3da7be53a3de4..10231d5bba159 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -3366,7 +3366,7 @@ void f2fs_get_new_segment(struct f2fs_sb_info *sbi, + unsigned int *newseg, bool new_sec, int dir); + void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type, + unsigned int start, unsigned int end); +-void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type); ++void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force); + void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi); + int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range); + bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi, +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 7ce22137afbe9..9ecf39c2b47d9 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1689,7 +1689,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset, + down_write(&sbi->pin_sem); + + f2fs_lock_op(sbi); +- f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED); ++ f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); + f2fs_unlock_op(sbi); + + map.m_seg_type = CURSEG_COLD_DATA_PINNED; +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index a37f88cc7c485..d2aad633529eb 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2937,7 +2937,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type, + } + + static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type, +- bool new_sec) ++ bool new_sec, bool force) + { + struct curseg_info *curseg = CURSEG_I(sbi, type); + unsigned int old_segno; +@@ -2945,7 +2945,7 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type, + if (!curseg->inited) + goto alloc; + +- if (curseg->next_blkoff || ++ if (force || curseg->next_blkoff || + get_valid_blocks(sbi, curseg->segno, new_sec)) + goto alloc; + +@@ -2957,16 +2957,17 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type, + locate_dirty_segment(sbi, old_segno); + } + +-static void __allocate_new_section(struct f2fs_sb_info *sbi, int type) ++static void __allocate_new_section(struct f2fs_sb_info *sbi, ++ int type, bool force) + { +- __allocate_new_segment(sbi, type, true); ++ __allocate_new_segment(sbi, type, true, force); + } + +-void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type) ++void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force) + { + down_read(&SM_I(sbi)->curseg_lock); + down_write(&SIT_I(sbi)->sentry_lock); +- __allocate_new_section(sbi, type); ++ __allocate_new_section(sbi, type, force); + up_write(&SIT_I(sbi)->sentry_lock); + up_read(&SM_I(sbi)->curseg_lock); + } +@@ -2978,7 +2979,7 @@ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi) + down_read(&SM_I(sbi)->curseg_lock); + down_write(&SIT_I(sbi)->sentry_lock); + for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) +- __allocate_new_segment(sbi, i, false); ++ __allocate_new_segment(sbi, i, false, false); + up_write(&SIT_I(sbi)->sentry_lock); + up_read(&SM_I(sbi)->curseg_lock); + } +@@ -4867,7 +4868,8 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type) + + f2fs_notice(sbi, "Assign new section to curseg[%d]: " + "curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff); +- allocate_segment_by_default(sbi, type, true); ++ ++ f2fs_allocate_new_section(sbi, type, true); + + /* check consistency of the zone curseg pointed to */ + if (check_zone_write_pointer(sbi, zbd, &zone)) +-- +2.43.0 + diff --git a/queue-5.10/f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch b/queue-5.10/f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch new file mode 100644 index 00000000000..0bab7d7f694 --- /dev/null +++ b/queue-5.10/f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch @@ -0,0 +1,39 @@ +From 26a21df69860ae83861dffd08b7e5326c5f4fdae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Oct 2024 12:48:01 +0800 +Subject: f2fs: check curseg->inited before write_sum_page in change_curseg + +From: Yongpeng Yang + +[ Upstream commit 43563069e1c1df417d2eed6eca8a22fc6b04691d ] + +In the __f2fs_init_atgc_curseg->get_atssr_segment calling, +curseg->segno is NULL_SEGNO, indicating that there is no summary +block that needs to be written. + +Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection") +Signed-off-by: Yongpeng Yang +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index d99c9e6a0b3e4..a6d05264f1365 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2691,7 +2691,8 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type) + struct f2fs_summary_block *sum_node; + struct page *sum_page; + +- write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno)); ++ if (curseg->inited) ++ write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno)); + + __set_test_and_inuse(sbi, new_segno); + +-- +2.43.0 + diff --git a/queue-5.10/f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch b/queue-5.10/f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch new file mode 100644 index 00000000000..df1eb8b1d10 --- /dev/null +++ b/queue-5.10/f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch @@ -0,0 +1,40 @@ +From feb2648884bfc3341347b07065a37125dbf70e0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Oct 2024 10:31:47 +0800 +Subject: f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block + +From: LongPing Wei + +[ Upstream commit c3af1f13476ec23fd99c98d060a89be28c1e8871 ] + +This f2fs_bug_on was introduced by commit 2c1905042c8c ("f2fs: check +segment type in __f2fs_replace_block") when there were only 6 curseg types. +After commit d0b9e42ab615 ("f2fs: introduce inmem curseg") was introduced, +the condition should be changed to checking curseg->seg_type. + +Fixes: d0b9e42ab615 ("f2fs: introduce inmem curseg") +Signed-off-by: LongPing Wei +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index 6fcc83637b153..a37f88cc7c485 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -3617,8 +3617,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + } + } + +- f2fs_bug_on(sbi, !IS_DATASEG(type)); + curseg = CURSEG_I(sbi, type); ++ f2fs_bug_on(sbi, !IS_DATASEG(curseg->seg_type)); + + mutex_lock(&curseg->curseg_mutex); + down_write(&sit_i->sentry_lock); +-- +2.43.0 + diff --git a/queue-5.10/f2fs-open-code-allocate_segment_by_default.patch b/queue-5.10/f2fs-open-code-allocate_segment_by_default.patch new file mode 100644 index 00000000000..953698867df --- /dev/null +++ b/queue-5.10/f2fs-open-code-allocate_segment_by_default.patch @@ -0,0 +1,106 @@ +From 375a0d1ab459ab2236fed043691922034d90eff3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 10:43:45 +0100 +Subject: f2fs: open code allocate_segment_by_default + +From: Christoph Hellwig + +[ Upstream commit 8442d94b8ac8d5d8300725a9ffa9def526b71170 ] + +allocate_segment_by_default has just two callers, which use very +different code pathes inside it based on the force paramter. Just +open code the logic in the two callers using a new helper to decided +if a new segment should be allocated. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg") +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 50 +++++++++++++++++++++++------------------------ + 1 file changed, 24 insertions(+), 26 deletions(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index 82f8a86d7d701..7d6f2ee2f0177 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2876,31 +2876,20 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type, + return 0; + } + +-/* +- * flush out current segment and replace it with new segment +- * This function should be returned with success, otherwise BUG +- */ +-static void allocate_segment_by_default(struct f2fs_sb_info *sbi, +- int type, bool force) ++static bool need_new_seg(struct f2fs_sb_info *sbi, int type) + { + struct curseg_info *curseg = CURSEG_I(sbi, type); + +- if (force) +- new_curseg(sbi, type, true); +- else if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) && +- curseg->seg_type == CURSEG_WARM_NODE) +- new_curseg(sbi, type, false); +- else if (curseg->alloc_type == LFS && +- is_next_segment_free(sbi, curseg, type) && +- likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED))) +- new_curseg(sbi, type, false); +- else if (f2fs_need_SSR(sbi) && +- get_ssr_segment(sbi, type, SSR, 0)) +- change_curseg(sbi, type, true); +- else +- new_curseg(sbi, type, false); +- +- stat_inc_seg_type(sbi, curseg); ++ if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) && ++ curseg->seg_type == CURSEG_WARM_NODE) ++ return true; ++ if (curseg->alloc_type == LFS && ++ is_next_segment_free(sbi, curseg, type) && ++ likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED))) ++ return true; ++ if (!f2fs_need_SSR(sbi) || !get_ssr_segment(sbi, type, SSR, 0)) ++ return true; ++ return false; + } + + void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type, +@@ -2953,7 +2942,8 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type, + return; + alloc: + old_segno = curseg->segno; +- allocate_segment_by_default(sbi, type, true); ++ new_curseg(sbi, type, true); ++ stat_inc_seg_type(sbi, curseg); + locate_dirty_segment(sbi, old_segno); + } + +@@ -3393,11 +3383,19 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, + update_sit_entry(sbi, old_blkaddr, -1); + + if (!__has_curseg_space(sbi, curseg)) { +- if (from_gc) ++ /* ++ * Flush out current segment and replace it with new segment. ++ */ ++ if (from_gc) { + get_atssr_segment(sbi, type, se->type, + AT_SSR, se->mtime); +- else +- allocate_segment_by_default(sbi, type, false); ++ } else { ++ if (need_new_seg(sbi, type)) ++ new_curseg(sbi, type, false); ++ else ++ change_curseg(sbi, type, true); ++ stat_inc_seg_type(sbi, curseg); ++ } + } + /* + * segment dirty status should be updated after segment allocation, +-- +2.43.0 + diff --git a/queue-5.10/f2fs-remove-struct-segment_allocation-default_salloc.patch b/queue-5.10/f2fs-remove-struct-segment_allocation-default_salloc.patch new file mode 100644 index 00000000000..e2c2ec52082 --- /dev/null +++ b/queue-5.10/f2fs-remove-struct-segment_allocation-default_salloc.patch @@ -0,0 +1,92 @@ +From 518141ff44add897384fc6b7044f9d63027ad07f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 10:43:44 +0100 +Subject: f2fs: remove struct segment_allocation default_salloc_ops + +From: Christoph Hellwig + +[ Upstream commit 1c8a8ec0a0e9a1176022a35c4daf04fe1594d270 ] + +There is only single instance of these ops, so remove the indirection +and call allocate_segment_by_default directly. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg") +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 11 ++--------- + fs/f2fs/segment.h | 6 ------ + 2 files changed, 2 insertions(+), 15 deletions(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index d2aad633529eb..82f8a86d7d701 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2953,7 +2953,7 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type, + return; + alloc: + old_segno = curseg->segno; +- SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true); ++ allocate_segment_by_default(sbi, type, true); + locate_dirty_segment(sbi, old_segno); + } + +@@ -2984,10 +2984,6 @@ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi) + up_read(&SM_I(sbi)->curseg_lock); + } + +-static const struct segment_allocation default_salloc_ops = { +- .allocate_segment = allocate_segment_by_default, +-}; +- + bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi, + struct cp_control *cpc) + { +@@ -3401,7 +3397,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, + get_atssr_segment(sbi, type, se->type, + AT_SSR, se->mtime); + else +- sit_i->s_ops->allocate_segment(sbi, type, false); ++ allocate_segment_by_default(sbi, type, false); + } + /* + * segment dirty status should be updated after segment allocation, +@@ -4337,9 +4333,6 @@ static int build_sit_info(struct f2fs_sb_info *sbi) + return -ENOMEM; + #endif + +- /* init SIT information */ +- sit_i->s_ops = &default_salloc_ops; +- + sit_i->sit_base_addr = le32_to_cpu(raw_super->sit_blkaddr); + sit_i->sit_blocks = sit_segs << sbi->log_blocks_per_seg; + sit_i->written_valid_blocks = 0; +diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h +index 665e0e186687d..720951ce2f9d1 100644 +--- a/fs/f2fs/segment.h ++++ b/fs/f2fs/segment.h +@@ -227,10 +227,6 @@ struct sec_entry { + unsigned int valid_blocks; /* # of valid blocks in a section */ + }; + +-struct segment_allocation { +- void (*allocate_segment)(struct f2fs_sb_info *, int, bool); +-}; +- + #define MAX_SKIP_GC_COUNT 16 + + struct inmem_pages { +@@ -240,8 +236,6 @@ struct inmem_pages { + }; + + struct sit_info { +- const struct segment_allocation *s_ops; +- + block_t sit_base_addr; /* start block address of SIT area */ + block_t sit_blocks; /* # of blocks used by SIT area */ + block_t written_valid_blocks; /* # of valid blocks in main area */ +-- +2.43.0 + diff --git a/queue-5.10/f2fs-remove-the-unused-flush-argument-to-change_curs.patch b/queue-5.10/f2fs-remove-the-unused-flush-argument-to-change_curs.patch new file mode 100644 index 00000000000..9b54bea654e --- /dev/null +++ b/queue-5.10/f2fs-remove-the-unused-flush-argument-to-change_curs.patch @@ -0,0 +1,90 @@ +From b67d455381f69ee1e5df1d6a70b862356b7b3e7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Nov 2022 10:43:46 +0100 +Subject: f2fs: remove the unused flush argument to change_curseg + +From: Christoph Hellwig + +[ Upstream commit 5bcd655fffaec24e849bda1207446f5cc821713e ] + +Signed-off-by: Christoph Hellwig +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg") +Signed-off-by: Sasha Levin +--- + fs/f2fs/segment.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c +index 7d6f2ee2f0177..d99c9e6a0b3e4 100644 +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -2683,7 +2683,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno) + * This function always allocates a used segment(from dirty seglist) by SSR + * manner, so it should recover the existing segment information of valid blocks + */ +-static void change_curseg(struct f2fs_sb_info *sbi, int type, bool flush) ++static void change_curseg(struct f2fs_sb_info *sbi, int type) + { + struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); + struct curseg_info *curseg = CURSEG_I(sbi, type); +@@ -2691,9 +2691,7 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type, bool flush) + struct f2fs_summary_block *sum_node; + struct page *sum_page; + +- if (flush) +- write_sum_page(sbi, curseg->sum_blk, +- GET_SUM_BLOCK(sbi, curseg->segno)); ++ write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno)); + + __set_test_and_inuse(sbi, new_segno); + +@@ -2732,7 +2730,7 @@ static void get_atssr_segment(struct f2fs_sb_info *sbi, int type, + struct seg_entry *se = get_seg_entry(sbi, curseg->next_segno); + + curseg->seg_type = se->type; +- change_curseg(sbi, type, true); ++ change_curseg(sbi, type); + } else { + /* allocate cold segment by default */ + curseg->seg_type = CURSEG_COLD_DATA; +@@ -2907,7 +2905,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type, + goto unlock; + + if (f2fs_need_SSR(sbi) && get_ssr_segment(sbi, type, SSR, 0)) +- change_curseg(sbi, type, true); ++ change_curseg(sbi, type); + else + new_curseg(sbi, type, true); + +@@ -3393,7 +3391,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, + if (need_new_seg(sbi, type)) + new_curseg(sbi, type, false); + else +- change_curseg(sbi, type, true); ++ change_curseg(sbi, type); + stat_inc_seg_type(sbi, curseg); + } + } +@@ -3624,7 +3622,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + /* change the current segment */ + if (segno != curseg->segno) { + curseg->next_segno = segno; +- change_curseg(sbi, type, true); ++ change_curseg(sbi, type); + } + + curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); +@@ -3651,7 +3649,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, + if (recover_curseg) { + if (old_cursegno != curseg->segno) { + curseg->next_segno = old_cursegno; +- change_curseg(sbi, type, true); ++ change_curseg(sbi, type); + } + curseg->next_blkoff = old_blkoff; + } +-- +2.43.0 + diff --git a/queue-5.10/fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch b/queue-5.10/fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch new file mode 100644 index 00000000000..4bfd7ffc109 --- /dev/null +++ b/queue-5.10/fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch @@ -0,0 +1,65 @@ +From a7a426038cc2b086e13c44aabfaab8088fe7da94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Jun 2023 13:07:02 +0200 +Subject: fbdev/sh7760fb: Alloc DMA memory from hardware device + +From: Thomas Zimmermann + +[ Upstream commit 8404e56f4bc1d1a65bfc98450ba3dae5e653dda1 ] + +Pass the hardware device to the DMA helpers dma_alloc_coherent() and +dma_free_coherent(). The fbdev device that is currently being used is +a software device and does not provide DMA memory. Also update the +related dev_*() output statements similarly. + +Signed-off-by: Thomas Zimmermann +Reviewed-by: Javier Martinez Canillas +Link: https://patchwork.freedesktop.org/patch/msgid/20230613110953.24176-28-tzimmermann@suse.de +Stable-dep-of: f89d17ae2ac4 ("fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()") +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/sh7760fb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/fbdev/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c +index 5978a89212322..6adf048c1bae8 100644 +--- a/drivers/video/fbdev/sh7760fb.c ++++ b/drivers/video/fbdev/sh7760fb.c +@@ -359,7 +359,7 @@ static void sh7760fb_free_mem(struct fb_info *info) + if (!info->screen_base) + return; + +- dma_free_coherent(info->dev, info->screen_size, ++ dma_free_coherent(info->device, info->screen_size, + info->screen_base, par->fbdma); + + par->fbdma = 0; +@@ -408,14 +408,14 @@ static int sh7760fb_alloc_mem(struct fb_info *info) + if (vram < PAGE_SIZE) + vram = PAGE_SIZE; + +- fbmem = dma_alloc_coherent(info->dev, vram, &par->fbdma, GFP_KERNEL); ++ fbmem = dma_alloc_coherent(info->device, vram, &par->fbdma, GFP_KERNEL); + + if (!fbmem) + return -ENOMEM; + + if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) { + sh7760fb_free_mem(info); +- dev_err(info->dev, "kernel gave me memory at 0x%08lx, which is" ++ dev_err(info->device, "kernel gave me memory at 0x%08lx, which is" + "unusable for the LCDC\n", (unsigned long)par->fbdma); + return -ENOMEM; + } +@@ -486,7 +486,7 @@ static int sh7760fb_probe(struct platform_device *pdev) + + ret = sh7760fb_alloc_mem(info); + if (ret) { +- dev_dbg(info->dev, "framebuffer memory allocation failed!\n"); ++ dev_dbg(info->device, "framebuffer memory allocation failed!\n"); + goto out_unmap; + } + +-- +2.43.0 + diff --git a/queue-5.10/fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch b/queue-5.10/fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch new file mode 100644 index 00000000000..efcac66dffd --- /dev/null +++ b/queue-5.10/fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch @@ -0,0 +1,43 @@ +From f27fe7cb3f931e1b9348eea865616a1c9af9d968 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Oct 2024 11:56:34 +0800 +Subject: fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem() + +From: Zhen Lei + +[ Upstream commit f89d17ae2ac42931be2a0153fecbf8533280c927 ] + +When information such as info->screen_base is not ready, calling +sh7760fb_free_mem() does not release memory correctly. Call +dma_free_coherent() instead. + +Fixes: 4a25e41831ee ("video: sh7760fb: SH7760/SH7763 LCDC framebuffer driver") +Signed-off-by: Zhen Lei +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/sh7760fb.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/video/fbdev/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c +index 6adf048c1bae8..62e28d315d815 100644 +--- a/drivers/video/fbdev/sh7760fb.c ++++ b/drivers/video/fbdev/sh7760fb.c +@@ -409,12 +409,11 @@ static int sh7760fb_alloc_mem(struct fb_info *info) + vram = PAGE_SIZE; + + fbmem = dma_alloc_coherent(info->device, vram, &par->fbdma, GFP_KERNEL); +- + if (!fbmem) + return -ENOMEM; + + if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) { +- sh7760fb_free_mem(info); ++ dma_free_coherent(info->device, vram, fbmem, par->fbdma); + dev_err(info->device, "kernel gave me memory at 0x%08lx, which is" + "unusable for the LCDC\n", (unsigned long)par->fbdma); + return -ENOMEM; +-- +2.43.0 + diff --git a/queue-5.10/firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch b/queue-5.10/firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch new file mode 100644 index 00000000000..28c95e42827 --- /dev/null +++ b/queue-5.10/firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch @@ -0,0 +1,93 @@ +From 3f869111ba201a954ef5e5c5997b48e5d2645379 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Nov 2024 11:21:15 +0800 +Subject: firmware: arm_scpi: Check the DVFS OPP count returned by the firmware + +From: Luo Qiu + +[ Upstream commit 109aa654f85c5141e813b2cd1bd36d90be678407 ] + +Fix a kernel crash with the below call trace when the SCPI firmware +returns OPP count of zero. + +dvfs_info.opp_count may be zero on some platforms during the reboot +test, and the kernel will crash after dereferencing the pointer to +kcalloc(info->count, sizeof(*opp), GFP_KERNEL). + + | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028 + | Mem abort info: + | ESR = 0x96000004 + | Exception class = DABT (current EL), IL = 32 bits + | SET = 0, FnV = 0 + | EA = 0, S1PTW = 0 + | Data abort info: + | ISV = 0, ISS = 0x00000004 + | CM = 0, WnR = 0 + | user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000faefa08c + | [0000000000000028] pgd=0000000000000000 + | Internal error: Oops: 96000004 [#1] SMP + | scpi-hwmon: probe of PHYT000D:00 failed with error -110 + | Process systemd-udevd (pid: 1701, stack limit = 0x00000000aaede86c) + | CPU: 2 PID: 1701 Comm: systemd-udevd Not tainted 4.19.90+ #1 + | Hardware name: PHYTIUM LTD Phytium FT2000/4/Phytium FT2000/4, BIOS + | pstate: 60000005 (nZCv daif -PAN -UAO) + | pc : scpi_dvfs_recalc_rate+0x40/0x58 [clk_scpi] + | lr : clk_register+0x438/0x720 + | Call trace: + | scpi_dvfs_recalc_rate+0x40/0x58 [clk_scpi] + | devm_clk_hw_register+0x50/0xa0 + | scpi_clk_ops_init.isra.2+0xa0/0x138 [clk_scpi] + | scpi_clocks_probe+0x528/0x70c [clk_scpi] + | platform_drv_probe+0x58/0xa8 + | really_probe+0x260/0x3d0 + | driver_probe_device+0x12c/0x148 + | device_driver_attach+0x74/0x98 + | __driver_attach+0xb4/0xe8 + | bus_for_each_dev+0x88/0xe0 + | driver_attach+0x30/0x40 + | bus_add_driver+0x178/0x2b0 + | driver_register+0x64/0x118 + | __platform_driver_register+0x54/0x60 + | scpi_clocks_driver_init+0x24/0x1000 [clk_scpi] + | do_one_initcall+0x54/0x220 + | do_init_module+0x54/0x1c8 + | load_module+0x14a4/0x1668 + | __se_sys_finit_module+0xf8/0x110 + | __arm64_sys_finit_module+0x24/0x30 + | el0_svc_common+0x78/0x170 + | el0_svc_handler+0x38/0x78 + | el0_svc+0x8/0x340 + | Code: 937d7c00 a94153f3 a8c27bfd f9400421 (b8606820) + | ---[ end trace 06feb22469d89fa8 ]--- + | Kernel panic - not syncing: Fatal exception + | SMP: stopping secondary CPUs + | Kernel Offset: disabled + | CPU features: 0x10,a0002008 + | Memory Limit: none + +Fixes: 8cb7cf56c9fe ("firmware: add support for ARM System Control and Power Interface(SCPI) protocol") +Signed-off-by: Luo Qiu +Message-Id: <55A2F7A784391686+20241101032115.275977-1-luoqiu@kylinsec.com.cn> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scpi.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c +index 36391cb5130e2..3a1d77b882f7e 100644 +--- a/drivers/firmware/arm_scpi.c ++++ b/drivers/firmware/arm_scpi.c +@@ -627,6 +627,9 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) + if (ret) + return ERR_PTR(ret); + ++ if (!buf.opp_count) ++ return ERR_PTR(-ENOENT); ++ + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); +-- +2.43.0 + diff --git a/queue-5.10/firmware-google-unregister-driver_info-on-failure.patch b/queue-5.10/firmware-google-unregister-driver_info-on-failure.patch new file mode 100644 index 00000000000..2b0346f59e4 --- /dev/null +++ b/queue-5.10/firmware-google-unregister-driver_info-on-failure.patch @@ -0,0 +1,53 @@ +From 16d67607e7a8853f94006c6a206671191ca7f036 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Oct 2024 21:13:44 +0800 +Subject: firmware: google: Unregister driver_info on failure + +From: Yuan Can + +[ Upstream commit 32b0901e141f6d4cf49d820b53eb09b88b1f72f7 ] + +When platform_device_register_full() returns error, the gsmi_init() returns +without unregister gsmi_driver_info, fix by add missing +platform_driver_unregister() when platform_device_register_full() failed. + +Fixes: 8942b2d5094b ("gsmi: Add GSMI commands to log S0ix info") +Signed-off-by: Yuan Can +Acked-by: Brian Norris +Link: https://lore.kernel.org/r/20241015131344.20272-1-yuancan@huawei.com +Signed-off-by: Tzung-Bi Shih +Signed-off-by: Sasha Levin +--- + drivers/firmware/google/gsmi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c +index 407cac71c77de..c82d38436b9b6 100644 +--- a/drivers/firmware/google/gsmi.c ++++ b/drivers/firmware/google/gsmi.c +@@ -917,7 +917,8 @@ static __init int gsmi_init(void) + gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info); + if (IS_ERR(gsmi_dev.pdev)) { + printk(KERN_ERR "gsmi: unable to register platform device\n"); +- return PTR_ERR(gsmi_dev.pdev); ++ ret = PTR_ERR(gsmi_dev.pdev); ++ goto out_unregister; + } + + /* SMI access needs to be serialized */ +@@ -1044,10 +1045,11 @@ static __init int gsmi_init(void) + gsmi_buf_free(gsmi_dev.name_buf); + dma_pool_destroy(gsmi_dev.dma_pool); + platform_device_unregister(gsmi_dev.pdev); +- pr_info("gsmi: failed to load: %d\n", ret); ++out_unregister: + #ifdef CONFIG_PM + platform_driver_unregister(&gsmi_driver_info); + #endif ++ pr_info("gsmi: failed to load: %d\n", ret); + return ret; + } + +-- +2.43.0 + diff --git a/queue-5.10/fs_parser-update-mount_api-doc-to-match-function-sig.patch b/queue-5.10/fs_parser-update-mount_api-doc-to-match-function-sig.patch new file mode 100644 index 00000000000..d1be9367c55 --- /dev/null +++ b/queue-5.10/fs_parser-update-mount_api-doc-to-match-function-sig.patch @@ -0,0 +1,45 @@ +From 98dd6904a706ce12fb170d6ddc4a7c73f0380ac8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Nov 2024 13:50:21 -0800 +Subject: fs_parser: update mount_api doc to match function signature + +From: Randy Dunlap + +[ Upstream commit c66f759832a83cb273ba5a55c66dcc99384efa74 ] + +Add the missing 'name' parameter to the mount_api documentation for +fs_validate_description(). + +Fixes: 96cafb9ccb15 ("fs_parser: remove fs_parameter_description name field") +Signed-off-by: Randy Dunlap +Link: https://lore.kernel.org/r/20241125215021.231758-1-rdunlap@infradead.org +Cc: Eric Sandeen +Cc: David Howells +Cc: Al Viro +Cc: Christian Brauner +Cc: Jan Kara +Cc: Jonathan Corbet +Cc: linux-doc@vger.kernel.org +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + Documentation/filesystems/mount_api.rst | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Documentation/filesystems/mount_api.rst b/Documentation/filesystems/mount_api.rst +index d7f53d62b5bb2..8fb03f57546d1 100644 +--- a/Documentation/filesystems/mount_api.rst ++++ b/Documentation/filesystems/mount_api.rst +@@ -778,7 +778,8 @@ process the parameters it is given. + + * :: + +- bool fs_validate_description(const struct fs_parameter_description *desc); ++ bool fs_validate_description(const char *name, ++ const struct fs_parameter_description *desc); + + This performs some validation checks on a parameter description. It + returns true if the description is good and false if it is not. It will +-- +2.43.0 + diff --git a/queue-5.10/hfsplus-don-t-query-the-device-logical-block-size-mu.patch b/queue-5.10/hfsplus-don-t-query-the-device-logical-block-size-mu.patch new file mode 100644 index 00000000000..ebb7433a3dd --- /dev/null +++ b/queue-5.10/hfsplus-don-t-query-the-device-logical-block-size-mu.patch @@ -0,0 +1,139 @@ +From defc2ec0baf6ce4d2f67c2795346036f2ba0ea5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2024 08:41:09 -0300 +Subject: hfsplus: don't query the device logical block size multiple times + +From: Thadeu Lima de Souza Cascardo + +[ Upstream commit 1c82587cb57687de3f18ab4b98a8850c789bedcf ] + +Devices block sizes may change. One of these cases is a loop device by +using ioctl LOOP_SET_BLOCK_SIZE. + +While this may cause other issues like IO being rejected, in the case of +hfsplus, it will allocate a block by using that size and potentially write +out-of-bounds when hfsplus_read_wrapper calls hfsplus_submit_bio and the +latter function reads a different io_size. + +Using a new min_io_size initally set to sb_min_blocksize works for the +purposes of the original fix, since it will be set to the max between +HFSPLUS_SECTOR_SIZE and the first seen logical block size. We still use the +max between HFSPLUS_SECTOR_SIZE and min_io_size in case the latter is not +initialized. + +Tested by mounting an hfsplus filesystem with loop block sizes 512, 1024 +and 4096. + +The produced KASAN report before the fix looks like this: + +[ 419.944641] ================================================================== +[ 419.945655] BUG: KASAN: slab-use-after-free in hfsplus_read_wrapper+0x659/0xa0a +[ 419.946703] Read of size 2 at addr ffff88800721fc00 by task repro/10678 +[ 419.947612] +[ 419.947846] CPU: 0 UID: 0 PID: 10678 Comm: repro Not tainted 6.12.0-rc5-00008-gdf56e0f2f3ca #84 +[ 419.949007] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 +[ 419.950035] Call Trace: +[ 419.950384] +[ 419.950676] dump_stack_lvl+0x57/0x78 +[ 419.951212] ? hfsplus_read_wrapper+0x659/0xa0a +[ 419.951830] print_report+0x14c/0x49e +[ 419.952361] ? __virt_addr_valid+0x267/0x278 +[ 419.952979] ? kmem_cache_debug_flags+0xc/0x1d +[ 419.953561] ? hfsplus_read_wrapper+0x659/0xa0a +[ 419.954231] kasan_report+0x89/0xb0 +[ 419.954748] ? hfsplus_read_wrapper+0x659/0xa0a +[ 419.955367] hfsplus_read_wrapper+0x659/0xa0a +[ 419.955948] ? __pfx_hfsplus_read_wrapper+0x10/0x10 +[ 419.956618] ? do_raw_spin_unlock+0x59/0x1a9 +[ 419.957214] ? _raw_spin_unlock+0x1a/0x2e +[ 419.957772] hfsplus_fill_super+0x348/0x1590 +[ 419.958355] ? hlock_class+0x4c/0x109 +[ 419.958867] ? __pfx_hfsplus_fill_super+0x10/0x10 +[ 419.959499] ? __pfx_string+0x10/0x10 +[ 419.960006] ? lock_acquire+0x3e2/0x454 +[ 419.960532] ? bdev_name.constprop.0+0xce/0x243 +[ 419.961129] ? __pfx_bdev_name.constprop.0+0x10/0x10 +[ 419.961799] ? pointer+0x3f0/0x62f +[ 419.962277] ? __pfx_pointer+0x10/0x10 +[ 419.962761] ? vsnprintf+0x6c4/0xfba +[ 419.963178] ? __pfx_vsnprintf+0x10/0x10 +[ 419.963621] ? setup_bdev_super+0x376/0x3b3 +[ 419.964029] ? snprintf+0x9d/0xd2 +[ 419.964344] ? __pfx_snprintf+0x10/0x10 +[ 419.964675] ? lock_acquired+0x45c/0x5e9 +[ 419.965016] ? set_blocksize+0x139/0x1c1 +[ 419.965381] ? sb_set_blocksize+0x6d/0xae +[ 419.965742] ? __pfx_hfsplus_fill_super+0x10/0x10 +[ 419.966179] mount_bdev+0x12f/0x1bf +[ 419.966512] ? __pfx_mount_bdev+0x10/0x10 +[ 419.966886] ? vfs_parse_fs_string+0xce/0x111 +[ 419.967293] ? __pfx_vfs_parse_fs_string+0x10/0x10 +[ 419.967702] ? __pfx_hfsplus_mount+0x10/0x10 +[ 419.968073] legacy_get_tree+0x104/0x178 +[ 419.968414] vfs_get_tree+0x86/0x296 +[ 419.968751] path_mount+0xba3/0xd0b +[ 419.969157] ? __pfx_path_mount+0x10/0x10 +[ 419.969594] ? kmem_cache_free+0x1e2/0x260 +[ 419.970311] do_mount+0x99/0xe0 +[ 419.970630] ? __pfx_do_mount+0x10/0x10 +[ 419.971008] __do_sys_mount+0x199/0x1c9 +[ 419.971397] do_syscall_64+0xd0/0x135 +[ 419.971761] entry_SYSCALL_64_after_hwframe+0x76/0x7e +[ 419.972233] RIP: 0033:0x7c3cb812972e +[ 419.972564] Code: 48 8b 0d f5 46 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c2 46 0d 00 f7 d8 64 89 01 48 +[ 419.974371] RSP: 002b:00007ffe30632548 EFLAGS: 00000286 ORIG_RAX: 00000000000000a5 +[ 419.975048] RAX: ffffffffffffffda RBX: 00007ffe306328d8 RCX: 00007c3cb812972e +[ 419.975701] RDX: 0000000020000000 RSI: 0000000020000c80 RDI: 00007ffe306325d0 +[ 419.976363] RBP: 00007ffe30632720 R08: 00007ffe30632610 R09: 0000000000000000 +[ 419.977034] R10: 0000000000200008 R11: 0000000000000286 R12: 0000000000000000 +[ 419.977713] R13: 00007ffe306328e8 R14: 00005a0eb298bc68 R15: 00007c3cb8356000 +[ 419.978375] +[ 419.978589] + +Fixes: 6596528e391a ("hfsplus: ensure bio requests are not smaller than the hardware sectors") +Signed-off-by: Thadeu Lima de Souza Cascardo +Link: https://lore.kernel.org/r/20241107114109.839253-1-cascardo@igalia.com +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/hfsplus/hfsplus_fs.h | 3 ++- + fs/hfsplus/wrapper.c | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h +index bfbe88e804eb0..c37a2f3d88af0 100644 +--- a/fs/hfsplus/hfsplus_fs.h ++++ b/fs/hfsplus/hfsplus_fs.h +@@ -156,6 +156,7 @@ struct hfsplus_sb_info { + + /* Runtime variables */ + u32 blockoffset; ++ u32 min_io_size; + sector_t part_start; + sector_t sect_count; + int fs_shift; +@@ -306,7 +307,7 @@ struct hfsplus_readdir_data { + */ + static inline unsigned short hfsplus_min_io_size(struct super_block *sb) + { +- return max_t(unsigned short, bdev_logical_block_size(sb->s_bdev), ++ return max_t(unsigned short, HFSPLUS_SB(sb)->min_io_size, + HFSPLUS_SECTOR_SIZE); + } + +diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c +index 0350dc7821bf9..59ba0a30f5392 100644 +--- a/fs/hfsplus/wrapper.c ++++ b/fs/hfsplus/wrapper.c +@@ -173,6 +173,8 @@ int hfsplus_read_wrapper(struct super_block *sb) + if (!blocksize) + goto out; + ++ sbi->min_io_size = blocksize; ++ + if (hfsplus_get_last_session(sb, &part_start, &part_size)) + goto out; + +-- +2.43.0 + diff --git a/queue-5.10/iio-light-al3010-fix-an-error-handling-path-in-al301.patch b/queue-5.10/iio-light-al3010-fix-an-error-handling-path-in-al301.patch new file mode 100644 index 00000000000..73efece7aad --- /dev/null +++ b/queue-5.10/iio-light-al3010-fix-an-error-handling-path-in-al301.patch @@ -0,0 +1,58 @@ +From 00cbdd904ef721e4215a7eef57f7fc1a3e88fbcf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 20:36:06 +0200 +Subject: iio: light: al3010: Fix an error handling path in al3010_probe() + +From: Christophe JAILLET + +[ Upstream commit a4b7064d34186cf4970fe0333c3b27346cf8f819 ] + +If i2c_smbus_write_byte_data() fails in al3010_init(), +al3010_set_pwr(false) is not called. + +In order to avoid such a situation, move the devm_add_action_or_reset() +witch calls al3010_set_pwr(false) right after a successful +al3010_set_pwr(true). + +Fixes: c36b5195ab70 ("iio: light: add Dyna-Image AL3010 driver") +Signed-off-by: Christophe JAILLET +Link: https://patch.msgid.link/ee5d10a2dd2b70f29772d5df33774d3974a80f30.1725993353.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/light/al3010.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c +index b4e9924094cd1..bd83e73e68026 100644 +--- a/drivers/iio/light/al3010.c ++++ b/drivers/iio/light/al3010.c +@@ -87,7 +87,12 @@ static int al3010_init(struct al3010_data *data) + int ret; + + ret = al3010_set_pwr(data->client, true); ++ if (ret < 0) ++ return ret; + ++ ret = devm_add_action_or_reset(&data->client->dev, ++ al3010_set_pwr_off, ++ data); + if (ret < 0) + return ret; + +@@ -191,12 +196,6 @@ static int al3010_probe(struct i2c_client *client, + return ret; + } + +- ret = devm_add_action_or_reset(&client->dev, +- al3010_set_pwr_off, +- data); +- if (ret < 0) +- return ret; +- + return devm_iio_device_register(&client->dev, indio_dev); + } + +-- +2.43.0 + diff --git a/queue-5.10/initramfs-avoid-filename-buffer-overrun.patch b/queue-5.10/initramfs-avoid-filename-buffer-overrun.patch new file mode 100644 index 00000000000..2f1098ce832 --- /dev/null +++ b/queue-5.10/initramfs-avoid-filename-buffer-overrun.patch @@ -0,0 +1,118 @@ +From f42555fbc153ee26234a432c2754c5070f322848 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Oct 2024 03:55:10 +0000 +Subject: initramfs: avoid filename buffer overrun + +From: David Disseldorp + +[ Upstream commit e017671f534dd3f568db9e47b0583e853d2da9b5 ] + +The initramfs filename field is defined in +Documentation/driver-api/early-userspace/buffer-format.rst as: + + 37 cpio_file := ALGN(4) + cpio_header + filename + "\0" + ALGN(4) + data +... + 55 ============= ================== ========================= + 56 Field name Field size Meaning + 57 ============= ================== ========================= +... + 70 c_namesize 8 bytes Length of filename, including final \0 + +When extracting an initramfs cpio archive, the kernel's do_name() path +handler assumes a zero-terminated path at @collected, passing it +directly to filp_open() / init_mkdir() / init_mknod(). + +If a specially crafted cpio entry carries a non-zero-terminated filename +and is followed by uninitialized memory, then a file may be created with +trailing characters that represent the uninitialized memory. The ability +to create an initramfs entry would imply already having full control of +the system, so the buffer overrun shouldn't be considered a security +vulnerability. + +Append the output of the following bash script to an existing initramfs +and observe any created /initramfs_test_fname_overrunAA* path. E.g. + ./reproducer.sh | gzip >> /myinitramfs + +It's easiest to observe non-zero uninitialized memory when the output is +gzipped, as it'll overflow the heap allocated @out_buf in __gunzip(), +rather than the initrd_start+initrd_size block. + +---- reproducer.sh ---- +nilchar="A" # change to "\0" to properly zero terminate / pad +magic="070701" +ino=1 +mode=$(( 0100777 )) +uid=0 +gid=0 +nlink=1 +mtime=1 +filesize=0 +devmajor=0 +devminor=1 +rdevmajor=0 +rdevminor=0 +csum=0 +fname="initramfs_test_fname_overrun" +namelen=$(( ${#fname} + 1 )) # plus one to account for terminator + +printf "%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%s" \ + $magic $ino $mode $uid $gid $nlink $mtime $filesize \ + $devmajor $devminor $rdevmajor $rdevminor $namelen $csum $fname + +termpadlen=$(( 1 + ((4 - ((110 + $namelen) & 3)) % 4) )) +printf "%.s${nilchar}" $(seq 1 $termpadlen) +---- reproducer.sh ---- + +Symlink filename fields handled in do_symlink() won't overrun past the +data segment, due to the explicit zero-termination of the symlink +target. + +Fix filename buffer overrun by aborting the initramfs FSM if any cpio +entry doesn't carry a zero-terminator at the expected (name_len - 1) +offset. + +Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") +Signed-off-by: David Disseldorp +Link: https://lore.kernel.org/r/20241030035509.20194-2-ddiss@suse.de +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + init/initramfs.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/init/initramfs.c b/init/initramfs.c +index ff09460727237..a56fc491c276d 100644 +--- a/init/initramfs.c ++++ b/init/initramfs.c +@@ -325,6 +325,15 @@ static int __init do_name(void) + { + state = SkipIt; + next_state = Reset; ++ ++ /* name_len > 0 && name_len <= PATH_MAX checked in do_header */ ++ if (collected[name_len - 1] != '\0') { ++ pr_err("initramfs name without nulterm: %.*s\n", ++ (int)name_len, collected); ++ error("malformed archive"); ++ return 1; ++ } ++ + if (strcmp(collected, "TRAILER!!!") == 0) { + free_hash(); + return 0; +@@ -390,6 +399,12 @@ static int __init do_copy(void) + + static int __init do_symlink(void) + { ++ if (collected[name_len - 1] != '\0') { ++ pr_err("initramfs symlink without nulterm: %.*s\n", ++ (int)name_len, collected); ++ error("malformed archive"); ++ return 1; ++ } + collected[N_ALIGN(name_len) + body_len] = '\0'; + clean_path(collected, 0); + init_symlink(collected + N_ALIGN(name_len), collected); +-- +2.43.0 + diff --git a/queue-5.10/ipmr-convert-proc-handlers-to-rcu_read_lock.patch b/queue-5.10/ipmr-convert-proc-handlers-to-rcu_read_lock.patch new file mode 100644 index 00000000000..b4392fb06dc --- /dev/null +++ b/queue-5.10/ipmr-convert-proc-handlers-to-rcu_read_lock.patch @@ -0,0 +1,86 @@ +From 094035ad03905cc8e6645464f14de1fe42ab71b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jun 2022 04:34:47 +0000 +Subject: ipmr: convert /proc handlers to rcu_read_lock() + +From: Eric Dumazet + +[ Upstream commit b96ef16d2f837870daaea51c38cd50458b95ad5c ] + +We can use standard rcu_read_lock(), to get rid +of last read_lock(&mrt_lock) call points. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Stable-dep-of: fc9c273d6daa ("ipmr: fix tables suspicious RCU usage") +Signed-off-by: Sasha Levin +--- + net/ipv4/ipmr.c | 8 ++++---- + net/ipv6/ip6mr.c | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index db184cb826b95..fe3d23611a297 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -2896,7 +2896,7 @@ static int ipmr_rtm_dumplink(struct sk_buff *skb, struct netlink_callback *cb) + */ + + static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) +- __acquires(mrt_lock) ++ __acquires(RCU) + { + struct mr_vif_iter *iter = seq->private; + struct net *net = seq_file_net(seq); +@@ -2908,14 +2908,14 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) + + iter->mrt = mrt; + +- read_lock(&mrt_lock); ++ rcu_read_lock(); + return mr_vif_seq_start(seq, pos); + } + + static void ipmr_vif_seq_stop(struct seq_file *seq, void *v) +- __releases(mrt_lock) ++ __releases(RCU) + { +- read_unlock(&mrt_lock); ++ rcu_read_unlock(); + } + + static int ipmr_vif_seq_show(struct seq_file *seq, void *v) +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index c758d0cc6146d..926baaf8661cc 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -405,7 +405,7 @@ static void ip6mr_free_table(struct mr_table *mrt) + */ + + static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) +- __acquires(mrt_lock) ++ __acquires(RCU) + { + struct mr_vif_iter *iter = seq->private; + struct net *net = seq_file_net(seq); +@@ -417,14 +417,14 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) + + iter->mrt = mrt; + +- read_lock(&mrt_lock); ++ rcu_read_lock(); + return mr_vif_seq_start(seq, pos); + } + + static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v) +- __releases(mrt_lock) ++ __releases(RCU) + { +- read_unlock(&mrt_lock); ++ rcu_read_unlock(); + } + + static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) +-- +2.43.0 + diff --git a/queue-5.10/ipmr-fix-tables-suspicious-rcu-usage.patch b/queue-5.10/ipmr-fix-tables-suspicious-rcu-usage.patch new file mode 100644 index 00000000000..0e11e4425bd --- /dev/null +++ b/queue-5.10/ipmr-fix-tables-suspicious-rcu-usage.patch @@ -0,0 +1,154 @@ +From 7b90915c575218edc0e3e450f306eefc585be7a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Nov 2024 16:40:58 +0100 +Subject: ipmr: fix tables suspicious RCU usage + +From: Paolo Abeni + +[ Upstream commit fc9c273d6daaa9866f349bbe8cae25c67764c456 ] + +Similar to the previous patch, plumb the RCU lock inside +the ipmr_get_table(), provided a lockless variant and apply +the latter in the few spots were the lock is already held. + +Fixes: 709b46e8d90b ("net: Add compat ioctl support for the ipv4 multicast ioctl SIOCGETSGCNT") +Fixes: f0ad0860d01e ("ipv4: ipmr: support multiple tables") +Reviewed-by: David Ahern +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/ipmr.c | 42 +++++++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index fe3d23611a297..6e4f91e76e2d3 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -131,7 +131,7 @@ static struct mr_table *ipmr_mr_table_iter(struct net *net, + return ret; + } + +-static struct mr_table *ipmr_get_table(struct net *net, u32 id) ++static struct mr_table *__ipmr_get_table(struct net *net, u32 id) + { + struct mr_table *mrt; + +@@ -142,6 +142,16 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id) + return NULL; + } + ++static struct mr_table *ipmr_get_table(struct net *net, u32 id) ++{ ++ struct mr_table *mrt; ++ ++ rcu_read_lock(); ++ mrt = __ipmr_get_table(net, id); ++ rcu_read_unlock(); ++ return mrt; ++} ++ + static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4, + struct mr_table **mrt) + { +@@ -183,7 +193,7 @@ static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp, + + arg->table = fib_rule_get_table(rule, arg); + +- mrt = ipmr_get_table(rule->fr_net, arg->table); ++ mrt = __ipmr_get_table(rule->fr_net, arg->table); + if (!mrt) + return -EAGAIN; + res->mrt = mrt; +@@ -315,6 +325,8 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id) + return net->ipv4.mrt; + } + ++#define __ipmr_get_table ipmr_get_table ++ + static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4, + struct mr_table **mrt) + { +@@ -404,7 +416,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) + if (id != RT_TABLE_DEFAULT && id >= 1000000000) + return ERR_PTR(-EINVAL); + +- mrt = ipmr_get_table(net, id); ++ mrt = __ipmr_get_table(net, id); + if (mrt) + return mrt; + +@@ -1366,7 +1378,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval, + goto out_unlock; + } + +- mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); ++ mrt = __ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); + if (!mrt) { + ret = -ENOENT; + goto out_unlock; +@@ -2242,11 +2254,13 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, + struct mr_table *mrt; + int err; + +- mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); +- if (!mrt) ++ rcu_read_lock(); ++ mrt = __ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) { ++ rcu_read_unlock(); + return -ENOENT; ++ } + +- rcu_read_lock(); + cache = ipmr_cache_find(mrt, saddr, daddr); + if (!cache && skb->dev) { + int vif = ipmr_find_vif(mrt, skb->dev); +@@ -2537,7 +2551,7 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, + grp = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0; + tableid = tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : 0; + +- mrt = ipmr_get_table(net, tableid ? tableid : RT_TABLE_DEFAULT); ++ mrt = __ipmr_get_table(net, tableid ? tableid : RT_TABLE_DEFAULT); + if (!mrt) { + err = -ENOENT; + goto errout_free; +@@ -2589,7 +2603,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) + if (filter.table_id) { + struct mr_table *mrt; + +- mrt = ipmr_get_table(sock_net(skb->sk), filter.table_id); ++ mrt = __ipmr_get_table(sock_net(skb->sk), filter.table_id); + if (!mrt) { + if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR) + return skb->len; +@@ -2697,7 +2711,7 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh, + break; + } + } +- mrt = ipmr_get_table(net, tblid); ++ mrt = __ipmr_get_table(net, tblid); + if (!mrt) { + ret = -ENOENT; + goto out; +@@ -2902,13 +2916,15 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) + struct net *net = seq_file_net(seq); + struct mr_table *mrt; + +- mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); +- if (!mrt) ++ rcu_read_lock(); ++ mrt = __ipmr_get_table(net, RT_TABLE_DEFAULT); ++ if (!mrt) { ++ rcu_read_unlock(); + return ERR_PTR(-ENOENT); ++ } + + iter->mrt = mrt; + +- rcu_read_lock(); + return mr_vif_seq_start(seq, pos); + } + +-- +2.43.0 + diff --git a/queue-5.10/kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch b/queue-5.10/kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch new file mode 100644 index 00000000000..99d99c02b56 --- /dev/null +++ b/queue-5.10/kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch @@ -0,0 +1,78 @@ +From df739d648270b8220f4fb5634a6c07cb3c53e072 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Nov 2024 16:43:09 +0100 +Subject: kcsan, seqlock: Fix incorrect assumption in read_seqbegin() + +From: Marco Elver + +[ Upstream commit 183ec5f26b2fc97a4a9871865bfe9b33c41fddb2 ] + +During testing of the preceding changes, I noticed that in some cases, +current->kcsan_ctx.in_flat_atomic remained true until task exit. This is +obviously wrong, because _all_ accesses for the given task will be +treated as atomic, resulting in false negatives i.e. missed data races. + +Debugging led to fs/dcache.c, where we can see this usage of seqlock: + + struct dentry *d_lookup(const struct dentry *parent, const struct qstr *name) + { + struct dentry *dentry; + unsigned seq; + + do { + seq = read_seqbegin(&rename_lock); + dentry = __d_lookup(parent, name); + if (dentry) + break; + } while (read_seqretry(&rename_lock, seq)); + [...] + +As can be seen, read_seqretry() is never called if dentry != NULL; +consequently, current->kcsan_ctx.in_flat_atomic will never be reset to +false by read_seqretry(). + +Give up on the wrong assumption of "assume closing read_seqretry()", and +rely on the already-present annotations in read_seqcount_begin/retry(). + +Fixes: 88ecd153be95 ("seqlock, kcsan: Add annotations for KCSAN") +Signed-off-by: Marco Elver +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20241104161910.780003-6-elver@google.com +Signed-off-by: Sasha Levin +--- + include/linux/seqlock.h | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h +index 0928a60b8f825..9bb3e8a40e941 100644 +--- a/include/linux/seqlock.h ++++ b/include/linux/seqlock.h +@@ -832,11 +832,7 @@ typedef struct { + */ + static inline unsigned read_seqbegin(const seqlock_t *sl) + { +- unsigned ret = read_seqcount_begin(&sl->seqcount); +- +- kcsan_atomic_next(0); /* non-raw usage, assume closing read_seqretry() */ +- kcsan_flat_atomic_begin(); +- return ret; ++ return read_seqcount_begin(&sl->seqcount); + } + + /** +@@ -852,12 +848,6 @@ static inline unsigned read_seqbegin(const seqlock_t *sl) + */ + static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) + { +- /* +- * Assume not nested: read_seqretry() may be called multiple times when +- * completing read critical section. +- */ +- kcsan_flat_atomic_end(); +- + return read_seqcount_retry(&sl->seqcount, start); + } + +-- +2.43.0 + diff --git a/queue-5.10/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch b/queue-5.10/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch new file mode 100644 index 00000000000..3a2e2c08bbb --- /dev/null +++ b/queue-5.10/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch @@ -0,0 +1,51 @@ +From ab9cf49bdd29a4eb8aa3195b0cfac5b52c1da4b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Aug 2024 16:32:51 +0100 +Subject: kselftest/arm64: mte: fix printf type warnings about longs + +From: Andre Przywara + +[ Upstream commit 96dddb7b9406259baace9a1831e8da155311be6f ] + +When checking MTE tags, we print some diagnostic messages when the tests +fail. Some variables uses there are "longs", however we only use "%x" +for the format specifier. + +Update the format specifiers to "%lx", to match the variable types they +are supposed to print. + +Fixes: f3b2a26ca78d ("kselftest/arm64: Verify mte tag inclusion via prctl") +Signed-off-by: Andre Przywara +Reviewed-by: Mark Brown +Link: https://lore.kernel.org/r/20240816153251.2833702-9-andre.przywara@arm.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/arm64/mte/check_tags_inclusion.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c +index deaef1f610768..74a3727f640de 100644 +--- a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c ++++ b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c +@@ -57,7 +57,7 @@ static int check_single_included_tags(int mem_type, int mode) + ptr = (char *)mte_insert_tags(ptr, BUFFER_SIZE); + /* Check tag value */ + if (MT_FETCH_TAG((uintptr_t)ptr) == tag) { +- ksft_print_msg("FAIL: wrong tag = 0x%x with include mask=0x%x\n", ++ ksft_print_msg("FAIL: wrong tag = 0x%lx with include mask=0x%x\n", + MT_FETCH_TAG((uintptr_t)ptr), + MT_INCLUDE_VALID_TAG(tag)); + result = KSFT_FAIL; +@@ -89,7 +89,7 @@ static int check_multiple_included_tags(int mem_type, int mode) + ptr = (char *)mte_insert_tags(ptr, BUFFER_SIZE); + /* Check tag value */ + if (MT_FETCH_TAG((uintptr_t)ptr) < tag) { +- ksft_print_msg("FAIL: wrong tag = 0x%x with include mask=0x%x\n", ++ ksft_print_msg("FAIL: wrong tag = 0x%lx with include mask=0x%lx\n", + MT_FETCH_TAG((uintptr_t)ptr), + MT_INCLUDE_VALID_TAGS(excl_mask)); + result = KSFT_FAIL; +-- +2.43.0 + diff --git a/queue-5.10/m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch b/queue-5.10/m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch new file mode 100644 index 00000000000..59bd550c802 --- /dev/null +++ b/queue-5.10/m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch @@ -0,0 +1,77 @@ +From fb5e1815b45c6e9e4bd39df57b6f24a18f94aeea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 22:43:15 +0100 +Subject: m68k: coldfire/device.c: only build FEC when HW macros are defined + +From: Antonio Quartulli + +[ Upstream commit 63a24cf8cc330e5a68ebd2e20ae200096974c475 ] + +When CONFIG_FEC is set (due to COMPILE_TEST) along with +CONFIG_M54xx, coldfire/device.c has compile errors due to +missing MCFEC_* and MCF_IRQ_FEC_* symbols. + +Make the whole FEC blocks dependent on having the HW macros +defined, rather than on CONFIG_FEC itself. + +This fix is very similar to commit e6e1e7b19fa1 ("m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined") + +Fixes: b7ce7f0d0efc ("m68knommu: merge common ColdFire FEC platform setup code") +To: Greg Ungerer +To: Geert Uytterhoeven +Cc: linux-m68k@lists.linux-m68k.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Antonio Quartulli +Signed-off-by: Greg Ungerer +Signed-off-by: Sasha Levin +--- + arch/m68k/coldfire/device.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c +index a055616942a1e..d73d90452b123 100644 +--- a/arch/m68k/coldfire/device.c ++++ b/arch/m68k/coldfire/device.c +@@ -93,7 +93,7 @@ static struct platform_device mcf_uart = { + .dev.platform_data = mcf_uart_platform_data, + }; + +-#if IS_ENABLED(CONFIG_FEC) ++#ifdef MCFFEC_BASE0 + + #ifdef CONFIG_M5441x + #define FEC_NAME "enet-fec" +@@ -145,6 +145,7 @@ static struct platform_device mcf_fec0 = { + .platform_data = FEC_PDATA, + } + }; ++#endif /* MCFFEC_BASE0 */ + + #ifdef MCFFEC_BASE1 + static struct resource mcf_fec1_resources[] = { +@@ -182,7 +183,6 @@ static struct platform_device mcf_fec1 = { + } + }; + #endif /* MCFFEC_BASE1 */ +-#endif /* CONFIG_FEC */ + + #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) + /* +@@ -583,12 +583,12 @@ static struct platform_device mcf_esdhc = { + + static struct platform_device *mcf_devices[] __initdata = { + &mcf_uart, +-#if IS_ENABLED(CONFIG_FEC) ++#ifdef MCFFEC_BASE0 + &mcf_fec0, ++#endif + #ifdef MCFFEC_BASE1 + &mcf_fec1, + #endif +-#endif + #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) + &mcf_qspi, + #endif +-- +2.43.0 + diff --git a/queue-5.10/m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch b/queue-5.10/m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch new file mode 100644 index 00000000000..eb27a9e4895 --- /dev/null +++ b/queue-5.10/m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch @@ -0,0 +1,37 @@ +From 3594986f942bb2c349300c9eb30995082e541a3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 09:24:35 +0200 +Subject: m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x + +From: Jean-Michel Hautbois + +[ Upstream commit f212140962c93cd5da43283a18e31681540fc23d ] + +Fix a typo in the CONFIG_M5441x preprocessor condition, where the GPIO +register offset was incorrectly set to 8 instead of 0. This prevented +proper GPIO configuration for m5441x targets. + +Fixes: bea8bcb12da0 ("m68knommu: Add support for the Coldfire m5441x.") +Signed-off-by: Jean-Michel Hautbois +Signed-off-by: Greg Ungerer +Signed-off-by: Sasha Levin +--- + arch/m68k/include/asm/mcfgpio.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h +index 27f32cc81da6b..02049568198c9 100644 +--- a/arch/m68k/include/asm/mcfgpio.h ++++ b/arch/m68k/include/asm/mcfgpio.h +@@ -144,7 +144,7 @@ static inline void gpio_free(unsigned gpio) + * read-modify-write as well as those controlled by the EPORT and GPIO modules. + */ + #define MCFGPIO_SCR_START 40 +-#elif defined(CONFIGM5441x) ++#elif defined(CONFIG_M5441x) + /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */ + #define MCFGPIO_SCR_START 0 + #else +-- +2.43.0 + diff --git a/queue-5.10/m68k-mvme147-fix-scsi-controller-irq-numbers.patch b/queue-5.10/m68k-mvme147-fix-scsi-controller-irq-numbers.patch new file mode 100644 index 00000000000..ed5e6f28262 --- /dev/null +++ b/queue-5.10/m68k-mvme147-fix-scsi-controller-irq-numbers.patch @@ -0,0 +1,46 @@ +From 0fe4206ac13b584c8c3ad8aa590daf93d1e15cc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2024 13:29:47 +1000 +Subject: m68k: mvme147: Fix SCSI controller IRQ numbers + +From: Daniel Palmer + +[ Upstream commit 47bc874427382018fa2e3e982480e156271eee70 ] + +Sometime long ago the m68k IRQ code was refactored and the interrupt +numbers for SCSI controller on this board ended up wrong, and it hasn't +worked since. + +The PCC adds 0x40 to the vector for its interrupts so they end up in +the user interrupt range. Hence, the kernel number should be the kernel +offset for user interrupt range + the PCC interrupt number. + +Fixes: 200a3d352cd5 ("[PATCH] m68k: convert VME irq code") +Signed-off-by: Daniel Palmer +Reviewed-by: Finn Thain +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/0e7636a21a0274eea35bfd5d874459d5078e97cc.1727926187.git.fthain@linux-m68k.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/m68k/include/asm/mvme147hw.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h +index e28eb1c0e0bfb..dbf88059e47a4 100644 +--- a/arch/m68k/include/asm/mvme147hw.h ++++ b/arch/m68k/include/asm/mvme147hw.h +@@ -93,8 +93,8 @@ struct pcc_regs { + #define M147_SCC_B_ADDR 0xfffe3000 + #define M147_SCC_PCLK 5000000 + +-#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45) +-#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46) ++#define MVME147_IRQ_SCSI_PORT (IRQ_USER + 5) ++#define MVME147_IRQ_SCSI_DMA (IRQ_USER + 6) + + /* SCC interrupts, for MVME147 */ + +-- +2.43.0 + diff --git a/queue-5.10/m68k-mvme147-reinstate-early-console.patch b/queue-5.10/m68k-mvme147-reinstate-early-console.patch new file mode 100644 index 00000000000..274fe96aef9 --- /dev/null +++ b/queue-5.10/m68k-mvme147-reinstate-early-console.patch @@ -0,0 +1,113 @@ +From 89667d369fb007a766172181a6f83047e3396498 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 10:51:24 +1100 +Subject: m68k: mvme147: Reinstate early console + +From: Daniel Palmer + +[ Upstream commit 077b33b9e2833ff25050d986178a2c4c4036cbac ] + +Commit a38eaa07a0ce ("m68k/mvme147: config.c - Remove unused +functions"), removed the console functionality for the mvme147 instead +of wiring it up to an early console. Put the console write function +back and wire it up like mvme16x does so it's possible to see Linux boot +on this fine hardware once more. + +Fixes: a38eaa07a0ce ("m68k/mvme147: config.c - Remove unused functions") +Signed-off-by: Daniel Palmer +Co-developed-by: Finn Thain +Signed-off-by: Finn Thain +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/a82e8f0068a8722996a0ccfe666abb5e0a5c120d.1730850684.git.fthain@linux-m68k.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/m68k/kernel/early_printk.c | 5 ++++- + arch/m68k/mvme147/config.c | 30 ++++++++++++++++++++++++++++++ + arch/m68k/mvme147/mvme147.h | 6 ++++++ + 3 files changed, 40 insertions(+), 1 deletion(-) + create mode 100644 arch/m68k/mvme147/mvme147.h + +diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c +index 3cc944df04f65..f11ef9f1f56fc 100644 +--- a/arch/m68k/kernel/early_printk.c ++++ b/arch/m68k/kernel/early_printk.c +@@ -13,6 +13,7 @@ + #include + + ++#include "../mvme147/mvme147.h" + #include "../mvme16x/mvme16x.h" + + asmlinkage void __init debug_cons_nputs(const char *s, unsigned n); +@@ -22,7 +23,9 @@ static void __ref debug_cons_write(struct console *c, + { + #if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \ + defined(CONFIG_COLDFIRE)) +- if (MACH_IS_MVME16x) ++ if (MACH_IS_MVME147) ++ mvme147_scc_write(c, s, n); ++ else if (MACH_IS_MVME16x) + mvme16x_cons_write(c, s, n); + else + debug_cons_nputs(s, n); +diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c +index aab7880e078df..4456591f5b7fe 100644 +--- a/arch/m68k/mvme147/config.c ++++ b/arch/m68k/mvme147/config.c +@@ -35,6 +35,7 @@ + #include + #include + ++#include "mvme147.h" + + static void mvme147_get_model(char *model); + extern void mvme147_sched_init(irq_handler_t handler); +@@ -188,3 +189,32 @@ int mvme147_hwclk(int op, struct rtc_time *t) + } + return 0; + } ++ ++static void scc_delay(void) ++{ ++ __asm__ __volatile__ ("nop; nop;"); ++} ++ ++static void scc_write(char ch) ++{ ++ do { ++ scc_delay(); ++ } while (!(in_8(M147_SCC_A_ADDR) & BIT(2))); ++ scc_delay(); ++ out_8(M147_SCC_A_ADDR, 8); ++ scc_delay(); ++ out_8(M147_SCC_A_ADDR, ch); ++} ++ ++void mvme147_scc_write(struct console *co, const char *str, unsigned int count) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ while (count--) { ++ if (*str == '\n') ++ scc_write('\r'); ++ scc_write(*str++); ++ } ++ local_irq_restore(flags); ++} +diff --git a/arch/m68k/mvme147/mvme147.h b/arch/m68k/mvme147/mvme147.h +new file mode 100644 +index 0000000000000..140bc98b0102a +--- /dev/null ++++ b/arch/m68k/mvme147/mvme147.h +@@ -0,0 +1,6 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++struct console; ++ ++/* config.c */ ++void mvme147_scc_write(struct console *co, const char *str, unsigned int count); +-- +2.43.0 + diff --git a/queue-5.10/m68k-mvme16x-add-and-use-mvme16x.h.patch b/queue-5.10/m68k-mvme16x-add-and-use-mvme16x.h.patch new file mode 100644 index 00000000000..237316da39e --- /dev/null +++ b/queue-5.10/m68k-mvme16x-add-and-use-mvme16x.h.patch @@ -0,0 +1,76 @@ +From 8b82bd8a40c01bdf2109acd4d3bb15bb183f322b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 16:08:25 +0200 +Subject: m68k: mvme16x: Add and use "mvme16x.h" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +[ Upstream commit dcec33c1fc4ab63983d93ffb0d82b68fc5775b88 ] + +When building with W=1: + + arch/m68k/mvme16x/config.c:208:6: warning: no previous prototype for ‘mvme16x_cons_write’ [-Wmissing-prototypes] + 208 | void mvme16x_cons_write(struct console *co, const char *str, unsigned count) + | ^~~~~~~~~~~~~~~~~~ + +Fix this by introducing a new header file "mvme16x.h" for holding the +prototypes of functions implemented in arch/m68k/mvme16x/. + +Signed-off-by: Geert Uytterhoeven +Acked-by: Arnd Bergmann +Link: https://lore.kernel.org/r/6200cc3b26fad215c4524748af04692e38c5ecd2.1694613528.git.geert@linux-m68k.org +Stable-dep-of: 077b33b9e283 ("m68k: mvme147: Reinstate early console") +Signed-off-by: Sasha Levin +--- + arch/m68k/kernel/early_printk.c | 4 ++-- + arch/m68k/mvme16x/config.c | 2 ++ + arch/m68k/mvme16x/mvme16x.h | 6 ++++++ + 3 files changed, 10 insertions(+), 2 deletions(-) + create mode 100644 arch/m68k/mvme16x/mvme16x.h + +diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c +index 7d3fe08a48eb0..3cc944df04f65 100644 +--- a/arch/m68k/kernel/early_printk.c ++++ b/arch/m68k/kernel/early_printk.c +@@ -12,8 +12,8 @@ + #include + #include + +-extern void mvme16x_cons_write(struct console *co, +- const char *str, unsigned count); ++ ++#include "../mvme16x/mvme16x.h" + + asmlinkage void __init debug_cons_nputs(const char *s, unsigned n); + +diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c +index d43d128b77471..e26ee07dec9e2 100644 +--- a/arch/m68k/mvme16x/config.c ++++ b/arch/m68k/mvme16x/config.c +@@ -38,6 +38,8 @@ + #include + #include + ++#include "mvme16x.h" ++ + extern t_bdid mvme_bdid; + + static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; +diff --git a/arch/m68k/mvme16x/mvme16x.h b/arch/m68k/mvme16x/mvme16x.h +new file mode 100644 +index 0000000000000..159c34b700394 +--- /dev/null ++++ b/arch/m68k/mvme16x/mvme16x.h +@@ -0,0 +1,6 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++struct console; ++ ++/* config.c */ ++void mvme16x_cons_write(struct console *co, const char *str, unsigned count); +-- +2.43.0 + diff --git a/queue-5.10/marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch b/queue-5.10/marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch new file mode 100644 index 00000000000..16791b26f92 --- /dev/null +++ b/queue-5.10/marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch @@ -0,0 +1,76 @@ +From 868cadd6911bb2cf91625e7d2ab5283583bcff9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Nov 2024 23:06:58 +0300 +Subject: marvell: pxa168_eth: fix call balance of pep->clk handling routines + +From: Vitalii Mordan + +[ Upstream commit b032ae57d4fe2b2445e3bc190db6fcaa8c102f68 ] + +If the clock pep->clk was not enabled in pxa168_eth_probe, +it should not be disabled in any path. + +Conversely, if it was enabled in pxa168_eth_probe, it must be disabled +in all error paths to ensure proper cleanup. + +Use the devm_clk_get_enabled helper function to ensure proper call balance +for pep->clk. + +Found by Linux Verification Center (linuxtesting.org) with Klever. + +Fixes: a49f37eed22b ("net: add Fast Ethernet driver for PXA168.") +Signed-off-by: Vitalii Mordan +Link: https://patch.msgid.link/20241121200658.2203871-1-mordan@ispras.ru +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/pxa168_eth.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c +index 3712e1786091f..cf867b8f43808 100644 +--- a/drivers/net/ethernet/marvell/pxa168_eth.c ++++ b/drivers/net/ethernet/marvell/pxa168_eth.c +@@ -1397,18 +1397,15 @@ static int pxa168_eth_probe(struct platform_device *pdev) + + printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n"); + +- clk = devm_clk_get(&pdev->dev, NULL); ++ clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) { +- dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n"); ++ dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n"); + return -ENODEV; + } +- clk_prepare_enable(clk); + + dev = alloc_etherdev(sizeof(struct pxa168_eth_private)); +- if (!dev) { +- err = -ENOMEM; +- goto err_clk; +- } ++ if (!dev) ++ return -ENOMEM; + + platform_set_drvdata(pdev, dev); + pep = netdev_priv(dev); +@@ -1523,8 +1520,6 @@ static int pxa168_eth_probe(struct platform_device *pdev) + mdiobus_free(pep->smi_bus); + err_netdev: + free_netdev(dev); +-err_clk: +- clk_disable_unprepare(clk); + return err; + } + +@@ -1541,7 +1536,6 @@ static int pxa168_eth_remove(struct platform_device *pdev) + if (dev->phydev) + phy_disconnect(dev->phydev); + +- clk_disable_unprepare(pep->clk); + mdiobus_unregister(pep->smi_bus); + mdiobus_free(pep->smi_bus); + cancel_work_sync(&pep->tx_timeout_task); +-- +2.43.0 + diff --git a/queue-5.10/media-atomisp-add-check-for-rgby_data-memory-allocat.patch b/queue-5.10/media-atomisp-add-check-for-rgby_data-memory-allocat.patch new file mode 100644 index 00000000000..932eba6d82e --- /dev/null +++ b/queue-5.10/media-atomisp-add-check-for-rgby_data-memory-allocat.patch @@ -0,0 +1,42 @@ +From 39632f4ffa97847fd215d7fcd682ebc851538e1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Nov 2024 22:50:51 +0800 +Subject: media: atomisp: Add check for rgby_data memory allocation failure + +From: Li Huafei + +[ Upstream commit ed61c59139509f76d3592683c90dc3fdc6e23cd6 ] + +In ia_css_3a_statistics_allocate(), there is no check on the allocation +result of the rgby_data memory. If rgby_data is not successfully +allocated, it may trigger the assert(host_stats->rgby_data) assertion in +ia_css_s3a_hmem_decode(). Adding a check to fix this potential issue. + +Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2") +Signed-off-by: Li Huafei +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20241104145051.3088231-1-lihuafei1@huawei.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/staging/media/atomisp/pci/sh_css_params.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c +index 90aa8fc999ef8..34d8ffb7742d3 100644 +--- a/drivers/staging/media/atomisp/pci/sh_css_params.c ++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c +@@ -4356,6 +4356,8 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) + goto err; + /* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */ + me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL); ++ if (!me->rgby_data) ++ goto err; + + IA_CSS_LEAVE("return=%p", me); + return me; +-- +2.43.0 + diff --git a/queue-5.10/media-atomisp-remove-ifdef-has_no_hmem.patch b/queue-5.10/media-atomisp-remove-ifdef-has_no_hmem.patch new file mode 100644 index 00000000000..28186682dd6 --- /dev/null +++ b/queue-5.10/media-atomisp-remove-ifdef-has_no_hmem.patch @@ -0,0 +1,150 @@ +From a534512afc9162bfb9911bfea96df9d749347a35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Nov 2021 07:19:06 +0000 +Subject: media: atomisp: remove #ifdef HAS_NO_HMEM + +From: Mauro Carvalho Chehab + +[ Upstream commit 63705da3dfc8922a2dbfc3c805a5faadb4416954 ] + +This is not defined anywhere, so, solve the ifdefs, getting +rid of them. + +Signed-off-by: Mauro Carvalho Chehab +Stable-dep-of: ed61c5913950 ("media: atomisp: Add check for rgby_data memory allocation failure") +Signed-off-by: Sasha Levin +--- + .../atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c | 2 -- + .../raw_aa_binning_1.0/ia_css_raa.host.c | 2 -- + .../pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c | 5 ----- + .../media/atomisp/pci/runtime/binary/src/binary.c | 4 ---- + drivers/staging/media/atomisp/pci/sh_css_params.c | 10 ---------- + 5 files changed, 23 deletions(-) + +diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c +index 82aa69b74677c..2091f001502d4 100644 +--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c ++++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c +@@ -13,7 +13,6 @@ + * more details. + */ + +-#if !defined(HAS_NO_HMEM) + + #include "ia_css_types.h" + #include "sh_css_internal.h" +@@ -63,4 +62,3 @@ ia_css_bh_encode( + uDIGIT_FITTING(from->ae_y_coef_b, 16, SH_CSS_AE_YCOEF_SHIFT); + } + +-#endif +diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c +index 29c707ecf9f3b..9b756daddee06 100644 +--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c ++++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c +@@ -13,7 +13,6 @@ + * more details. + */ + +-#if !defined(HAS_NO_HMEM) + + #include "ia_css_types.h" + #include "sh_css_internal.h" +@@ -32,4 +31,3 @@ ia_css_raa_encode( + (void)from; + } + +-#endif +diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c +index ba52c80df4a58..bd7b89d9475bf 100644 +--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c ++++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c +@@ -227,10 +227,6 @@ ia_css_s3a_hmem_decode( + struct ia_css_3a_statistics *host_stats, + const struct ia_css_bh_table *hmem_buf) + { +-#if defined(HAS_NO_HMEM) +- (void)host_stats; +- (void)hmem_buf; +-#else + struct ia_css_3a_rgby_output *out_ptr; + int i; + +@@ -291,7 +287,6 @@ ia_css_s3a_hmem_decode( + out_ptr[0].g -= diff; + out_ptr[0].b -= diff; + out_ptr[0].y -= diff; +-#endif + } + + void +diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c +index 060d387495704..002bd8cf28634 100644 +--- a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c ++++ b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c +@@ -805,11 +805,7 @@ ia_css_binary_3a_grid_info(const struct ia_css_binary *binary, + s3a_info->deci_factor_log2 = binary->deci_factor_log2; + s3a_info->elem_bit_depth = SH_CSS_BAYER_BITS; + s3a_info->use_dmem = binary->info->sp.s3a.s3atbl_use_dmem; +-#if defined(HAS_NO_HMEM) +- s3a_info->has_histogram = 1; +-#else + s3a_info->has_histogram = 0; +-#endif + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } +diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c +index 8d6514c45eeb6..90aa8fc999ef8 100644 +--- a/drivers/staging/media/atomisp/pci/sh_css_params.c ++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c +@@ -16,12 +16,10 @@ + #include "gdc_device.h" /* gdc_lut_store(), ... */ + #include "isp.h" /* ISP_VEC_ELEMBITS */ + #include "vamem.h" +-#if !defined(HAS_NO_HMEM) + #ifndef __INLINE_HMEM__ + #define __INLINE_HMEM__ + #endif + #include "hmem.h" +-#endif /* !defined(HAS_NO_HMEM) */ + #define IA_CSS_INCLUDE_PARAMETERS + #define IA_CSS_INCLUDE_ACC_PARAMETERS + +@@ -1513,10 +1511,8 @@ ia_css_translate_3a_statistics( + ia_css_s3a_vmem_decode(host_stats, isp_stats->vmem_stats_hi, + isp_stats->vmem_stats_lo); + } +-#if !defined(HAS_NO_HMEM) + IA_CSS_LOG("3A: HMEM"); + ia_css_s3a_hmem_decode(host_stats, isp_stats->hmem_stats); +-#endif + + IA_CSS_LEAVE("void"); + } +@@ -2255,9 +2251,7 @@ ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) + me->vmem_size = ISP_S3ATBL_HI_LO_STRIDE_BYTES * + grid->aligned_height; + } +-#if !defined(HAS_NO_HMEM) + me->hmem_size = sizeof_hmem(HMEM0_ID); +-#endif + + /* All subsections need to be aligned to the system bus width */ + me->dmem_size = CEIL_MUL(me->dmem_size, HIVE_ISP_DDR_WORD_BYTES); +@@ -4360,12 +4354,8 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) + me->data = kvmalloc(grid_size * sizeof(*me->data), GFP_KERNEL); + if (!me->data) + goto err; +-#if !defined(HAS_NO_HMEM) + /* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */ + me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL); +-#else +- me->rgby_data = NULL; +-#endif + + IA_CSS_LEAVE("return=%p", me); + return me; +-- +2.43.0 + diff --git a/queue-5.10/mfd-da9052-spi-change-read-mask-to-write-mask.patch b/queue-5.10/mfd-da9052-spi-change-read-mask-to-write-mask.patch new file mode 100644 index 00000000000..b5cac8bdeb7 --- /dev/null +++ b/queue-5.10/mfd-da9052-spi-change-read-mask-to-write-mask.patch @@ -0,0 +1,38 @@ +From 49fad7370f136069cb8497455bdf95747649598e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 12:19:53 +0200 +Subject: mfd: da9052-spi: Change read-mask to write-mask + +From: Marcus Folkesson + +[ Upstream commit 2e3378f6c79a1b3f7855ded1ef306ea4406352ed ] + +Driver has mixed up the R/W bit. +The LSB bit is set on write rather than read. +Change it to avoid nasty things to happen. + +Fixes: e9e9d3973594 ("mfd: da9052: Avoid setting read_flag_mask for da9052-i2c driver") +Signed-off-by: Marcus Folkesson +Link: https://lore.kernel.org/r/20240925-da9052-v2-1-f243e4505b07@gmail.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9052-spi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c +index 5faf3766a5e20..06c500bf4d57e 100644 +--- a/drivers/mfd/da9052-spi.c ++++ b/drivers/mfd/da9052-spi.c +@@ -37,7 +37,7 @@ static int da9052_spi_probe(struct spi_device *spi) + spi_set_drvdata(spi, da9052); + + config = da9052_regmap_config; +- config.read_flag_mask = 1; ++ config.write_flag_mask = 1; + config.reg_bits = 7; + config.pad_bits = 1; + config.val_bits = 8; +-- +2.43.0 + diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch new file mode 100644 index 00000000000..12bb0bfd180 --- /dev/null +++ b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch @@ -0,0 +1,189 @@ +From 4546cf9eca4055c0ffdb1136e9461a7344536058 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Jun 2022 01:17:40 +0300 +Subject: mfd: intel_soc_pmic_bxtwc: Use dev_err_probe() + +From: Andy Shevchenko + +[ Upstream commit d30e2c30a43de950cfd3690f24342a39034221c4 ] + +Simplify the mux error path a bit by using dev_err_probe(). + +Signed-off-by: Andy Shevchenko +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20220628221747.33956-4-andriy.shevchenko@linux.intel.com +Stable-dep-of: 686fb77712a4 ("mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device") +Signed-off-by: Sasha Levin +--- + drivers/mfd/intel_soc_pmic_bxtwc.c | 86 +++++++++--------------------- + 1 file changed, 26 insertions(+), 60 deletions(-) + +diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c +index eba89780dbe75..3b41cc2d1ec01 100644 +--- a/drivers/mfd/intel_soc_pmic_bxtwc.c ++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c +@@ -410,12 +410,9 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, + int irq; + + irq = regmap_irq_get_virq(pdata, pirq); +- if (irq < 0) { +- dev_err(pmic->dev, +- "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n", +- pirq, chip->name, irq); +- return irq; +- } ++ if (irq < 0) ++ return dev_err_probe(pmic->dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", ++ pirq, chip->name); + + return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags, + 0, chip, data); +@@ -423,6 +420,7 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, + + static int bxtwc_probe(struct platform_device *pdev) + { ++ struct device *dev = &pdev->dev; + int ret; + acpi_handle handle; + acpi_status status; +@@ -431,15 +429,10 @@ static int bxtwc_probe(struct platform_device *pdev) + + handle = ACPI_HANDLE(&pdev->dev); + status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv); +- if (ACPI_FAILURE(status)) { +- dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n"); +- return -ENODEV; +- } +- if (hrv != BROXTON_PMIC_WC_HRV) { +- dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n", +- hrv); +- return -ENODEV; +- } ++ if (ACPI_FAILURE(status)) ++ return dev_err_probe(dev, -ENODEV, "Failed to get PMIC hardware revision\n"); ++ if (hrv != BROXTON_PMIC_WC_HRV) ++ return dev_err_probe(dev, -ENODEV, "Invalid PMIC hardware revision: %llu\n", hrv); + + pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) +@@ -459,40 +452,31 @@ static int bxtwc_probe(struct platform_device *pdev) + + pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic, + &bxtwc_regmap_config); +- if (IS_ERR(pmic->regmap)) { +- ret = PTR_ERR(pmic->regmap); +- dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret); +- return ret; +- } ++ if (IS_ERR(pmic->regmap)) ++ return dev_err_probe(dev, PTR_ERR(pmic->regmap), "Failed to initialise regmap\n"); + + ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq, + IRQF_ONESHOT | IRQF_SHARED, + 0, &bxtwc_regmap_irq_chip, + &pmic->irq_chip_data); +- if (ret) { +- dev_err(&pdev->dev, "Failed to add IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); + + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_PWRBTN_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_pwrbtn, + &pmic->irq_chip_data_pwrbtn); +- if (ret) { +- dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n"); + + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_TMU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_tmu, + &pmic->irq_chip_data_tmu); +- if (ret) { +- dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n"); + + /* Add chained IRQ handler for BCU IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +@@ -500,12 +484,8 @@ static int bxtwc_probe(struct platform_device *pdev) + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_bcu, + &pmic->irq_chip_data_bcu); +- +- +- if (ret) { +- dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n"); + + /* Add chained IRQ handler for ADC IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +@@ -513,12 +493,8 @@ static int bxtwc_probe(struct platform_device *pdev) + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_adc, + &pmic->irq_chip_data_adc); +- +- +- if (ret) { +- dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n"); + + /* Add chained IRQ handler for CHGR IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +@@ -526,12 +502,8 @@ static int bxtwc_probe(struct platform_device *pdev) + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_chgr, + &pmic->irq_chip_data_chgr); +- +- +- if (ret) { +- dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n"); + + /* Add chained IRQ handler for CRIT IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +@@ -539,19 +511,13 @@ static int bxtwc_probe(struct platform_device *pdev) + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_crit, + &pmic->irq_chip_data_crit); +- +- +- if (ret) { +- dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add CRIT IRQ chip\n"); + + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, + ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL); +- if (ret) { +- dev_err(&pdev->dev, "Failed to add devices\n"); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add devices\n"); + + ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group); + if (ret) { +-- +2.43.0 + diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch new file mode 100644 index 00000000000..3ddcf40ebbd --- /dev/null +++ b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch @@ -0,0 +1,118 @@ +From 05cb51dbb482c87c2c8d086e41eabe7a11e816c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 5 Oct 2024 22:27:06 +0300 +Subject: mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices + +From: Andy Shevchenko + +[ Upstream commit 0350d783ab888cb1cb48ced36cc28b372723f1a4 ] + +While design wise the idea of converting the driver to use +the hierarchy of the IRQ chips is correct, the implementation +has (inherited) flaws. This was unveiled when platform_get_irq() +had started WARN() on IRQ 0 that is supposed to be a Linux +IRQ number (also known as vIRQ). + +Rework the driver to respect IRQ domain when creating each MFD +device separately, as the domain is not the same for all of them. + +Fixes: 57129044f504 ("mfd: intel_soc_pmic_bxtwc: Use chained IRQs for second level IRQ chips") +Tested-by: Zhang Ning +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20241005193029.1929139-4-andriy.shevchenko@linux.intel.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/intel_soc_pmic_bxtwc.c | 54 +++++++++++++++++------------- + 1 file changed, 30 insertions(+), 24 deletions(-) + +diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c +index 8b55f839a946b..6d708d6f7281a 100644 +--- a/drivers/mfd/intel_soc_pmic_bxtwc.c ++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c +@@ -230,21 +230,11 @@ static struct resource tmu_resources[] = { + }; + + static struct mfd_cell bxt_wc_dev[] = { +- { +- .name = "bxt_wcove_gpadc", +- .num_resources = ARRAY_SIZE(adc_resources), +- .resources = adc_resources, +- }, + { + .name = "bxt_wcove_thermal", + .num_resources = ARRAY_SIZE(thermal_resources), + .resources = thermal_resources, + }, +- { +- .name = "bxt_wcove_bcu", +- .num_resources = ARRAY_SIZE(bcu_resources), +- .resources = bcu_resources, +- }, + { + .name = "bxt_wcove_gpio", + .num_resources = ARRAY_SIZE(gpio_resources), +@@ -263,6 +253,22 @@ static const struct mfd_cell bxt_wc_tmu_dev[] = { + }, + }; + ++static const struct mfd_cell bxt_wc_bcu_dev[] = { ++ { ++ .name = "bxt_wcove_bcu", ++ .num_resources = ARRAY_SIZE(bcu_resources), ++ .resources = bcu_resources, ++ }, ++}; ++ ++static const struct mfd_cell bxt_wc_adc_dev[] = { ++ { ++ .name = "bxt_wcove_gpadc", ++ .num_resources = ARRAY_SIZE(adc_resources), ++ .resources = adc_resources, ++ }, ++}; ++ + static struct mfd_cell bxt_wc_chgr_dev[] = { + { + .name = "bxt_wcove_usbc", +@@ -504,23 +510,23 @@ static int bxtwc_probe(struct platform_device *pdev) + if (ret) + return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n"); + +- /* Add chained IRQ handler for BCU IRQs */ +- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +- BXTWC_BCU_LVL1_IRQ, +- IRQF_ONESHOT, +- &bxtwc_regmap_irq_chip_bcu, +- &pmic->irq_chip_data_bcu); ++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev), ++ pmic->irq_chip_data, ++ BXTWC_BCU_LVL1_IRQ, ++ IRQF_ONESHOT, ++ &bxtwc_regmap_irq_chip_bcu, ++ &pmic->irq_chip_data_bcu); + if (ret) +- return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n"); ++ return ret; + +- /* Add chained IRQ handler for ADC IRQs */ +- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +- BXTWC_ADC_LVL1_IRQ, +- IRQF_ONESHOT, +- &bxtwc_regmap_irq_chip_adc, +- &pmic->irq_chip_data_adc); ++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev), ++ pmic->irq_chip_data, ++ BXTWC_ADC_LVL1_IRQ, ++ IRQF_ONESHOT, ++ &bxtwc_regmap_irq_chip_adc, ++ &pmic->irq_chip_data_adc); + if (ret) +- return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n"); ++ return ret; + + ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev), + pmic->irq_chip_data, +-- +2.43.0 + diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch new file mode 100644 index 00000000000..8726edaa2ec --- /dev/null +++ b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch @@ -0,0 +1,147 @@ +From 08f39765067b5286fd01ac15da91837242ff723e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 5 Oct 2024 22:27:05 +0300 +Subject: mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device + +From: Andy Shevchenko + +[ Upstream commit 9b79d59e6b2b515eb9a22bc469ef7b8f0904fc73 ] + +While design wise the idea of converting the driver to use +the hierarchy of the IRQ chips is correct, the implementation +has (inherited) flaws. This was unveiled when platform_get_irq() +had started WARN() on IRQ 0 that is supposed to be a Linux +IRQ number (also known as vIRQ). + +Rework the driver to respect IRQ domain when creating each MFD +device separately, as the domain is not the same for all of them. + +Fixes: 957ae5098185 ("platform/x86: Add Whiskey Cove PMIC TMU support") +Fixes: 57129044f504 ("mfd: intel_soc_pmic_bxtwc: Use chained IRQs for second level IRQ chips") +Reported-by: Zhang Ning +Closes: https://lore.kernel.org/r/TY2PR01MB3322FEDCDC048B7D3794F922CDBA2@TY2PR01MB3322.jpnprd01.prod.outlook.com +Tested-by: Zhang Ning +Acked-by: Hans de Goede +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20241005193029.1929139-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/intel_soc_pmic_bxtwc.c | 31 ++++++++++++++------------ + drivers/platform/x86/intel_bxtwc_tmu.c | 22 +++++------------- + 2 files changed, 23 insertions(+), 30 deletions(-) + +diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c +index 82c71b475a7e0..8b55f839a946b 100644 +--- a/drivers/mfd/intel_soc_pmic_bxtwc.c ++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c +@@ -245,12 +245,6 @@ static struct mfd_cell bxt_wc_dev[] = { + .num_resources = ARRAY_SIZE(bcu_resources), + .resources = bcu_resources, + }, +- { +- .name = "bxt_wcove_tmu", +- .num_resources = ARRAY_SIZE(tmu_resources), +- .resources = tmu_resources, +- }, +- + { + .name = "bxt_wcove_gpio", + .num_resources = ARRAY_SIZE(gpio_resources), +@@ -261,6 +255,14 @@ static struct mfd_cell bxt_wc_dev[] = { + }, + }; + ++static const struct mfd_cell bxt_wc_tmu_dev[] = { ++ { ++ .name = "bxt_wcove_tmu", ++ .num_resources = ARRAY_SIZE(tmu_resources), ++ .resources = tmu_resources, ++ }, ++}; ++ + static struct mfd_cell bxt_wc_chgr_dev[] = { + { + .name = "bxt_wcove_usbc", +@@ -485,6 +487,15 @@ static int bxtwc_probe(struct platform_device *pdev) + if (ret) + return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); + ++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev), ++ pmic->irq_chip_data, ++ BXTWC_TMU_LVL1_IRQ, ++ IRQF_ONESHOT, ++ &bxtwc_regmap_irq_chip_tmu, ++ &pmic->irq_chip_data_tmu); ++ if (ret) ++ return ret; ++ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_PWRBTN_LVL1_IRQ, + IRQF_ONESHOT, +@@ -493,14 +504,6 @@ static int bxtwc_probe(struct platform_device *pdev) + if (ret) + return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n"); + +- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +- BXTWC_TMU_LVL1_IRQ, +- IRQF_ONESHOT, +- &bxtwc_regmap_irq_chip_tmu, +- &pmic->irq_chip_data_tmu); +- if (ret) +- return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n"); +- + /* Add chained IRQ handler for BCU IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_BCU_LVL1_IRQ, +diff --git a/drivers/platform/x86/intel_bxtwc_tmu.c b/drivers/platform/x86/intel_bxtwc_tmu.c +index 7ccf583649e6b..3c9778366d930 100644 +--- a/drivers/platform/x86/intel_bxtwc_tmu.c ++++ b/drivers/platform/x86/intel_bxtwc_tmu.c +@@ -48,9 +48,8 @@ static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data) + static int bxt_wcove_tmu_probe(struct platform_device *pdev) + { + struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); +- struct regmap_irq_chip_data *regmap_irq_chip; + struct wcove_tmu *wctmu; +- int ret, virq, irq; ++ int ret; + + wctmu = devm_kzalloc(&pdev->dev, sizeof(*wctmu), GFP_KERNEL); + if (!wctmu) +@@ -59,27 +58,18 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev) + wctmu->dev = &pdev->dev; + wctmu->regmap = pmic->regmap; + +- irq = platform_get_irq(pdev, 0); +- if (irq < 0) +- return irq; ++ wctmu->irq = platform_get_irq(pdev, 0); ++ if (wctmu->irq < 0) ++ return wctmu->irq; + +- regmap_irq_chip = pmic->irq_chip_data_tmu; +- virq = regmap_irq_get_virq(regmap_irq_chip, irq); +- if (virq < 0) { +- dev_err(&pdev->dev, +- "failed to get virtual interrupt=%d\n", irq); +- return virq; +- } +- +- ret = devm_request_threaded_irq(&pdev->dev, virq, ++ ret = devm_request_threaded_irq(&pdev->dev, wctmu->irq, + NULL, bxt_wcove_tmu_irq_handler, + IRQF_ONESHOT, "bxt_wcove_tmu", wctmu); + if (ret) { + dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n", +- ret, virq); ++ ret, wctmu->irq); + return ret; + } +- wctmu->irq = virq; + + /* Unmask TMU second level Wake & System alarm */ + regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG, +-- +2.43.0 + diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch new file mode 100644 index 00000000000..54d7a67d20e --- /dev/null +++ b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch @@ -0,0 +1,142 @@ +From 6148a7da81d658b0f698dc91d5f792a196509df6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 5 Oct 2024 22:27:04 +0300 +Subject: mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device + +From: Andy Shevchenko + +[ Upstream commit 686fb77712a4bc94b76a0c5ae74c60118b7a0d79 ] + +While design wise the idea of converting the driver to use +the hierarchy of the IRQ chips is correct, the implementation +has (inherited) flaws. This was unveiled when platform_get_irq() +had started WARN() on IRQ 0 that is supposed to be a Linux +IRQ number (also known as vIRQ). + +Rework the driver to respect IRQ domain when creating each MFD +device separately, as the domain is not the same for all of them. + +Fixes: 9c6235c86332 ("mfd: intel_soc_pmic_bxtwc: Add bxt_wcove_usbc device") +Fixes: d2061f9cc32d ("usb: typec: add driver for Intel Whiskey Cove PMIC USB Type-C PHY") +Fixes: 57129044f504 ("mfd: intel_soc_pmic_bxtwc: Use chained IRQs for second level IRQ chips") +Reported-by: Zhang Ning +Closes: https://lore.kernel.org/r/TY2PR01MB3322FEDCDC048B7D3794F922CDBA2@TY2PR01MB3322.jpnprd01.prod.outlook.com +Tested-by: Zhang Ning +Signed-off-by: Andy Shevchenko +Acked-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20241005193029.1929139-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/intel_soc_pmic_bxtwc.c | 57 +++++++++++++++++++++--------- + drivers/usb/typec/tcpm/wcove.c | 4 --- + 2 files changed, 40 insertions(+), 21 deletions(-) + +diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c +index 3b41cc2d1ec01..82c71b475a7e0 100644 +--- a/drivers/mfd/intel_soc_pmic_bxtwc.c ++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c +@@ -240,16 +240,6 @@ static struct mfd_cell bxt_wc_dev[] = { + .num_resources = ARRAY_SIZE(thermal_resources), + .resources = thermal_resources, + }, +- { +- .name = "bxt_wcove_usbc", +- .num_resources = ARRAY_SIZE(usbc_resources), +- .resources = usbc_resources, +- }, +- { +- .name = "bxt_wcove_ext_charger", +- .num_resources = ARRAY_SIZE(charger_resources), +- .resources = charger_resources, +- }, + { + .name = "bxt_wcove_bcu", + .num_resources = ARRAY_SIZE(bcu_resources), +@@ -271,6 +261,19 @@ static struct mfd_cell bxt_wc_dev[] = { + }, + }; + ++static struct mfd_cell bxt_wc_chgr_dev[] = { ++ { ++ .name = "bxt_wcove_usbc", ++ .num_resources = ARRAY_SIZE(usbc_resources), ++ .resources = usbc_resources, ++ }, ++ { ++ .name = "bxt_wcove_ext_charger", ++ .num_resources = ARRAY_SIZE(charger_resources), ++ .resources = charger_resources, ++ }, ++}; ++ + static int regmap_ipc_byte_reg_read(void *context, unsigned int reg, + unsigned int *val) + { +@@ -418,6 +421,26 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, + 0, chip, data); + } + ++static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic, ++ const struct mfd_cell *cells, int n_devs, ++ struct regmap_irq_chip_data *pdata, ++ int pirq, int irq_flags, ++ const struct regmap_irq_chip *chip, ++ struct regmap_irq_chip_data **data) ++{ ++ struct device *dev = pmic->dev; ++ struct irq_domain *domain; ++ int ret; ++ ++ ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data); ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name); ++ ++ domain = regmap_irq_get_domain(*data); ++ ++ return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain); ++} ++ + static int bxtwc_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -496,14 +519,14 @@ static int bxtwc_probe(struct platform_device *pdev) + if (ret) + return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n"); + +- /* Add chained IRQ handler for CHGR IRQs */ +- ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +- BXTWC_CHGR_LVL1_IRQ, +- IRQF_ONESHOT, +- &bxtwc_regmap_irq_chip_chgr, +- &pmic->irq_chip_data_chgr); ++ ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev), ++ pmic->irq_chip_data, ++ BXTWC_CHGR_LVL1_IRQ, ++ IRQF_ONESHOT, ++ &bxtwc_regmap_irq_chip_chgr, ++ &pmic->irq_chip_data_chgr); + if (ret) +- return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n"); ++ return ret; + + /* Add chained IRQ handler for CRIT IRQs */ + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, +diff --git a/drivers/usb/typec/tcpm/wcove.c b/drivers/usb/typec/tcpm/wcove.c +index 7e9c279bf49df..22fe8d60fe368 100644 +--- a/drivers/usb/typec/tcpm/wcove.c ++++ b/drivers/usb/typec/tcpm/wcove.c +@@ -620,10 +620,6 @@ static int wcove_typec_probe(struct platform_device *pdev) + if (irq < 0) + return irq; + +- irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq); +- if (irq < 0) +- return irq; +- + ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid); + if (ret) + return ret; +-- +2.43.0 + diff --git a/queue-5.10/mfd-rt5033-fix-missing-regmap_del_irq_chip.patch b/queue-5.10/mfd-rt5033-fix-missing-regmap_del_irq_chip.patch new file mode 100644 index 00000000000..b5feb3d6833 --- /dev/null +++ b/queue-5.10/mfd-rt5033-fix-missing-regmap_del_irq_chip.patch @@ -0,0 +1,39 @@ +From bdfac5d59fa3fb682be07fe6e801791d3d9e297c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Oct 2024 23:41:06 +0800 +Subject: mfd: rt5033: Fix missing regmap_del_irq_chip() + +From: Zhang Changzhong + +[ Upstream commit d256d612f47529ed0b332298e2d5ea981a4dd5b8 ] + +Fix missing call to regmap_del_irq_chip() in error handling path by +using devm_regmap_add_irq_chip(). + +Fixes: 0b271258544b ("mfd: rt5033: Add Richtek RT5033 driver core.") +Signed-off-by: Zhang Changzhong +Link: https://lore.kernel.org/r/1730302867-8391-1-git-send-email-zhangchangzhong@huawei.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/rt5033.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c +index 302115dabff4b..9afb8d2b35476 100644 +--- a/drivers/mfd/rt5033.c ++++ b/drivers/mfd/rt5033.c +@@ -82,8 +82,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c, + } + dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id); + +- ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq, +- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ++ ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap, ++ rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + 0, &rt5033_irq_chip, &rt5033->irq_data); + if (ret) { + dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", +-- +2.43.0 + diff --git a/queue-5.10/mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch b/queue-5.10/mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch new file mode 100644 index 00000000000..b5d049ffc0e --- /dev/null +++ b/queue-5.10/mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch @@ -0,0 +1,49 @@ +From 6c8d3ebdfc809b4dcbc3162dd6049912075bb2c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2024 11:15:30 +0800 +Subject: mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race + +From: Jinjie Ruan + +[ Upstream commit 2174f9a8c9db50f74df769edd5a4ab822c73b6d2 ] + +As the comment said, disable_irq() after request_irq() still has a +time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN +flag will disable IRQ auto-enable when request IRQ. + +Fixes: 72cd799544f2 ("[PATCH] I2C: add i2c driver for TPS6501x") +Signed-off-by: Jinjie Ruan +Link: https://lore.kernel.org/r/20240912031530.2211654-1-ruanjinjie@huawei.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/tps65010.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c +index 7e7dbee58ca90..744a68f3c359c 100644 +--- a/drivers/mfd/tps65010.c ++++ b/drivers/mfd/tps65010.c +@@ -549,17 +549,13 @@ static int tps65010_probe(struct i2c_client *client, + */ + if (client->irq > 0) { + status = request_irq(client->irq, tps65010_irq, +- IRQF_TRIGGER_FALLING, DRIVER_NAME, tps); ++ IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN, ++ DRIVER_NAME, tps); + if (status < 0) { + dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", + client->irq, status); + return status; + } +- /* annoying race here, ideally we'd have an option +- * to claim the irq now and enable it later. +- * FIXME genirq IRQF_NOAUTOEN now solves that ... +- */ +- disable_irq(client->irq); + set_bit(FLAG_IRQ_ENABLE, &tps->flags); + } else + dev_warn(&client->dev, "IRQ not configured!\n"); +-- +2.43.0 + diff --git a/queue-5.10/mips-asm-fix-warning-when-disabling-mips_fp_support.patch b/queue-5.10/mips-asm-fix-warning-when-disabling-mips_fp_support.patch new file mode 100644 index 00000000000..217a2f20626 --- /dev/null +++ b/queue-5.10/mips-asm-fix-warning-when-disabling-mips_fp_support.patch @@ -0,0 +1,49 @@ +From a29afac8012ee2908ad60c5c2befe5f568363a98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Oct 2024 12:12:14 +0200 +Subject: mips: asm: fix warning when disabling MIPS_FP_SUPPORT + +From: Jonas Gorski + +[ Upstream commit da09935975c8f8c90d6f57be2422dee5557206cd ] + +When MIPS_FP_SUPPORT is disabled, __sanitize_fcr31() is defined as +nothing, which triggers a gcc warning: + + In file included from kernel/sched/core.c:79: + kernel/sched/core.c: In function 'context_switch': + ./arch/mips/include/asm/switch_to.h:114:39: warning: suggest braces around empty body in an 'if' statement [-Wempty-body] + 114 | __sanitize_fcr31(next); \ + | ^ + kernel/sched/core.c:5316:9: note: in expansion of macro 'switch_to' + 5316 | switch_to(prev, next, prev); + | ^~~~~~~~~ + +Fix this by providing an empty body for __sanitize_fcr31() like one is +defined for __mips_mt_fpaff_switch_to(). + +Fixes: 36a498035bd2 ("MIPS: Avoid FCSR sanitization when CONFIG_MIPS_FP_SUPPORT=n") +Signed-off-by: Jonas Gorski +Reviewed-by: Maciej W. Rozycki +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/include/asm/switch_to.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h +index a4374b4cb88fd..d6ccd53440213 100644 +--- a/arch/mips/include/asm/switch_to.h ++++ b/arch/mips/include/asm/switch_to.h +@@ -97,7 +97,7 @@ do { \ + } \ + } while (0) + #else +-# define __sanitize_fcr31(next) ++# define __sanitize_fcr31(next) do { (void) (next); } while (0) + #endif + + /* +-- +2.43.0 + diff --git a/queue-5.10/misc-apds990x-fix-missing-pm_runtime_disable.patch b/queue-5.10/misc-apds990x-fix-missing-pm_runtime_disable.patch new file mode 100644 index 00000000000..682be758281 --- /dev/null +++ b/queue-5.10/misc-apds990x-fix-missing-pm_runtime_disable.patch @@ -0,0 +1,67 @@ +From 7e913a3dffbd74912719cdd605dcdb546e5f5342 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Sep 2024 11:55:56 +0800 +Subject: misc: apds990x: Fix missing pm_runtime_disable() + +From: Jinjie Ruan + +[ Upstream commit 3c5d8b819d27012264edd17e6ae7fffda382fe44 ] + +The pm_runtime_disable() is missing in probe error path, +so add it to fix it. + +Fixes: 92b1f84d46b2 ("drivers/misc: driver for APDS990X ALS and proximity sensors") +Signed-off-by: Jinjie Ruan +Link: https://lore.kernel.org/r/20240923035556.3009105-1-ruanjinjie@huawei.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/apds990x.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c +index 45f5b997a0e10..5b17288ecc2f0 100644 +--- a/drivers/misc/apds990x.c ++++ b/drivers/misc/apds990x.c +@@ -1148,7 +1148,7 @@ static int apds990x_probe(struct i2c_client *client, + err = chip->pdata->setup_resources(); + if (err) { + err = -EINVAL; +- goto fail3; ++ goto fail4; + } + } + +@@ -1156,7 +1156,7 @@ static int apds990x_probe(struct i2c_client *client, + apds990x_attribute_group); + if (err < 0) { + dev_err(&chip->client->dev, "Sysfs registration failed\n"); +- goto fail4; ++ goto fail5; + } + + err = request_threaded_irq(client->irq, NULL, +@@ -1167,15 +1167,17 @@ static int apds990x_probe(struct i2c_client *client, + if (err) { + dev_err(&client->dev, "could not get IRQ %d\n", + client->irq); +- goto fail5; ++ goto fail6; + } + return err; +-fail5: ++fail6: + sysfs_remove_group(&chip->client->dev.kobj, + &apds990x_attribute_group[0]); +-fail4: ++fail5: + if (chip->pdata && chip->pdata->release_resources) + chip->pdata->release_resources(); ++fail4: ++ pm_runtime_disable(&client->dev); + fail3: + regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); + fail2: +-- +2.43.0 + diff --git a/queue-5.10/mmc-mmc_spi-drop-buggy-snprintf.patch b/queue-5.10/mmc-mmc_spi-drop-buggy-snprintf.patch new file mode 100644 index 00000000000..a941208f7cb --- /dev/null +++ b/queue-5.10/mmc-mmc_spi-drop-buggy-snprintf.patch @@ -0,0 +1,66 @@ +From a49b982fc9522404b2a1542ece3f07fc803986c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 18:01:34 +0200 +Subject: mmc: mmc_spi: drop buggy snprintf() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bartosz Golaszewski + +[ Upstream commit 328bda09cc91b3d93bc64f4a4dadc44313dd8140 ] + +GCC 13 complains about the truncated output of snprintf(): + +drivers/mmc/host/mmc_spi.c: In function ‘mmc_spi_response_get’: +drivers/mmc/host/mmc_spi.c:227:64: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] + 227 | snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", + | ^ +drivers/mmc/host/mmc_spi.c:227:9: note: ‘snprintf’ output between 26 and 43 bytes into a destination of size 32 + 227 | snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 228 | cmd->opcode, maptype(cmd)); + +Drop it and fold the string it generates into the only place where it's +emitted - the dev_dbg() call at the end of the function. + +Fixes: 15a0580ced08 ("mmc_spi host driver") +Suggested-by: Christophe JAILLET +Signed-off-by: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20241008160134.69934-1-brgl@bgdev.pl +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/mmc_spi.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c +index a1fb5d0e9553a..d85e5f7f5011d 100644 +--- a/drivers/mmc/host/mmc_spi.c ++++ b/drivers/mmc/host/mmc_spi.c +@@ -230,10 +230,6 @@ static int mmc_spi_response_get(struct mmc_spi_host *host, + u8 leftover = 0; + unsigned short rotator; + int i; +- char tag[32]; +- +- snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", +- cmd->opcode, maptype(cmd)); + + /* Except for data block reads, the whole response will already + * be stored in the scratch buffer. It's somewhere after the +@@ -386,8 +382,9 @@ static int mmc_spi_response_get(struct mmc_spi_host *host, + } + + if (value < 0) +- dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n", +- tag, cmd->resp[0], cmd->resp[1]); ++ dev_dbg(&host->spi->dev, ++ " ... CMD%d response SPI_%s: resp %04x %08x\n", ++ cmd->opcode, maptype(cmd), cmd->resp[0], cmd->resp[1]); + + /* disable chipselect on errors and some success cases */ + if (value >= 0 && cs_on) +-- +2.43.0 + diff --git a/queue-5.10/mtd-rawnand-atmel-fix-possible-memory-leak.patch b/queue-5.10/mtd-rawnand-atmel-fix-possible-memory-leak.patch new file mode 100644 index 00000000000..fcf0cbc54c5 --- /dev/null +++ b/queue-5.10/mtd-rawnand-atmel-fix-possible-memory-leak.patch @@ -0,0 +1,70 @@ +From 7885763356c1ca927f08ea39e0db6cbc8fc1be64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 22:31:49 +0200 +Subject: mtd: rawnand: atmel: Fix possible memory leak + +From: Miquel Raynal + +[ Upstream commit 6d734f1bfc336aaea91313a5632f2f197608fadd ] + +The pmecc "user" structure is allocated in atmel_pmecc_create_user() and +was supposed to be freed with atmel_pmecc_destroy_user(), but this other +helper is never called. One solution would be to find the proper +location to call the destructor, but the trend today is to switch to +device managed allocations, which in this case fits pretty well. + +Replace kzalloc() by devm_kzalloc() and drop the destructor entirely. + +Reported-by: "Dr. David Alan Gilbert" +Closes: https://lore.kernel.org/all/ZvmIvRJCf6VhHvpo@gallifrey/ +Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20241001203149.387655-1-miquel.raynal@bootlin.com +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/atmel/pmecc.c | 8 +------- + drivers/mtd/nand/raw/atmel/pmecc.h | 2 -- + 2 files changed, 1 insertion(+), 9 deletions(-) + +diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c +index cbb023bf00f72..09848d13802d8 100644 +--- a/drivers/mtd/nand/raw/atmel/pmecc.c ++++ b/drivers/mtd/nand/raw/atmel/pmecc.c +@@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, + size = ALIGN(size, sizeof(s32)); + size += (req->ecc.strength + 1) * sizeof(s32) * 3; + +- user = kzalloc(size, GFP_KERNEL); ++ user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL); + if (!user) + return ERR_PTR(-ENOMEM); + +@@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, + } + EXPORT_SYMBOL_GPL(atmel_pmecc_create_user); + +-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user) +-{ +- kfree(user); +-} +-EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user); +- + static int get_strength(struct atmel_pmecc_user *user) + { + const int *strengths = user->pmecc->caps->strengths; +diff --git a/drivers/mtd/nand/raw/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h +index 7851c05126cf1..cc0c5af1f4f1a 100644 +--- a/drivers/mtd/nand/raw/atmel/pmecc.h ++++ b/drivers/mtd/nand/raw/atmel/pmecc.h +@@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev); + struct atmel_pmecc_user * + atmel_pmecc_create_user(struct atmel_pmecc *pmecc, + struct atmel_pmecc_user_req *req); +-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user); +- + void atmel_pmecc_reset(struct atmel_pmecc *pmecc); + int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op); + void atmel_pmecc_disable(struct atmel_pmecc_user *user); +-- +2.43.0 + diff --git a/queue-5.10/net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch b/queue-5.10/net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch new file mode 100644 index 00000000000..ac65ace3acc --- /dev/null +++ b/queue-5.10/net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch @@ -0,0 +1,61 @@ +From 58a37bfabbae0a5f1cb39c282326ad747962549c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 17:13:43 +0000 +Subject: net: hsr: fix hsr_init_sk() vs network/transport headers. + +From: Eric Dumazet + +[ Upstream commit 9cfb5e7f0ded2bfaabc270ceb5f91d13f0e805b9 ] + +Following sequence in hsr_init_sk() is invalid : + + skb_reset_mac_header(skb); + skb_reset_mac_len(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + +It is invalid because skb_reset_mac_len() needs the correct +network header, which should be after the mac header. + +This patch moves the skb_reset_network_header() +and skb_reset_transport_header() before +the call to dev_hard_header(). + +As a result skb->mac_len is no longer set to a value +close to 65535. + +Fixes: 48b491a5cc74 ("net: hsr: fix mac_len checks") +Signed-off-by: Eric Dumazet +Cc: George McCollister +Link: https://patch.msgid.link/20241122171343.897551-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/hsr/hsr_device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index c5a4c5fb72934..505eb58f7e081 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -256,6 +256,8 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master) + skb->dev = master->dev; + skb->priority = TC_PRIO_CONTROL; + ++ skb_reset_network_header(skb); ++ skb_reset_transport_header(skb); + if (dev_hard_header(skb, skb->dev, ETH_P_PRP, + hsr->sup_multicast_addr, + skb->dev->dev_addr, skb->len) <= 0) +@@ -263,8 +265,6 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master) + + skb_reset_mac_header(skb); + skb_reset_mac_len(skb); +- skb_reset_network_header(skb); +- skb_reset_transport_header(skb); + + return skb; + out: +-- +2.43.0 + diff --git a/queue-5.10/net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch b/queue-5.10/net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch new file mode 100644 index 00000000000..e03cf34cb64 --- /dev/null +++ b/queue-5.10/net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch @@ -0,0 +1,67 @@ +From f05ec627e4c3e2bf47e787330753ac474690dacb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 18:19:48 +0000 +Subject: net: introduce a netdev feature for UDP GRO forwarding + +From: Alexander Lobakin + +[ Upstream commit 6f1c0ea133a6e4a193a7b285efe209664caeea43 ] + +Introduce a new netdev feature, NETIF_F_GRO_UDP_FWD, to allow user +to turn UDP GRO on and off for forwarding. +Defaults to off to not change current datapath. + +Suggested-by: Paolo Abeni +Signed-off-by: Alexander Lobakin +Signed-off-by: Jakub Kicinski +Stable-dep-of: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.") +Signed-off-by: Sasha Levin +--- + include/linux/netdev_features.h | 4 +++- + net/ethtool/common.c | 1 + + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h +index e2a92697a6638..7b7a7e4d81254 100644 +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -84,6 +84,7 @@ enum { + NETIF_F_GRO_FRAGLIST_BIT, /* Fraglist GRO */ + + NETIF_F_HW_MACSEC_BIT, /* Offload MACsec operations */ ++ NETIF_F_GRO_UDP_FWD_BIT, /* Allow UDP GRO for forwarding */ + + /* + * Add your fresh new feature above and remember to update +@@ -157,6 +158,7 @@ enum { + #define NETIF_F_GRO_FRAGLIST __NETIF_F(GRO_FRAGLIST) + #define NETIF_F_GSO_FRAGLIST __NETIF_F(GSO_FRAGLIST) + #define NETIF_F_HW_MACSEC __NETIF_F(HW_MACSEC) ++#define NETIF_F_GRO_UDP_FWD __NETIF_F(GRO_UDP_FWD) + + /* Finds the next feature with the highest number of the range of start-1 till 0. + */ +@@ -234,7 +236,7 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start) + #define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) + + /* Changeable features with no special hardware requirements that defaults to off. */ +-#define NETIF_F_SOFT_FEATURES_OFF NETIF_F_GRO_FRAGLIST ++#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD) + + #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \ + NETIF_F_HW_VLAN_CTAG_RX | \ +diff --git a/net/ethtool/common.c b/net/ethtool/common.c +index 24036e3055a13..181220101a6e7 100644 +--- a/net/ethtool/common.c ++++ b/net/ethtool/common.c +@@ -68,6 +68,7 @@ const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = { + [NETIF_F_HW_TLS_RX_BIT] = "tls-hw-rx-offload", + [NETIF_F_GRO_FRAGLIST_BIT] = "rx-gro-list", + [NETIF_F_HW_MACSEC_BIT] = "macsec-hw-offload", ++ [NETIF_F_GRO_UDP_FWD_BIT] = "rx-udp-gro-forwarding", + }; + + const char +-- +2.43.0 + diff --git a/queue-5.10/net-rfkill-gpio-add-check-for-clk_enable.patch b/queue-5.10/net-rfkill-gpio-add-check-for-clk_enable.patch new file mode 100644 index 00000000000..d0eec28b573 --- /dev/null +++ b/queue-5.10/net-rfkill-gpio-add-check-for-clk_enable.patch @@ -0,0 +1,44 @@ +From 36c7d393b835c1069a67695718f02accfb82e1b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2024 14:53:41 -0500 +Subject: net: rfkill: gpio: Add check for clk_enable() + +From: Mingwei Zheng + +[ Upstream commit 8251e7621b25ccdb689f1dd9553b8789e3745ea1 ] + +Add check for the return value of clk_enable() to catch the potential +error. + +Fixes: 7176ba23f8b5 ("net: rfkill: add generic gpio rfkill driver") +Signed-off-by: Mingwei Zheng +Signed-off-by: Jiasheng Jiang +Link: https://patch.msgid.link/20241108195341.1853080-1-zmw12306@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/rfkill/rfkill-gpio.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c +index f74baefd855d3..2df5bf240b64a 100644 +--- a/net/rfkill/rfkill-gpio.c ++++ b/net/rfkill/rfkill-gpio.c +@@ -30,8 +30,12 @@ static int rfkill_gpio_set_power(void *data, bool blocked) + { + struct rfkill_gpio_data *rfkill = data; + +- if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) +- clk_enable(rfkill->clk); ++ if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) { ++ int ret = clk_enable(rfkill->clk); ++ ++ if (ret) ++ return ret; ++ } + + gpiod_set_value_cansleep(rfkill->shutdown_gpio, !blocked); + gpiod_set_value_cansleep(rfkill->reset_gpio, !blocked); +-- +2.43.0 + diff --git a/queue-5.10/net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch b/queue-5.10/net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch new file mode 100644 index 00000000000..3ddcade0ef7 --- /dev/null +++ b/queue-5.10/net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch @@ -0,0 +1,50 @@ +From c060709fb05e6fd5dd4ca37d6cd38339c159b847 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 15:12:55 +0100 +Subject: net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken + +From: Maxime Chevallier + +[ Upstream commit 407618d66dba55e7db1278872e8be106808bbe91 ] + +On DWMAC3 and later, there's a RX Watchdog interrupt that's used for +interrupt coalescing. It's known to be buggy on some platforms, and +dwmac-socfpga appears to be one of them. Changing the interrupt +coalescing from ethtool doesn't appear to have any effect here. + +Without disabling RIWT (Received Interrupt Watchdog Timer, I +believe...), we observe latencies while receiving traffic that amount to +around ~0.4ms. This was discovered with NTP but can be easily reproduced +with a simple ping. Without this patch : + +64 bytes from 192.168.5.2: icmp_seq=1 ttl=64 time=0.657 ms + +With this patch : + +64 bytes from 192.168.5.2: icmp_seq=1 ttl=64 time=0.254 ms + +Fixes: 801d233b7302 ("net: stmmac: Add SOCFPGA glue driver") +Signed-off-by: Maxime Chevallier +Link: https://patch.msgid.link/20241122141256.764578-1-maxime.chevallier@bootlin.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +index 142bf912011e2..263235a4fc554 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +@@ -426,6 +426,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) + plat_dat->bsp_priv = dwmac; + plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; + ++ plat_dat->riwt_off = 1; ++ + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); + if (ret) + goto err_remove_config_dt; +-- +2.43.0 + diff --git a/queue-5.10/net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch b/queue-5.10/net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch new file mode 100644 index 00000000000..477b7548b29 --- /dev/null +++ b/queue-5.10/net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch @@ -0,0 +1,51 @@ +From fe60b77a776d2c2f8bc9d2a0e51fe2d56a3b11b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Nov 2024 14:05:58 +0100 +Subject: net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY + device + +From: Oleksij Rempel + +[ Upstream commit ae7370e61c5d8f5bcefc2d4fca724bd4e9bbf789 ] + +Add calls to `phy_device_free` after `fixed_phy_unregister` to fix a +memory leak that occurs when the device is unplugged. This ensures +proper cleanup of pseudo fixed-link PHYs. + +Fixes: 89b36fb5e532 ("lan78xx: Lan7801 Support for Fixed PHY") +Cc: Raghuram Chary J +Signed-off-by: Oleksij Rempel +Link: https://patch.msgid.link/20241116130558.1352230-2-o.rempel@pengutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/lan78xx.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 96d3d0bd248bc..757d5c82f3f09 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2157,6 +2157,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) + if (dev->chipid == ID_REV_CHIP_ID_7801_) { + if (phy_is_pseudo_fixed_link(phydev)) { + fixed_phy_unregister(phydev); ++ phy_device_free(phydev); + } else { + phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, + 0xfffffff0); +@@ -3835,8 +3836,10 @@ static void lan78xx_disconnect(struct usb_interface *intf) + + phy_disconnect(net->phydev); + +- if (phy_is_pseudo_fixed_link(phydev)) ++ if (phy_is_pseudo_fixed_link(phydev)) { + fixed_phy_unregister(phydev); ++ phy_device_free(phydev); ++ } + + unregister_netdev(net); + +-- +2.43.0 + diff --git a/queue-5.10/net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch b/queue-5.10/net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch new file mode 100644 index 00000000000..fc39134460e --- /dev/null +++ b/queue-5.10/net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch @@ -0,0 +1,49 @@ +From 5373c9cf9c12de35dee218077b5d7b749f88b993 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Nov 2024 15:03:51 +0100 +Subject: net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL + configuration + +From: Oleksij Rempel + +[ Upstream commit e863ff806f72098bccaf8fa89c80d9ad6187c3b0 ] + +Validate Wake-on-LAN (WoL) options in `lan78xx_set_wol` before calling +`usb_autopm_get_interface`. This prevents USB autopm refcounting issues +and ensures the adapter can properly enter autosuspend when invalid WoL +options are provided. + +Fixes: eb9ad088f966 ("lan78xx: Check for supported Wake-on-LAN modes") +Signed-off-by: Oleksij Rempel +Acked-by: Florian Fainelli +Link: https://patch.msgid.link/20241118140351.2398166-1-o.rempel@pengutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/lan78xx.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 757d5c82f3f09..cabe6cdd6903a 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1428,13 +1428,13 @@ static int lan78xx_set_wol(struct net_device *netdev, + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); + int ret; + ++ if (wol->wolopts & ~WAKE_ALL) ++ return -EINVAL; ++ + ret = usb_autopm_get_interface(dev->intf); + if (ret < 0) + return ret; + +- if (wol->wolopts & ~WAKE_ALL) +- return -EINVAL; +- + pdata->wol = wol->wolopts; + + device_set_wakeup_enable(&dev->udev->dev, (bool)wol->wolopts); +-- +2.43.0 + diff --git a/queue-5.10/netdevsim-copy-addresses-for-both-in-and-out-paths.patch b/queue-5.10/netdevsim-copy-addresses-for-both-in-and-out-paths.patch new file mode 100644 index 00000000000..8a13606b108 --- /dev/null +++ b/queue-5.10/netdevsim-copy-addresses-for-both-in-and-out-paths.patch @@ -0,0 +1,70 @@ +From 0e3b7bca065a9c607fd9dbb57f665ae0e9404076 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Oct 2024 04:00:26 +0000 +Subject: netdevsim: copy addresses for both in and out paths + +From: Hangbin Liu + +[ Upstream commit 2cf567f421dbfe7e53b7e5ddee9400da10efb75d ] + +The current code only copies the address for the in path, leaving the out +path address set to 0. This patch corrects the issue by copying the addresses +for both the in and out paths. Before this patch: + + # cat /sys/kernel/debug/netdevsim/netdevsim0/ports/0/ipsec + SA count=2 tx=20 + sa[0] tx ipaddr=0.0.0.0 + sa[0] spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1 + sa[0] key=0x3167608a ca4f1397 43565909 941fa627 + sa[1] rx ipaddr=192.168.0.1 + sa[1] spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1 + sa[1] key=0x3167608a ca4f1397 43565909 941fa627 + +After this patch: + + = cat /sys/kernel/debug/netdevsim/netdevsim0/ports/0/ipsec + SA count=2 tx=20 + sa[0] tx ipaddr=192.168.0.2 + sa[0] spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1 + sa[0] key=0x3167608a ca4f1397 43565909 941fa627 + sa[1] rx ipaddr=192.168.0.1 + sa[1] spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1 + sa[1] key=0x3167608a ca4f1397 43565909 941fa627 + +Fixes: 7699353da875 ("netdevsim: add ipsec offload testing") +Reviewed-by: Simon Horman +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20241010040027.21440-3-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/netdevsim/ipsec.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c +index 386336a38f349..feca55eef9938 100644 +--- a/drivers/net/netdevsim/ipsec.c ++++ b/drivers/net/netdevsim/ipsec.c +@@ -171,14 +171,13 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs) + return ret; + } + +- if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { ++ if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) + sa.rx = true; + +- if (xs->props.family == AF_INET6) +- memcpy(sa.ipaddr, &xs->id.daddr.a6, 16); +- else +- memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4); +- } ++ if (xs->props.family == AF_INET6) ++ memcpy(sa.ipaddr, &xs->id.daddr.a6, 16); ++ else ++ memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4); + + /* the preparations worked, so save the info */ + memcpy(&ipsec->sa[sa_idx], &sa, sizeof(sa)); +-- +2.43.0 + diff --git a/queue-5.10/netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch b/queue-5.10/netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch new file mode 100644 index 00000000000..31971b71fec --- /dev/null +++ b/queue-5.10/netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch @@ -0,0 +1,37 @@ +From 85aad10a3d3f1013a863c121c5ccb11d7a9320b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 May 2022 13:06:43 +0300 +Subject: netdevsim: rely on XFRM state direction instead of flags + +From: Leon Romanovsky + +[ Upstream commit 55e2f83afb1c142885da63c5a9ce2998b6f6ab21 ] + +Make sure that netdevsim relies on direction and not on flags. + +Reviewed-by: Raed Salem +Signed-off-by: Leon Romanovsky +Acked-by: Jakub Kicinski +Signed-off-by: Steffen Klassert +Stable-dep-of: 2cf567f421db ("netdevsim: copy addresses for both in and out paths") +Signed-off-by: Sasha Levin +--- + drivers/net/netdevsim/ipsec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c +index b80ed2ffd45eb..386336a38f349 100644 +--- a/drivers/net/netdevsim/ipsec.c ++++ b/drivers/net/netdevsim/ipsec.c +@@ -171,7 +171,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs) + return ret; + } + +- if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { ++ if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { + sa.rx = true; + + if (xs->props.family == AF_INET6) +-- +2.43.0 + diff --git a/queue-5.10/netlink-typographical-error-in-nlmsg_type-constants-.patch b/queue-5.10/netlink-typographical-error-in-nlmsg_type-constants-.patch new file mode 100644 index 00000000000..c2a8d1c7632 --- /dev/null +++ b/queue-5.10/netlink-typographical-error-in-nlmsg_type-constants-.patch @@ -0,0 +1,36 @@ +From 262f8f209d4cf8fe3a2d135b8bc9848b7b25f736 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 Nov 2024 23:39:50 +0100 +Subject: netlink: typographical error in nlmsg_type constants definition + +From: Maurice Lambert + +[ Upstream commit 84bfbfbbd32aee136afea4b6bf82581dce79c305 ] + +This commit fix a typographical error in netlink nlmsg_type constants definition in the include/uapi/linux/rtnetlink.h at line 177. The definition is RTM_NEWNVLAN RTM_NEWVLAN instead of RTM_NEWVLAN RTM_NEWVLAN. + +Signed-off-by: Maurice Lambert +Fixes: 8dcea187088b ("net: bridge: vlan: add rtm definitions and dump support") +Link: https://patch.msgid.link/20241103223950.230300-1-mauricelambert434@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/uapi/linux/rtnetlink.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h +index 9b814c92de123..31be7345e0c2e 100644 +--- a/include/uapi/linux/rtnetlink.h ++++ b/include/uapi/linux/rtnetlink.h +@@ -172,7 +172,7 @@ enum { + #define RTM_GETLINKPROP RTM_GETLINKPROP + + RTM_NEWVLAN = 112, +-#define RTM_NEWNVLAN RTM_NEWVLAN ++#define RTM_NEWVLAN RTM_NEWVLAN + RTM_DELVLAN, + #define RTM_DELVLAN RTM_DELVLAN + RTM_GETVLAN, +-- +2.43.0 + diff --git a/queue-5.10/netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch b/queue-5.10/netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch new file mode 100644 index 00000000000..6710afd4e89 --- /dev/null +++ b/queue-5.10/netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch @@ -0,0 +1,45 @@ +From 01f17401af2e04b4a121af34acbcf1a239ae0133 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Nov 2024 03:15:18 -0800 +Subject: netpoll: Use rcu_access_pointer() in netpoll_poll_lock + +From: Breno Leitao + +[ Upstream commit a57d5a72f8dec7db8a79d0016fb0a3bdecc82b56 ] + +The ndev->npinfo pointer in netpoll_poll_lock() is RCU-protected but is +being accessed directly for a NULL check. While no RCU read lock is held +in this context, we should still use proper RCU primitives for +consistency and correctness. + +Replace the direct NULL check with rcu_access_pointer(), which is the +appropriate primitive when only checking for NULL without dereferencing +the pointer. This function provides the necessary ordering guarantees +without requiring RCU read-side protection. + +Fixes: bea3348eef27 ("[NET]: Make NAPI polling independent of struct net_device objects.") +Signed-off-by: Breno Leitao +Reviewed-by: Michal Kubiak +Link: https://patch.msgid.link/20241118-netpoll_rcu-v1-2-a1888dcb4a02@debian.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/netpoll.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h +index e6a2d72e0dc7a..533f8a5323a3b 100644 +--- a/include/linux/netpoll.h ++++ b/include/linux/netpoll.h +@@ -70,7 +70,7 @@ static inline void *netpoll_poll_lock(struct napi_struct *napi) + { + struct net_device *dev = napi->dev; + +- if (dev && dev->npinfo) { ++ if (dev && rcu_access_pointer(dev->npinfo)) { + int owner = smp_processor_id(); + + while (cmpxchg(&napi->poll_owner, -1, owner) != -1) +-- +2.43.0 + diff --git a/queue-5.10/nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch b/queue-5.10/nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch new file mode 100644 index 00000000000..dc7094d8f63 --- /dev/null +++ b/queue-5.10/nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch @@ -0,0 +1,37 @@ +From a14574fbeb60884c36392a3efe7b9f7e7910fca8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Oct 2024 11:03:56 -0400 +Subject: NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir() + +From: Chuck Lever + +[ Upstream commit f64ea4af43161bb86ffc77e6aeb5bcf5c3229df0 ] + +It's only current caller already length-checks the string, but let's +be safe. + +Fixes: 0964a3d3f1aa ("[PATCH] knfsd: nfsd4 reboot dirname fix") +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4recover.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c +index 2904268c18c9a..eca39b5c12c68 100644 +--- a/fs/nfsd/nfs4recover.c ++++ b/fs/nfsd/nfs4recover.c +@@ -658,7 +658,8 @@ nfs4_reset_recoverydir(char *recdir) + return status; + status = -ENOTDIR; + if (d_is_dir(path.dentry)) { +- strcpy(user_recovery_dirname, recdir); ++ strscpy(user_recovery_dirname, recdir, ++ sizeof(user_recovery_dirname)); + status = 0; + } + path_put(&path); +-- +2.43.0 + diff --git a/queue-5.10/nfsd-fix-nfsd4_shutdown_copy.patch b/queue-5.10/nfsd-fix-nfsd4_shutdown_copy.patch new file mode 100644 index 00000000000..57362c34213 --- /dev/null +++ b/queue-5.10/nfsd-fix-nfsd4_shutdown_copy.patch @@ -0,0 +1,73 @@ +From 26b4bc3e2ac1e825ba05ec57df0a1c879a29820d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Oct 2024 09:40:03 -0400 +Subject: NFSD: Fix nfsd4_shutdown_copy() + +From: Chuck Lever + +[ Upstream commit 62a8642ba00aa8ceb0a02ade942f5ec52e877c95 ] + +nfsd4_shutdown_copy() is just this: + + while ((copy = nfsd4_get_copy(clp)) != NULL) + nfsd4_stop_copy(copy); + +nfsd4_get_copy() bumps @copy's reference count, preventing +nfsd4_stop_copy() from releasing @copy. + +A while loop like this usually works by removing the first element +of the list, but neither nfsd4_get_copy() nor nfsd4_stop_copy() +alters the async_copies list. + +Best I can tell, then, is that nfsd4_shutdown_copy() continues to +loop until other threads manage to remove all the items from this +list. The spinning loop blocks shutdown until these items are gone. + +Possibly the reason we haven't seen this issue in the field is +because client_has_state() prevents __destroy_client() from calling +nfsd4_shutdown_copy() if there are any items on this list. In a +subsequent patch I plan to remove that restriction. + +Fixes: e0639dc5805a ("NFSD introduce async copy feature") +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4proc.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index 237e47896af86..8cf0e4e62bc84 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1256,7 +1256,7 @@ static void nfsd4_stop_copy(struct nfsd4_copy *copy) + nfs4_put_copy(copy); + } + +-static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp) ++static struct nfsd4_copy *nfsd4_unhash_copy(struct nfs4_client *clp) + { + struct nfsd4_copy *copy = NULL; + +@@ -1265,6 +1265,9 @@ static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp) + copy = list_first_entry(&clp->async_copies, struct nfsd4_copy, + copies); + refcount_inc(©->refcount); ++ copy->cp_clp = NULL; ++ if (!list_empty(©->copies)) ++ list_del_init(©->copies); + } + spin_unlock(&clp->async_lock); + return copy; +@@ -1274,7 +1277,7 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp) + { + struct nfsd4_copy *copy; + +- while ((copy = nfsd4_get_copy(clp)) != NULL) ++ while ((copy = nfsd4_unhash_copy(clp)) != NULL) + nfsd4_stop_copy(copy); + } + #ifdef CONFIG_NFSD_V4_2_INTER_SSC +-- +2.43.0 + diff --git a/queue-5.10/nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch b/queue-5.10/nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch new file mode 100644 index 00000000000..a29fb788690 --- /dev/null +++ b/queue-5.10/nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch @@ -0,0 +1,37 @@ +From 9012872c33883c74704550ebdb79d33854897565 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Oct 2024 11:03:53 -0400 +Subject: NFSD: Prevent NULL dereference in nfsd4_process_cb_update() + +From: Chuck Lever + +[ Upstream commit 1e02c641c3a43c88cecc08402000418e15578d38 ] + +@ses is initialized to NULL. If __nfsd4_find_backchannel() finds no +available backchannel session, setup_callback_client() will try to +dereference @ses and segfault. + +Fixes: dcbeaa68dbbd ("nfsd4: allow backchannel recovery") +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4callback.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 4eae2c5af2edf..18d62d3424c1a 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -1379,6 +1379,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb) + ses = c->cn_session; + } + spin_unlock(&clp->cl_lock); ++ if (!c) ++ return; + + err = setup_callback_client(clp, &conn, ses); + if (err) { +-- +2.43.0 + diff --git a/queue-5.10/nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch b/queue-5.10/nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch new file mode 100644 index 00000000000..5a848e07216 --- /dev/null +++ b/queue-5.10/nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch @@ -0,0 +1,94 @@ +From f7e4dbe5e3db37c512c35c650f4ba9edd0164760 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Nov 2024 05:40:04 +0100 +Subject: nvme-pci: fix freeing of the HMB descriptor table + +From: Christoph Hellwig + +[ Upstream commit 3c2fb1ca8086eb139b2a551358137525ae8e0d7a ] + +The HMB descriptor table is sized to the maximum number of descriptors +that could be used for a given device, but __nvme_alloc_host_mem could +break out of the loop earlier on memory allocation failure and end up +using less descriptors than planned for, which leads to an incorrect +size passed to dma_free_coherent. + +In practice this was not showing up because the number of descriptors +tends to be low and the dma coherent allocator always allocates and +frees at least a page. + +Fixes: 87ad72a59a38 ("nvme-pci: implement host memory buffer support") +Signed-off-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 78cac4220e03a..875ebef6adc71 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -147,6 +147,7 @@ struct nvme_dev { + /* host memory buffer support: */ + u64 host_mem_size; + u32 nr_host_mem_descs; ++ u32 host_mem_descs_size; + dma_addr_t host_mem_descs_dma; + struct nvme_host_mem_buf_desc *host_mem_descs; + void **host_mem_desc_bufs; +@@ -1925,10 +1926,10 @@ static void nvme_free_host_mem(struct nvme_dev *dev) + + kfree(dev->host_mem_desc_bufs); + dev->host_mem_desc_bufs = NULL; +- dma_free_coherent(dev->dev, +- dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs), ++ dma_free_coherent(dev->dev, dev->host_mem_descs_size, + dev->host_mem_descs, dev->host_mem_descs_dma); + dev->host_mem_descs = NULL; ++ dev->host_mem_descs_size = 0; + dev->nr_host_mem_descs = 0; + } + +@@ -1936,7 +1937,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred, + u32 chunk_size) + { + struct nvme_host_mem_buf_desc *descs; +- u32 max_entries, len; ++ u32 max_entries, len, descs_size; + dma_addr_t descs_dma; + int i = 0; + void **bufs; +@@ -1949,8 +1950,9 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred, + if (dev->ctrl.hmmaxd && dev->ctrl.hmmaxd < max_entries) + max_entries = dev->ctrl.hmmaxd; + +- descs = dma_alloc_coherent(dev->dev, max_entries * sizeof(*descs), +- &descs_dma, GFP_KERNEL); ++ descs_size = max_entries * sizeof(*descs); ++ descs = dma_alloc_coherent(dev->dev, descs_size, &descs_dma, ++ GFP_KERNEL); + if (!descs) + goto out; + +@@ -1979,6 +1981,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred, + dev->host_mem_size = size; + dev->host_mem_descs = descs; + dev->host_mem_descs_dma = descs_dma; ++ dev->host_mem_descs_size = descs_size; + dev->host_mem_desc_bufs = bufs; + return 0; + +@@ -1993,8 +1996,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred, + + kfree(bufs); + out_free_descs: +- dma_free_coherent(dev->dev, max_entries * sizeof(*descs), descs, +- descs_dma); ++ dma_free_coherent(dev->dev, descs_size, descs, descs_dma); + out: + dev->host_mem_descs = NULL; + return -ENOMEM; +-- +2.43.0 + diff --git a/queue-5.10/ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch b/queue-5.10/ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch new file mode 100644 index 00000000000..776f0f6bb5d --- /dev/null +++ b/queue-5.10/ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch @@ -0,0 +1,98 @@ +From fd60c0272d1fe93af7f9e0825cdf973b6f6e22ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 12:17:36 +0300 +Subject: ocfs2: fix uninitialized value in ocfs2_file_read_iter() + +From: Dmitry Antipov + +[ Upstream commit adc77b19f62d7e80f98400b2fca9d700d2afdd6f ] + +Syzbot has reported the following KMSAN splat: + +BUG: KMSAN: uninit-value in ocfs2_file_read_iter+0x9a4/0xf80 + ocfs2_file_read_iter+0x9a4/0xf80 + __io_read+0x8d4/0x20f0 + io_read+0x3e/0xf0 + io_issue_sqe+0x42b/0x22c0 + io_wq_submit_work+0xaf9/0xdc0 + io_worker_handle_work+0xd13/0x2110 + io_wq_worker+0x447/0x1410 + ret_from_fork+0x6f/0x90 + ret_from_fork_asm+0x1a/0x30 + +Uninit was created at: + __alloc_pages_noprof+0x9a7/0xe00 + alloc_pages_mpol_noprof+0x299/0x990 + alloc_pages_noprof+0x1bf/0x1e0 + allocate_slab+0x33a/0x1250 + ___slab_alloc+0x12ef/0x35e0 + kmem_cache_alloc_bulk_noprof+0x486/0x1330 + __io_alloc_req_refill+0x84/0x560 + io_submit_sqes+0x172f/0x2f30 + __se_sys_io_uring_enter+0x406/0x41c0 + __x64_sys_io_uring_enter+0x11f/0x1a0 + x64_sys_call+0x2b54/0x3ba0 + do_syscall_64+0xcd/0x1e0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Since an instance of 'struct kiocb' may be passed from the block layer +with 'private' field uninitialized, introduce 'ocfs2_iocb_init_rw_locked()' +and use it from where 'ocfs2_dio_end_io()' might take care, i.e. in +'ocfs2_file_read_iter()' and 'ocfs2_file_write_iter()'. + +Link: https://lkml.kernel.org/r/20241029091736.1501946-1-dmantipov@yandex.ru +Fixes: 7cdfc3a1c397 ("ocfs2: Remember rw lock level during direct io") +Signed-off-by: Dmitry Antipov +Reported-by: syzbot+a73e253cca4f0230a5a5@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=a73e253cca4f0230a5a5 +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Joseph Qi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/aops.h | 2 ++ + fs/ocfs2/file.c | 4 ++++ + 2 files changed, 6 insertions(+) + +diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h +index 70ed4382750d5..5b129ae9c3d22 100644 +--- a/fs/ocfs2/aops.h ++++ b/fs/ocfs2/aops.h +@@ -72,6 +72,8 @@ enum ocfs2_iocb_lock_bits { + OCFS2_IOCB_NUM_LOCKS + }; + ++#define ocfs2_iocb_init_rw_locked(iocb) \ ++ (iocb->private = NULL) + #define ocfs2_iocb_clear_rw_locked(iocb) \ + clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private) + #define ocfs2_iocb_rw_locked_level(iocb) \ +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index 224ced997d64b..3ce7606f5dbe8 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -2401,6 +2401,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, + } else + inode_lock(inode); + ++ ocfs2_iocb_init_rw_locked(iocb); ++ + /* + * Concurrent O_DIRECT writes are allowed with + * mount_option "coherency=buffered". +@@ -2547,6 +2549,8 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, + if (!direct_io && nowait) + return -EOPNOTSUPP; + ++ ocfs2_iocb_init_rw_locked(iocb); ++ + /* + * buffered reads protect themselves in ->readpage(). O_DIRECT reads + * need locks to protect pending reads from racing with truncate. +-- +2.43.0 + diff --git a/queue-5.10/octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch b/queue-5.10/octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch new file mode 100644 index 00000000000..1d0eb056ad1 --- /dev/null +++ b/queue-5.10/octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch @@ -0,0 +1,210 @@ +From 77cd25f2bb5fb06c0ef4f90ee74e9c249bc089cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Feb 2021 16:05:26 +0530 +Subject: octeontx2-af: Add new CGX_CMD to get PHY FEC statistics + +From: Felix Manlunas + +[ Upstream commit bd74d4ea29cc3c0520d9af109bb7a7c769325746 ] + +This patch adds support to fetch fec stats from PHY. The stats are +put in the shared data struct fwdata. A PHY driver indicates +that it has FEC stats by setting the flag fwdata.phy.misc.has_fec_stats + +Besides CGX_CMD_GET_PHY_FEC_STATS, also add CGX_CMD_PRBS and +CGX_CMD_DISPLAY_EYE to enum cgx_cmd_id so that Linux's enum list is in sync +with firmware's enum list. + +Signed-off-by: Felix Manlunas +Signed-off-by: Christina Jacob +Signed-off-by: Sunil Goutham +Signed-off-by: Hariprasad Kelam +Reviewed-by: Jesse Brandeburg +Signed-off-by: David S. Miller +Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/marvell/octeontx2/af/cgx.c | 12 ++++++ + .../net/ethernet/marvell/octeontx2/af/cgx.h | 1 + + .../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 5 +++ + .../net/ethernet/marvell/octeontx2/af/mbox.h | 43 +++++++++++++++++++ + .../net/ethernet/marvell/octeontx2/af/rvu.h | 4 ++ + .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 32 ++++++++++++++ + 6 files changed, 97 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 6bcc403e031ff..1eaf728d5e79f 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -866,6 +866,18 @@ int cgx_set_fec(u64 fec, int cgx_id, int lmac_id) + return cgx->lmac_idmap[lmac_id]->link_info.fec; + } + ++int cgx_get_phy_fec_stats(void *cgxd, int lmac_id) ++{ ++ struct cgx *cgx = cgxd; ++ u64 req = 0, resp; ++ ++ if (!cgx) ++ return -ENODEV; ++ ++ req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_PHY_FEC_STATS, req); ++ return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id); ++} ++ + static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable) + { + u64 req = 0; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h +index 6295a6963ff78..82563a88fe1bb 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h +@@ -153,5 +153,6 @@ void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable); + u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id); + int cgx_set_fec(u64 fec, int cgx_id, int lmac_id); + int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp); ++int cgx_get_phy_fec_stats(void *cgxd, int lmac_id); + + #endif /* CGX_H */ +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h +index 3485596c0ed6c..65f832ac39cf1 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h +@@ -89,6 +89,11 @@ enum cgx_cmd_id { + CGX_CMD_SET_AN, + CGX_CMD_GET_ADV_LINK_MODES, + CGX_CMD_GET_ADV_FEC, ++ CGX_CMD_GET_PHY_MOD_TYPE, /* line-side modulation type: NRZ or PAM4 */ ++ CGX_CMD_SET_PHY_MOD_TYPE, ++ CGX_CMD_PRBS, ++ CGX_CMD_DISPLAY_EYE, ++ CGX_CMD_GET_PHY_FEC_STATS, + }; + + /* async event ids */ +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +index 9a135d1cf102d..ccd58d378fe48 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +@@ -151,6 +151,8 @@ M(CGX_CFG_PAUSE_FRM, 0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg, \ + cgx_pause_frm_cfg) \ + M(CGX_FEC_SET, 0x210, cgx_set_fec_param, fec_mode, fec_mode) \ + M(CGX_FEC_STATS, 0x211, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \ ++M(CGX_GET_PHY_FEC_STATS, 0x212, cgx_get_phy_fec_stats, msg_req, msg_rsp) \ ++M(CGX_FW_DATA_GET, 0x213, cgx_get_aux_link_info, msg_req, cgx_fw_data) \ + /* NPA mbox IDs (range 0x400 - 0x5FF) */ \ + /* NPA mbox IDs (range 0x400 - 0x5FF) */ \ + M(NPA_LF_ALLOC, 0x400, npa_lf_alloc, \ +@@ -399,6 +401,47 @@ struct fec_mode { + int fec; + }; + ++struct sfp_eeprom_s { ++#define SFP_EEPROM_SIZE 256 ++ u16 sff_id; ++ u8 buf[SFP_EEPROM_SIZE]; ++ u64 reserved; ++}; ++ ++struct phy_s { ++ struct { ++ u64 can_change_mod_type:1; ++ u64 mod_type:1; ++ u64 has_fec_stats:1; ++ } misc; ++ struct fec_stats_s { ++ u32 rsfec_corr_cws; ++ u32 rsfec_uncorr_cws; ++ u32 brfec_corr_blks; ++ u32 brfec_uncorr_blks; ++ } fec_stats; ++}; ++ ++struct cgx_lmac_fwdata_s { ++ u16 rw_valid; ++ u64 supported_fec; ++ u64 supported_an; ++ u64 supported_link_modes; ++ /* only applicable if AN is supported */ ++ u64 advertised_fec; ++ u64 advertised_link_modes; ++ /* Only applicable if SFP/QSFP slot is present */ ++ struct sfp_eeprom_s sfp_eeprom; ++ struct phy_s phy; ++#define LMAC_FWDATA_RESERVED_MEM 1021 ++ u64 reserved[LMAC_FWDATA_RESERVED_MEM]; ++}; ++ ++struct cgx_fw_data { ++ struct mbox_msghdr hdr; ++ struct cgx_lmac_fwdata_s fwdata; ++}; ++ + /* NPA mbox message formats */ + + /* NPA mailbox error codes +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +index ec9a291e866c7..da8ab4ac4280d 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +@@ -291,6 +291,10 @@ struct rvu_fwdata { + u64 msixtr_base; + #define FWDATA_RESERVED_MEM 1023 + u64 reserved[FWDATA_RESERVED_MEM]; ++#define CGX_MAX 5 ++#define CGX_LMACS_MAX 4 ++ struct cgx_lmac_fwdata_s cgx_fw_data[CGX_MAX][CGX_LMACS_MAX]; ++ /* Do not add new fields below this line */ + }; + + struct ptp; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +index 05ef3a104748a..8f116d681ff42 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +@@ -692,6 +692,19 @@ int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu, + return 0; + } + ++int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req, ++ struct msg_rsp *rsp) ++{ ++ int pf = rvu_get_pf(req->hdr.pcifunc); ++ u8 cgx_id, lmac_id; ++ ++ if (!is_pf_cgxmapped(rvu, pf)) ++ return -EPERM; ++ ++ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); ++ return cgx_get_phy_fec_stats(rvu_cgx_pdata(cgx_id, rvu), lmac_id); ++} ++ + /* Finds cumulative status of NIX rx/tx counters from LF of a PF and those + * from its VFs as well. ie. NIX rx/tx counters at the CGX port level + */ +@@ -800,3 +813,22 @@ int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu, + rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id); + return 0; + } ++ ++int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req, ++ struct cgx_fw_data *rsp) ++{ ++ int pf = rvu_get_pf(req->hdr.pcifunc); ++ u8 cgx_id, lmac_id; ++ ++ if (!rvu->fwdata) ++ return -ENXIO; ++ ++ if (!is_pf_cgxmapped(rvu, pf)) ++ return -EPERM; ++ ++ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); ++ ++ memcpy(&rsp->fwdata, &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id], ++ sizeof(struct cgx_lmac_fwdata_s)); ++ return 0; ++} +-- +2.43.0 + diff --git a/queue-5.10/octeontx2-af-forward-error-correction-configuration.patch b/queue-5.10/octeontx2-af-forward-error-correction-configuration.patch new file mode 100644 index 00000000000..c5c1a3e53f4 --- /dev/null +++ b/queue-5.10/octeontx2-af-forward-error-correction-configuration.patch @@ -0,0 +1,320 @@ +From da3d76109ec863608968a4887dfa2126e9c54401 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Feb 2021 16:05:25 +0530 +Subject: octeontx2-af: forward error correction configuration + +From: Christina Jacob + +[ Upstream commit 84c4f9cab4f99e774a8d9bbee299d288bdb2d792 ] + +CGX block supports forward error correction modes baseR +and RS. This patch adds support to set encoding mode +and to read corrected/uncorrected block counters + +Adds new mailbox handlers set_fec to configure encoding modes +and fec_stats to read counters and also increase mbox timeout +to accomdate firmware command response timeout. + +Along with new CGX_CMD_SET_FEC command add other commands to +sync with kernel enum list with firmware. + +Signed-off-by: Christina Jacob +Signed-off-by: Sunil Goutham +Signed-off-by: Hariprasad Kelam +Reviewed-by: Jesse Brandeburg +Signed-off-by: David S. Miller +Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/marvell/octeontx2/af/cgx.c | 76 +++++++++++++++++++ + .../net/ethernet/marvell/octeontx2/af/cgx.h | 7 ++ + .../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 17 ++++- + .../net/ethernet/marvell/octeontx2/af/mbox.h | 24 +++++- + .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 33 ++++++++ + 5 files changed, 155 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 7f82baf8e7403..6bcc403e031ff 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -340,6 +340,60 @@ int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat) + return 0; + } + ++static int cgx_set_fec_stats_count(struct cgx_link_user_info *linfo) ++{ ++ if (!linfo->fec) ++ return 0; ++ ++ switch (linfo->lmac_type_id) { ++ case LMAC_MODE_SGMII: ++ case LMAC_MODE_XAUI: ++ case LMAC_MODE_RXAUI: ++ case LMAC_MODE_QSGMII: ++ return 0; ++ case LMAC_MODE_10G_R: ++ case LMAC_MODE_25G_R: ++ case LMAC_MODE_100G_R: ++ case LMAC_MODE_USXGMII: ++ return 1; ++ case LMAC_MODE_40G_R: ++ return 4; ++ case LMAC_MODE_50G_R: ++ if (linfo->fec == OTX2_FEC_BASER) ++ return 2; ++ else ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp) ++{ ++ int stats, fec_stats_count = 0; ++ int corr_reg, uncorr_reg; ++ struct cgx *cgx = cgxd; ++ ++ if (!cgx || lmac_id >= cgx->lmac_count) ++ return -ENODEV; ++ fec_stats_count = ++ cgx_set_fec_stats_count(&cgx->lmac_idmap[lmac_id]->link_info); ++ if (cgx->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) { ++ corr_reg = CGXX_SPUX_LNX_FEC_CORR_BLOCKS; ++ uncorr_reg = CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS; ++ } else { ++ corr_reg = CGXX_SPUX_RSFEC_CORR; ++ uncorr_reg = CGXX_SPUX_RSFEC_UNCORR; ++ } ++ for (stats = 0; stats < fec_stats_count; stats++) { ++ rsp->fec_corr_blks += ++ cgx_read(cgx, lmac_id, corr_reg + (stats * 8)); ++ rsp->fec_uncorr_blks += ++ cgx_read(cgx, lmac_id, uncorr_reg + (stats * 8)); ++ } ++ return 0; ++} ++ + int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable) + { + struct cgx *cgx = cgxd; +@@ -620,6 +674,7 @@ static inline void link_status_user_format(u64 lstat, + linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat); + linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat); + linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)]; ++ linfo->fec = FIELD_GET(RESP_LINKSTAT_FEC, lstat); + linfo->lmac_type_id = cgx_get_lmac_type(cgx, lmac_id); + lmac_string = cgx_lmactype_string[linfo->lmac_type_id]; + strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1); +@@ -790,6 +845,27 @@ int cgx_get_fwdata_base(u64 *base) + return err; + } + ++int cgx_set_fec(u64 fec, int cgx_id, int lmac_id) ++{ ++ u64 req = 0, resp; ++ struct cgx *cgx; ++ int err = 0; ++ ++ cgx = cgx_get_pdata(cgx_id); ++ if (!cgx) ++ return -ENXIO; ++ ++ req = FIELD_SET(CMDREG_ID, CGX_CMD_SET_FEC, req); ++ req = FIELD_SET(CMDSETFEC, fec, req); ++ err = cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id); ++ if (err) ++ return err; ++ ++ cgx->lmac_idmap[lmac_id]->link_info.fec = ++ FIELD_GET(RESP_LINKSTAT_FEC, resp); ++ return cgx->lmac_idmap[lmac_id]->link_info.fec; ++} ++ + static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable) + { + u64 req = 0; +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h +index e176a6c654ef2..6295a6963ff78 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h +@@ -55,6 +55,11 @@ + #define CGXX_SCRATCH1_REG 0x1058 + #define CGX_CONST 0x2000 + #define CGXX_SPUX_CONTROL1 0x10000 ++#define CGXX_SPUX_LNX_FEC_CORR_BLOCKS 0x10700 ++#define CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS 0x10800 ++#define CGXX_SPUX_RSFEC_CORR 0x10088 ++#define CGXX_SPUX_RSFEC_UNCORR 0x10090 ++ + #define CGXX_SPUX_CONTROL1_LBK BIT_ULL(14) + #define CGXX_GMP_PCS_MRX_CTL 0x30000 + #define CGXX_GMP_PCS_MRX_CTL_LBK BIT_ULL(14) +@@ -146,5 +151,7 @@ int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id, + u8 tx_pause, u8 rx_pause); + void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable); + u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id); ++int cgx_set_fec(u64 fec, int cgx_id, int lmac_id); ++int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp); + + #endif /* CGX_H */ +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h +index c3702fa58b6bd..3485596c0ed6c 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h +@@ -81,6 +81,14 @@ enum cgx_cmd_id { + CGX_CMD_GET_MKEX_PRFL_SIZE, + CGX_CMD_GET_MKEX_PRFL_ADDR, + CGX_CMD_GET_FWD_BASE, /* get base address of shared FW data */ ++ CGX_CMD_GET_LINK_MODES, /* Supported Link Modes */ ++ CGX_CMD_SET_LINK_MODE, ++ CGX_CMD_GET_SUPPORTED_FEC, ++ CGX_CMD_SET_FEC, ++ CGX_CMD_GET_AN, ++ CGX_CMD_SET_AN, ++ CGX_CMD_GET_ADV_LINK_MODES, ++ CGX_CMD_GET_ADV_FEC, + }; + + /* async event ids */ +@@ -171,13 +179,19 @@ struct cgx_lnk_sts { + uint64_t full_duplex:1; + uint64_t speed:4; /* cgx_link_speed */ + uint64_t err_type:10; +- uint64_t reserved2:39; ++ uint64_t an:1; /* AN supported or not */ ++ uint64_t fec:2; /* FEC type if enabled, if not 0 */ ++ uint64_t port:8; ++ uint64_t reserved2:28; + }; + + #define RESP_LINKSTAT_UP GENMASK_ULL(9, 9) + #define RESP_LINKSTAT_FDUPLEX GENMASK_ULL(10, 10) + #define RESP_LINKSTAT_SPEED GENMASK_ULL(14, 11) + #define RESP_LINKSTAT_ERRTYPE GENMASK_ULL(24, 15) ++#define RESP_LINKSTAT_AN GENMASK_ULL(25, 25) ++#define RESP_LINKSTAT_FEC GENMASK_ULL(27, 26) ++#define RESP_LINKSTAT_PORT GENMASK_ULL(35, 28) + + /* scratchx(1) CSR used for non-secure SW->ATF communication + * This CSR acts as a command register +@@ -199,4 +213,5 @@ struct cgx_lnk_sts { + #define CMDLINKCHANGE_FULLDPLX BIT_ULL(9) + #define CMDLINKCHANGE_SPEED GENMASK_ULL(13, 10) + ++#define CMDSETFEC GENMASK_ULL(9, 8) + #endif /* __CGX_FW_INTF_H__ */ +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +index f46de8419b770..9a135d1cf102d 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +@@ -36,7 +36,7 @@ + + #define INTR_MASK(pfvfs) ((pfvfs < 64) ? (BIT_ULL(pfvfs) - 1) : (~0ull)) + +-#define MBOX_RSP_TIMEOUT 2000 /* Time(ms) to wait for mbox response */ ++#define MBOX_RSP_TIMEOUT 3000 /* Time(ms) to wait for mbox response */ + + #define MBOX_MSG_ALIGN 16 /* Align mbox msg start to 16bytes */ + +@@ -149,6 +149,9 @@ M(CGX_PTP_RX_ENABLE, 0x20C, cgx_ptp_rx_enable, msg_req, msg_rsp) \ + M(CGX_PTP_RX_DISABLE, 0x20D, cgx_ptp_rx_disable, msg_req, msg_rsp) \ + M(CGX_CFG_PAUSE_FRM, 0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg, \ + cgx_pause_frm_cfg) \ ++M(CGX_FEC_SET, 0x210, cgx_set_fec_param, fec_mode, fec_mode) \ ++M(CGX_FEC_STATS, 0x211, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \ ++ /* NPA mbox IDs (range 0x400 - 0x5FF) */ \ + /* NPA mbox IDs (range 0x400 - 0x5FF) */ \ + M(NPA_LF_ALLOC, 0x400, npa_lf_alloc, \ + npa_lf_alloc_req, npa_lf_alloc_rsp) \ +@@ -346,6 +349,11 @@ struct cgx_stats_rsp { + u64 tx_stats[CGX_TX_STATS_COUNT]; + }; + ++struct cgx_fec_stats_rsp { ++ struct mbox_msghdr hdr; ++ u64 fec_corr_blks; ++ u64 fec_uncorr_blks; ++}; + /* Structure for requesting the operation for + * setting/getting mac address in the CGX interface + */ +@@ -359,6 +367,7 @@ struct cgx_link_user_info { + uint64_t full_duplex:1; + uint64_t lmac_type_id:4; + uint64_t speed:20; /* speed in Mbps */ ++ uint64_t fec:2; /* FEC type if enabled else 0 */ + #define LMACTYPE_STR_LEN 16 + char lmac_type[LMACTYPE_STR_LEN]; + }; +@@ -377,6 +386,19 @@ struct cgx_pause_frm_cfg { + u8 tx_pause; + }; + ++enum fec_type { ++ OTX2_FEC_NONE, ++ OTX2_FEC_BASER, ++ OTX2_FEC_RS, ++ OTX2_FEC_STATS_CNT = 2, ++ OTX2_FEC_OFF, ++}; ++ ++struct fec_mode { ++ struct mbox_msghdr hdr; ++ int fec; ++}; ++ + /* NPA mbox message formats */ + + /* NPA mailbox error codes +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +index 83743e15326d7..05ef3a104748a 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +@@ -462,6 +462,22 @@ int rvu_mbox_handler_cgx_stats(struct rvu *rvu, struct msg_req *req, + return 0; + } + ++int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu, ++ struct msg_req *req, ++ struct cgx_fec_stats_rsp *rsp) ++{ ++ int pf = rvu_get_pf(req->hdr.pcifunc); ++ u8 cgx_idx, lmac; ++ void *cgxd; ++ ++ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc)) ++ return -EPERM; ++ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac); ++ ++ cgxd = rvu_cgx_pdata(cgx_idx, rvu); ++ return cgx_get_fec_stats(cgxd, lmac, rsp); ++} ++ + int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu, + struct cgx_mac_addr_set_or_get *req, + struct cgx_mac_addr_set_or_get *rsp) +@@ -767,3 +783,20 @@ int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start) + mutex_unlock(&rvu->cgx_cfg_lock); + return err; + } ++ ++int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu, ++ struct fec_mode *req, ++ struct fec_mode *rsp) ++{ ++ int pf = rvu_get_pf(req->hdr.pcifunc); ++ u8 cgx_id, lmac_id; ++ ++ if (!is_pf_cgxmapped(rvu, pf)) ++ return -EPERM; ++ ++ if (req->fec == OTX2_FEC_OFF) ++ req->fec = OTX2_FEC_NONE; ++ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); ++ rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id); ++ return 0; ++} +-- +2.43.0 + diff --git a/queue-5.10/octeontx2-af-mbox-changes-for-98xx.patch b/queue-5.10/octeontx2-af-mbox-changes-for-98xx.patch new file mode 100644 index 00000000000..33924353f23 --- /dev/null +++ b/queue-5.10/octeontx2-af-mbox-changes-for-98xx.patch @@ -0,0 +1,369 @@ +From 0134afea263b93be1f06b859e161a186fb1e1fa4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Oct 2020 10:45:46 +0530 +Subject: octeontx2-af: Mbox changes for 98xx + +From: Subbaraya Sundeep + +[ Upstream commit a84cdcea3b4feb46730c88454b5f85e828429c2b ] + +This patch puts together all mailbox changes +for 98xx silicon: + +Attach -> +Modify resource attach mailbox handler to +request LFs from a block address out of multiple +blocks of same type. If a PF/VF need LFs from two +blocks of same type then attach mbox should be +called twice. + +Example: + struct rsrc_attach *attach; + .. Allocate memory for message .. + attach->cptlfs = 3; /* 3 LFs from CPT0 */ + .. Send message .. + .. Allocate memory for message .. + attach->modify = 1; + attach->cpt_blkaddr = BLKADDR_CPT1; + attach->cptlfs = 2; /* 2 LFs from CPT1 */ + .. Send message .. + +Detach -> +Update detach mailbox and its handler to detach +resources from CPT1 and NIX1 blocks. + +MSIX -> +Updated the MSIX mailbox and its handler to return +MSIX offsets for the new block CPT1. + +Free resources -> +Update free_rsrc mailbox and its handler to return +the free resources count of new blocks NIX1 and CPT1 + +Links -> +Number of CGX,LBK and SDP links may vary between +platforms. For example, in 98xx number of CGX and LBK +links are more than 96xx. Hence the info about number +of links present in hardware is useful for consumers to +request link configuration properly. This patch sends +this info in nix_lf_alloc_rsp. + +Signed-off-by: Subbaraya Sundeep +Signed-off-by: Sunil Goutham +Signed-off-by: Rakesh Babu +Signed-off-by: Jakub Kicinski +Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/marvell/octeontx2/af/mbox.h | 19 ++++- + .../net/ethernet/marvell/octeontx2/af/rvu.c | 85 +++++++++++++++---- + .../ethernet/marvell/octeontx2/af/rvu_nix.c | 4 + + .../ethernet/marvell/octeontx2/af/rvu_reg.c | 2 +- + .../marvell/octeontx2/af/rvu_struct.h | 2 + + 5 files changed, 94 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +index 263a211294168..f46de8419b770 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +@@ -86,7 +86,7 @@ struct mbox_msghdr { + #define OTX2_MBOX_REQ_SIG (0xdead) + #define OTX2_MBOX_RSP_SIG (0xbeef) + u16 sig; /* Signature, for validating corrupted msgs */ +-#define OTX2_MBOX_VERSION (0x0001) ++#define OTX2_MBOX_VERSION (0x0007) + u16 ver; /* Version of msg's structure for this ID */ + u16 next_msgoff; /* Offset of next msg within mailbox region */ + int rc; /* Msg process'ed response code */ +@@ -271,6 +271,17 @@ struct ready_msg_rsp { + * or to detach partial of a cetain resource type. + * Rest of the fields specify how many of what type to + * be attached. ++ * To request LFs from two blocks of same type this mailbox ++ * can be sent twice as below: ++ * struct rsrc_attach *attach; ++ * .. Allocate memory for message .. ++ * attach->cptlfs = 3; <3 LFs from CPT0> ++ * .. Send message .. ++ * .. Allocate memory for message .. ++ * attach->modify = 1; ++ * attach->cpt_blkaddr = BLKADDR_CPT1; ++ * attach->cptlfs = 2; <2 LFs from CPT1> ++ * .. Send message .. + */ + struct rsrc_attach { + struct mbox_msghdr hdr; +@@ -281,6 +292,7 @@ struct rsrc_attach { + u16 ssow; + u16 timlfs; + u16 cptlfs; ++ int cpt_blkaddr; /* BLKADDR_CPT0/BLKADDR_CPT1 or 0 for BLKADDR_CPT0 */ + }; + + /* Structure for relinquishing resources. +@@ -314,6 +326,8 @@ struct msix_offset_rsp { + u16 ssow_msixoff[MAX_RVU_BLKLF_CNT]; + u16 timlf_msixoff[MAX_RVU_BLKLF_CNT]; + u16 cptlf_msixoff[MAX_RVU_BLKLF_CNT]; ++ u8 cpt1_lfs; ++ u16 cpt1_lf_msixoff[MAX_RVU_BLKLF_CNT]; + }; + + struct get_hw_cap_rsp { +@@ -491,6 +505,9 @@ struct nix_lf_alloc_rsp { + u8 lf_tx_stats; /* NIX_AF_CONST1::LF_TX_STATS */ + u16 cints; /* NIX_AF_CONST2::CINTS */ + u16 qints; /* NIX_AF_CONST2::QINTS */ ++ u8 cgx_links; /* No. of CGX links present in HW */ ++ u8 lbk_links; /* No. of LBK links present in HW */ ++ u8 sdp_links; /* No. of SDP links present in HW */ + }; + + /* NIX AQ enqueue msg */ +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +index e8a2552fb690a..78309821ce298 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +@@ -1185,6 +1185,8 @@ static int rvu_detach_rsrcs(struct rvu *rvu, struct rsrc_detach *detach, + continue; + else if ((blkid == BLKADDR_NIX0) && !detach->nixlf) + continue; ++ else if ((blkid == BLKADDR_NIX1) && !detach->nixlf) ++ continue; + else if ((blkid == BLKADDR_SSO) && !detach->sso) + continue; + else if ((blkid == BLKADDR_SSOW) && !detach->ssow) +@@ -1193,6 +1195,8 @@ static int rvu_detach_rsrcs(struct rvu *rvu, struct rsrc_detach *detach, + continue; + else if ((blkid == BLKADDR_CPT0) && !detach->cptlfs) + continue; ++ else if ((blkid == BLKADDR_CPT1) && !detach->cptlfs) ++ continue; + } + rvu_detach_block(rvu, pcifunc, block->type); + } +@@ -1242,7 +1246,8 @@ static int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc) + return pfvf->nix_blkaddr; + } + +-static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc) ++static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, ++ u16 pcifunc, struct rsrc_attach *attach) + { + int blkaddr; + +@@ -1250,6 +1255,14 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc) + case BLKTYPE_NIX: + blkaddr = rvu_get_nix_blkaddr(rvu, pcifunc); + break; ++ case BLKTYPE_CPT: ++ if (attach->hdr.ver < RVU_MULTI_BLK_VER) ++ return rvu_get_blkaddr(rvu, blktype, 0); ++ blkaddr = attach->cpt_blkaddr ? attach->cpt_blkaddr : ++ BLKADDR_CPT0; ++ if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1) ++ return -ENODEV; ++ break; + default: + return rvu_get_blkaddr(rvu, blktype, 0); + }; +@@ -1260,8 +1273,8 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc) + return -ENODEV; + } + +-static void rvu_attach_block(struct rvu *rvu, int pcifunc, +- int blktype, int num_lfs) ++static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype, ++ int num_lfs, struct rsrc_attach *attach) + { + struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); + struct rvu_hwinfo *hw = rvu->hw; +@@ -1273,7 +1286,7 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, + if (!num_lfs) + return; + +- blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc); ++ blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc, attach); + if (blkaddr < 0) + return; + +@@ -1321,7 +1334,8 @@ static int rvu_check_rsrc_availability(struct rvu *rvu, + + /* Only one NIX LF can be attached */ + if (req->nixlf && !is_blktype_attached(pfvf, BLKTYPE_NIX)) { +- blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_NIX, pcifunc); ++ blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_NIX, ++ pcifunc, req); + if (blkaddr < 0) + return blkaddr; + block = &hw->block[blkaddr]; +@@ -1383,7 +1397,11 @@ static int rvu_check_rsrc_availability(struct rvu *rvu, + } + + if (req->cptlfs) { +- block = &hw->block[BLKADDR_CPT0]; ++ blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_CPT, ++ pcifunc, req); ++ if (blkaddr < 0) ++ return blkaddr; ++ block = &hw->block[blkaddr]; + if (req->cptlfs > block->lf.max) { + dev_err(&rvu->pdev->dev, + "Func 0x%x: Invalid CPTLF req, %d > max %d\n", +@@ -1404,6 +1422,22 @@ static int rvu_check_rsrc_availability(struct rvu *rvu, + return -ENOSPC; + } + ++static bool rvu_attach_from_same_block(struct rvu *rvu, int blktype, ++ struct rsrc_attach *attach) ++{ ++ int blkaddr, num_lfs; ++ ++ blkaddr = rvu_get_attach_blkaddr(rvu, blktype, ++ attach->hdr.pcifunc, attach); ++ if (blkaddr < 0) ++ return false; ++ ++ num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, attach->hdr.pcifunc), ++ blkaddr); ++ /* Requester already has LFs from given block ? */ ++ return !!num_lfs; ++} ++ + int rvu_mbox_handler_attach_resources(struct rvu *rvu, + struct rsrc_attach *attach, + struct msg_rsp *rsp) +@@ -1424,10 +1458,10 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, + + /* Now attach the requested resources */ + if (attach->npalf) +- rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1); ++ rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach); + + if (attach->nixlf) +- rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1); ++ rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach); + + if (attach->sso) { + /* RVU func doesn't know which exact LF or slot is attached +@@ -1437,25 +1471,30 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, + */ + if (attach->modify) + rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO); +- rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO, attach->sso); ++ rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO, ++ attach->sso, attach); + } + + if (attach->ssow) { + if (attach->modify) + rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW); +- rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW, attach->ssow); ++ rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW, ++ attach->ssow, attach); + } + + if (attach->timlfs) { + if (attach->modify) + rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM); +- rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM, attach->timlfs); ++ rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM, ++ attach->timlfs, attach); + } + + if (attach->cptlfs) { +- if (attach->modify) ++ if (attach->modify && ++ rvu_attach_from_same_block(rvu, BLKTYPE_CPT, attach)) + rvu_detach_block(rvu, pcifunc, BLKTYPE_CPT); +- rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT, attach->cptlfs); ++ rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT, ++ attach->cptlfs, attach); + } + + exit: +@@ -1533,7 +1572,7 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req, + struct rvu_hwinfo *hw = rvu->hw; + u16 pcifunc = req->hdr.pcifunc; + struct rvu_pfvf *pfvf; +- int lf, slot; ++ int lf, slot, blkaddr; + + pfvf = rvu_get_pfvf(rvu, pcifunc); + if (!pfvf->msix.bmap) +@@ -1543,8 +1582,14 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req, + lf = rvu_get_lf(rvu, &hw->block[BLKADDR_NPA], pcifunc, 0); + rsp->npa_msixoff = rvu_get_msix_offset(rvu, pfvf, BLKADDR_NPA, lf); + +- lf = rvu_get_lf(rvu, &hw->block[BLKADDR_NIX0], pcifunc, 0); +- rsp->nix_msixoff = rvu_get_msix_offset(rvu, pfvf, BLKADDR_NIX0, lf); ++ /* Get BLKADDR from which LFs are attached to pcifunc */ ++ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc); ++ if (blkaddr < 0) { ++ rsp->nix_msixoff = MSIX_VECTOR_INVALID; ++ } else { ++ lf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0); ++ rsp->nix_msixoff = rvu_get_msix_offset(rvu, pfvf, blkaddr, lf); ++ } + + rsp->sso = pfvf->sso; + for (slot = 0; slot < rsp->sso; slot++) { +@@ -1573,6 +1618,14 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req, + rsp->cptlf_msixoff[slot] = + rvu_get_msix_offset(rvu, pfvf, BLKADDR_CPT0, lf); + } ++ ++ rsp->cpt1_lfs = pfvf->cpt1_lfs; ++ for (slot = 0; slot < rsp->cpt1_lfs; slot++) { ++ lf = rvu_get_lf(rvu, &hw->block[BLKADDR_CPT1], pcifunc, slot); ++ rsp->cpt1_lf_msixoff[slot] = ++ rvu_get_msix_offset(rvu, pfvf, BLKADDR_CPT1, lf); ++ } ++ + return 0; + } + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +index fb4b18be503c5..0a69d326f618c 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +@@ -1179,6 +1179,10 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, + cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2); + rsp->qints = ((cfg >> 12) & 0xFFF); + rsp->cints = ((cfg >> 24) & 0xFFF); ++ rsp->cgx_links = hw->cgx_links; ++ rsp->lbk_links = hw->lbk_links; ++ rsp->sdp_links = hw->sdp_links; ++ + return rc; + } + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c +index 9d7c135c79659..e266f0c495595 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c +@@ -35,7 +35,7 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = { + {0x1200, 0x12E0} } }, + {NIX_TXSCH_LVL_TL3, 3, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608}, + {0x1610, 0x1618} } }, +- {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x1768} } }, ++ {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } }, + {NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } }, + }; + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h +index a3ecb5de90005..761e8e9f5299c 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h +@@ -14,6 +14,8 @@ + /* RVU Block revision IDs */ + #define RVU_BLK_RVUM_REVID 0x01 + ++#define RVU_MULTI_BLK_VER 0x7ULL ++ + /* RVU Block Address Enumeration */ + enum rvu_block_addr_e { + BLKADDR_RVUM = 0x0ULL, +-- +2.43.0 + diff --git a/queue-5.10/octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch b/queue-5.10/octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch new file mode 100644 index 00000000000..1beacc85cbe --- /dev/null +++ b/queue-5.10/octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch @@ -0,0 +1,67 @@ +From 2feee6ff37720b99b3afe4cba72f65f8ff750041 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Oct 2020 10:45:47 +0530 +Subject: octeontx2-pf: Calculate LBK link instead of hardcoding + +From: Subbaraya Sundeep + +[ Upstream commit 8bcf5ced6526e1c4c8a2703f9ca9135fef7409d6 ] + +CGX links are followed by LBK links but number of +CGX and LBK links varies between platforms. Hence +get the number of links present in hardware from +AF and use it to calculate LBK link number. + +Signed-off-by: Subbaraya Sundeep +Signed-off-by: Sunil Goutham +Signed-off-by: Rakesh Babu +Signed-off-by: Jakub Kicinski +Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 8 ++++++-- + drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 2 ++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +index b062ed06235d2..3b4530bc30378 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +@@ -532,8 +532,10 @@ static int otx2_get_link(struct otx2_nic *pfvf) + link = 4 * ((map >> 8) & 0xF) + ((map >> 4) & 0xF); + } + /* LBK channel */ +- if (pfvf->hw.tx_chan_base < SDP_CHAN_BASE) +- link = 12; ++ if (pfvf->hw.tx_chan_base < SDP_CHAN_BASE) { ++ map = pfvf->hw.tx_chan_base & 0x7FF; ++ link = pfvf->hw.cgx_links | ((map >> 8) & 0xF); ++ } + + return link; + } +@@ -1519,6 +1521,8 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf, + pfvf->hw.tx_chan_base = rsp->tx_chan_base; + pfvf->hw.lso_tsov4_idx = rsp->lso_tsov4_idx; + pfvf->hw.lso_tsov6_idx = rsp->lso_tsov6_idx; ++ pfvf->hw.cgx_links = rsp->cgx_links; ++ pfvf->hw.lbk_links = rsp->lbk_links; + } + EXPORT_SYMBOL(mbox_handler_nix_lf_alloc); + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +index d6253f2a414d3..386cb08497e48 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +@@ -197,6 +197,8 @@ struct otx2_hw { + struct otx2_drv_stats drv_stats; + u64 cgx_rx_stats[CGX_RX_STATS_COUNT]; + u64 cgx_tx_stats[CGX_TX_STATS_COUNT]; ++ u8 cgx_links; /* No. of CGX links present in HW */ ++ u8 lbk_links; /* No. of LBK links present in HW */ + }; + + struct otx2_vf_config { +-- +2.43.0 + diff --git a/queue-5.10/octeontx2-pf-ethtool-fec-mode-support.patch b/queue-5.10/octeontx2-pf-ethtool-fec-mode-support.patch new file mode 100644 index 00000000000..f8f00110c72 --- /dev/null +++ b/queue-5.10/octeontx2-pf-ethtool-fec-mode-support.patch @@ -0,0 +1,337 @@ +From ad5f297a3dbe436e02aa4297b20cb343530928b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Feb 2021 16:05:27 +0530 +Subject: octeontx2-pf: ethtool fec mode support + +From: Christina Jacob + +[ Upstream commit d0cf9503e908ee7b235a5efecedeb74aabc482f3 ] + +Add ethtool support to configure fec modes baser/rs and +support to fecth FEC stats from CGX as well PHY. + +Configure fec mode + - ethtool --set-fec eth0 encoding rs/baser/off/auto +Query fec mode + - ethtool --show-fec eth0 + +Signed-off-by: Christina Jacob +Signed-off-by: Sunil Goutham +Signed-off-by: Hariprasad Kelam +Reviewed-by: Jesse Brandeburg +Signed-off-by: David S. Miller +Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c") +Signed-off-by: Sasha Levin +--- + .../marvell/octeontx2/nic/otx2_common.c | 20 +++ + .../marvell/octeontx2/nic/otx2_common.h | 6 + + .../marvell/octeontx2/nic/otx2_ethtool.c | 160 +++++++++++++++++- + .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 3 + + 4 files changed, 188 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +index 3b4530bc30378..2b6baf0ad3f7d 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +@@ -60,6 +60,19 @@ void otx2_update_lmac_stats(struct otx2_nic *pfvf) + mutex_unlock(&pfvf->mbox.lock); + } + ++void otx2_update_lmac_fec_stats(struct otx2_nic *pfvf) ++{ ++ struct msg_req *req; ++ ++ if (!netif_running(pfvf->netdev)) ++ return; ++ mutex_lock(&pfvf->mbox.lock); ++ req = otx2_mbox_alloc_msg_cgx_fec_stats(&pfvf->mbox); ++ if (req) ++ otx2_sync_mbox_msg(&pfvf->mbox); ++ mutex_unlock(&pfvf->mbox.lock); ++} ++ + int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx) + { + struct otx2_rcv_queue *rq = &pfvf->qset.rq[qidx]; +@@ -1492,6 +1505,13 @@ void mbox_handler_cgx_stats(struct otx2_nic *pfvf, + pfvf->hw.cgx_tx_stats[id] = rsp->tx_stats[id]; + } + ++void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf, ++ struct cgx_fec_stats_rsp *rsp) ++{ ++ pfvf->hw.cgx_fec_corr_blks += rsp->fec_corr_blks; ++ pfvf->hw.cgx_fec_uncorr_blks += rsp->fec_uncorr_blks; ++} ++ + void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf, + struct nix_txsch_alloc_rsp *rsp) + { +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +index 386cb08497e48..866b1a2cc9a12 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +@@ -197,6 +197,8 @@ struct otx2_hw { + struct otx2_drv_stats drv_stats; + u64 cgx_rx_stats[CGX_RX_STATS_COUNT]; + u64 cgx_tx_stats[CGX_TX_STATS_COUNT]; ++ u64 cgx_fec_corr_blks; ++ u64 cgx_fec_uncorr_blks; + u8 cgx_links; /* No. of CGX links present in HW */ + u8 lbk_links; /* No. of LBK links present in HW */ + }; +@@ -627,6 +629,9 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf, + struct nix_txsch_alloc_rsp *rsp); + void mbox_handler_cgx_stats(struct otx2_nic *pfvf, + struct cgx_stats_rsp *rsp); ++void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf, ++ struct cgx_fec_stats_rsp *rsp); ++void otx2_set_fec_stats_count(struct otx2_nic *pfvf); + void mbox_handler_nix_bp_enable(struct otx2_nic *pfvf, + struct nix_bp_cfg_rsp *rsp); + +@@ -635,6 +640,7 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf); + void otx2_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats); + void otx2_update_lmac_stats(struct otx2_nic *pfvf); ++void otx2_update_lmac_fec_stats(struct otx2_nic *pfvf); + int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx); + int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx); + void otx2_set_ethtool_ops(struct net_device *netdev); +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +index fc4ca8246df24..540a16d0a3274 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +@@ -66,6 +66,8 @@ static const unsigned int otx2_n_dev_stats = ARRAY_SIZE(otx2_dev_stats); + static const unsigned int otx2_n_drv_stats = ARRAY_SIZE(otx2_drv_stats); + static const unsigned int otx2_n_queue_stats = ARRAY_SIZE(otx2_queue_stats); + ++static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf); ++ + static void otx2_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) + { +@@ -128,6 +130,10 @@ static void otx2_get_strings(struct net_device *netdev, u32 sset, u8 *data) + + strcpy(data, "reset_count"); + data += ETH_GSTRING_LEN; ++ sprintf(data, "Fec Corrected Errors: "); ++ data += ETH_GSTRING_LEN; ++ sprintf(data, "Fec Uncorrected Errors: "); ++ data += ETH_GSTRING_LEN; + } + + static void otx2_get_qset_stats(struct otx2_nic *pfvf, +@@ -160,11 +166,30 @@ static void otx2_get_qset_stats(struct otx2_nic *pfvf, + } + } + ++static int otx2_get_phy_fec_stats(struct otx2_nic *pfvf) ++{ ++ struct msg_req *req; ++ int rc = -ENOMEM; ++ ++ mutex_lock(&pfvf->mbox.lock); ++ req = otx2_mbox_alloc_msg_cgx_get_phy_fec_stats(&pfvf->mbox); ++ if (!req) ++ goto end; ++ ++ if (!otx2_sync_mbox_msg(&pfvf->mbox)) ++ rc = 0; ++end: ++ mutex_unlock(&pfvf->mbox.lock); ++ return rc; ++} ++ + /* Get device and per queue statistics */ + static void otx2_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, u64 *data) + { + struct otx2_nic *pfvf = netdev_priv(netdev); ++ u64 fec_corr_blks, fec_uncorr_blks; ++ struct cgx_fw_data *rsp; + int stat; + + otx2_get_dev_stats(pfvf); +@@ -183,6 +208,32 @@ static void otx2_get_ethtool_stats(struct net_device *netdev, + for (stat = 0; stat < CGX_TX_STATS_COUNT; stat++) + *(data++) = pfvf->hw.cgx_tx_stats[stat]; + *(data++) = pfvf->reset_count; ++ ++ fec_corr_blks = pfvf->hw.cgx_fec_corr_blks; ++ fec_uncorr_blks = pfvf->hw.cgx_fec_uncorr_blks; ++ ++ rsp = otx2_get_fwdata(pfvf); ++ if (!IS_ERR(rsp) && rsp->fwdata.phy.misc.has_fec_stats && ++ !otx2_get_phy_fec_stats(pfvf)) { ++ /* Fetch fwdata again because it's been recently populated with ++ * latest PHY FEC stats. ++ */ ++ rsp = otx2_get_fwdata(pfvf); ++ if (!IS_ERR(rsp)) { ++ struct fec_stats_s *p = &rsp->fwdata.phy.fec_stats; ++ ++ if (pfvf->linfo.fec == OTX2_FEC_BASER) { ++ fec_corr_blks = p->brfec_corr_blks; ++ fec_uncorr_blks = p->brfec_uncorr_blks; ++ } else { ++ fec_corr_blks = p->rsfec_corr_cws; ++ fec_uncorr_blks = p->rsfec_uncorr_cws; ++ } ++ } ++ } ++ ++ *(data++) = fec_corr_blks; ++ *(data++) = fec_uncorr_blks; + } + + static int otx2_get_sset_count(struct net_device *netdev, int sset) +@@ -195,9 +246,11 @@ static int otx2_get_sset_count(struct net_device *netdev, int sset) + + qstats_count = otx2_n_queue_stats * + (pfvf->hw.rx_queues + pfvf->hw.tx_queues); ++ otx2_update_lmac_fec_stats(pfvf); + + return otx2_n_dev_stats + otx2_n_drv_stats + qstats_count + +- CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT + 1; ++ CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT + OTX2_FEC_STATS_CNT ++ + 1; + } + + /* Get no of queues device supports and current queue count */ +@@ -700,6 +753,109 @@ static int otx2_get_ts_info(struct net_device *netdev, + return 0; + } + ++static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf) ++{ ++ struct cgx_fw_data *rsp = NULL; ++ struct msg_req *req; ++ int err = 0; ++ ++ mutex_lock(&pfvf->mbox.lock); ++ req = otx2_mbox_alloc_msg_cgx_get_aux_link_info(&pfvf->mbox); ++ if (!req) { ++ mutex_unlock(&pfvf->mbox.lock); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ err = otx2_sync_mbox_msg(&pfvf->mbox); ++ if (!err) { ++ rsp = (struct cgx_fw_data *) ++ otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr); ++ } else { ++ rsp = ERR_PTR(err); ++ } ++ ++ mutex_unlock(&pfvf->mbox.lock); ++ return rsp; ++} ++ ++static int otx2_get_fecparam(struct net_device *netdev, ++ struct ethtool_fecparam *fecparam) ++{ ++ struct otx2_nic *pfvf = netdev_priv(netdev); ++ struct cgx_fw_data *rsp; ++ const int fec[] = { ++ ETHTOOL_FEC_OFF, ++ ETHTOOL_FEC_BASER, ++ ETHTOOL_FEC_RS, ++ ETHTOOL_FEC_BASER | ETHTOOL_FEC_RS}; ++#define FEC_MAX_INDEX 4 ++ if (pfvf->linfo.fec < FEC_MAX_INDEX) ++ fecparam->active_fec = fec[pfvf->linfo.fec]; ++ ++ rsp = otx2_get_fwdata(pfvf); ++ if (IS_ERR(rsp)) ++ return PTR_ERR(rsp); ++ ++ if (rsp->fwdata.supported_fec <= FEC_MAX_INDEX) { ++ if (!rsp->fwdata.supported_fec) ++ fecparam->fec = ETHTOOL_FEC_NONE; ++ else ++ fecparam->fec = fec[rsp->fwdata.supported_fec]; ++ } ++ return 0; ++} ++ ++static int otx2_set_fecparam(struct net_device *netdev, ++ struct ethtool_fecparam *fecparam) ++{ ++ struct otx2_nic *pfvf = netdev_priv(netdev); ++ struct mbox *mbox = &pfvf->mbox; ++ struct fec_mode *req, *rsp; ++ int err = 0, fec = 0; ++ ++ switch (fecparam->fec) { ++ /* Firmware does not support AUTO mode consider it as FEC_OFF */ ++ case ETHTOOL_FEC_OFF: ++ case ETHTOOL_FEC_AUTO: ++ fec = OTX2_FEC_OFF; ++ break; ++ case ETHTOOL_FEC_RS: ++ fec = OTX2_FEC_RS; ++ break; ++ case ETHTOOL_FEC_BASER: ++ fec = OTX2_FEC_BASER; ++ break; ++ default: ++ netdev_warn(pfvf->netdev, "Unsupported FEC mode: %d", ++ fecparam->fec); ++ return -EINVAL; ++ } ++ ++ if (fec == pfvf->linfo.fec) ++ return 0; ++ ++ mutex_lock(&mbox->lock); ++ req = otx2_mbox_alloc_msg_cgx_set_fec_param(&pfvf->mbox); ++ if (!req) { ++ err = -ENOMEM; ++ goto end; ++ } ++ req->fec = fec; ++ err = otx2_sync_mbox_msg(&pfvf->mbox); ++ if (err) ++ goto end; ++ ++ rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox, ++ 0, &req->hdr); ++ if (rsp->fec >= 0) ++ pfvf->linfo.fec = rsp->fec; ++ else ++ err = rsp->fec; ++end: ++ mutex_unlock(&mbox->lock); ++ return err; ++} ++ + static const struct ethtool_ops otx2_ethtool_ops = { + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | + ETHTOOL_COALESCE_MAX_FRAMES, +@@ -725,6 +881,8 @@ static const struct ethtool_ops otx2_ethtool_ops = { + .get_pauseparam = otx2_get_pauseparam, + .set_pauseparam = otx2_set_pauseparam, + .get_ts_info = otx2_get_ts_info, ++ .get_fecparam = otx2_get_fecparam, ++ .set_fecparam = otx2_set_fecparam, + }; + + void otx2_set_ethtool_ops(struct net_device *netdev) +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +index aada28868ac59..1516f24837754 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +@@ -787,6 +787,9 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf, + case MBOX_MSG_CGX_STATS: + mbox_handler_cgx_stats(pf, (struct cgx_stats_rsp *)msg); + break; ++ case MBOX_MSG_CGX_FEC_STATS: ++ mbox_handler_cgx_fec_stats(pf, (struct cgx_fec_stats_rsp *)msg); ++ break; + default: + if (msg->rc) + dev_err(pf->dev, +-- +2.43.0 + diff --git a/queue-5.10/octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch b/queue-5.10/octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch new file mode 100644 index 00000000000..6088cdc8b5e --- /dev/null +++ b/queue-5.10/octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch @@ -0,0 +1,52 @@ +From ae3cee96bd1ff3baa6d878e124408f950487ab6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Oct 2024 19:02:29 +0000 +Subject: octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c + +From: Dipendra Khadka + +[ Upstream commit e26f8eac6bb20b20fdb8f7dc695711ebce4c7c5c ] + +Add error pointer check after calling otx2_mbox_get_rsp(). + +Fixes: 75f36270990c ("octeontx2-pf: Support to enable/disable pause frames via ethtool") +Fixes: d0cf9503e908 ("octeontx2-pf: ethtool fec mode support") +Signed-off-by: Dipendra Khadka +Reviewed-by: Simon Horman +Signed-off-by: Andrew Lunn +Signed-off-by: Sasha Levin +--- + .../net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +index 540a16d0a3274..3d0c090551e76 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +@@ -317,6 +317,11 @@ static void otx2_get_pauseparam(struct net_device *netdev, + if (!otx2_sync_mbox_msg(&pfvf->mbox)) { + rsp = (struct cgx_pause_frm_cfg *) + otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr); ++ if (IS_ERR(rsp)) { ++ mutex_unlock(&pfvf->mbox.lock); ++ return; ++ } ++ + pause->rx_pause = rsp->rx_pause; + pause->tx_pause = rsp->tx_pause; + } +@@ -847,6 +852,11 @@ static int otx2_set_fecparam(struct net_device *netdev, + + rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox, + 0, &req->hdr); ++ if (IS_ERR(rsp)) { ++ err = PTR_ERR(rsp); ++ goto end; ++ } ++ + if (rsp->fec >= 0) + pfvf->linfo.fec = rsp->fec; + else +-- +2.43.0 + diff --git a/queue-5.10/pci-cpqphp-fix-pcibios_-return-value-confusion.patch b/queue-5.10/pci-cpqphp-fix-pcibios_-return-value-confusion.patch new file mode 100644 index 00000000000..7ee0ca35050 --- /dev/null +++ b/queue-5.10/pci-cpqphp-fix-pcibios_-return-value-confusion.patch @@ -0,0 +1,85 @@ +From 72f820acc9518ecd05c9a9fe879cf531812747bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Oct 2024 12:11:37 +0300 +Subject: PCI: cpqphp: Fix PCIBIOS_* return value confusion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit e2226dbc4a4919d9c8bd9293299b532090bdf020 ] + +Code in and related to PCI_RefinedAccessConfig() has three types of return +type confusion: + + - PCI_RefinedAccessConfig() tests pci_bus_read_config_dword() return value + against -1. + + - PCI_RefinedAccessConfig() returns both -1 and PCIBIOS_* return codes. + + - Callers of PCI_RefinedAccessConfig() only test for -1. + +Make PCI_RefinedAccessConfig() return PCIBIOS_* codes consistently and +adapt callers accordingly. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Link: https://lore.kernel.org/r/20241022091140.3504-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/hotplug/cpqphp_pci.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c +index a20875da4ec70..ce6eb71a63599 100644 +--- a/drivers/pci/hotplug/cpqphp_pci.c ++++ b/drivers/pci/hotplug/cpqphp_pci.c +@@ -135,11 +135,13 @@ int cpqhp_unconfigure_device(struct pci_func *func) + static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value) + { + u32 vendID = 0; ++ int ret; + +- if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1) +- return -1; ++ ret = pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID); ++ if (ret != PCIBIOS_SUCCESSFUL) ++ return PCIBIOS_DEVICE_NOT_FOUND; + if (PCI_POSSIBLE_ERROR(vendID)) +- return -1; ++ return PCIBIOS_DEVICE_NOT_FOUND; + return pci_bus_read_config_dword(bus, devfn, offset, value); + } + +@@ -200,13 +202,15 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_ + { + u16 tdevice; + u32 work; ++ int ret; + u8 tbus; + + ctrl->pci_bus->number = bus_num; + + for (tdevice = 0; tdevice < 0xFF; tdevice++) { + /* Scan for access first */ +- if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) ++ ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work); ++ if (ret) + continue; + dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); + /* Yep we got one. Not a bridge ? */ +@@ -218,7 +222,8 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_ + } + for (tdevice = 0; tdevice < 0xFF; tdevice++) { + /* Scan for access first */ +- if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) ++ ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work); ++ if (ret) + continue; + dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); + /* Yep we got one. bridge ? */ +-- +2.43.0 + diff --git a/queue-5.10/pci-cpqphp-use-pci_possible_error-to-check-config-re.patch b/queue-5.10/pci-cpqphp-use-pci_possible_error-to-check-config-re.patch new file mode 100644 index 00000000000..c1ef48a45f8 --- /dev/null +++ b/queue-5.10/pci-cpqphp-use-pci_possible_error-to-check-config-re.patch @@ -0,0 +1,54 @@ +From 5f5a1f58a25084d7b02671d2e926a514db1b7392 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Aug 2024 14:50:50 +0800 +Subject: PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads + +From: weiyufeng + +[ Upstream commit a18a025c2fb5fbf2d1d0606ea0d7441ac90e9c39 ] + +When config pci_ops.read() can detect failed PCI transactions, the data +returned to the CPU is PCI_ERROR_RESPONSE (~0 or 0xffffffff). + +Obviously a successful PCI config read may *also* return that data if a +config register happens to contain ~0, so it doesn't definitively indicate +an error unless we know the register cannot contain ~0. + +Use PCI_POSSIBLE_ERROR() to check the response we get when we read data +from hardware. This unifies PCI error response checking and makes error +checks consistent and easier to find. + +Link: https://lore.kernel.org/r/b12005c0d57bb9d4c8b486724d078b7bd92f8321.1637243717.git.naveennaidu479@gmail.com +Signed-off-by: Naveen Naidu +Signed-off-by: Bjorn Helgaas +Stable-dep-of: e2226dbc4a49 ("PCI: cpqphp: Fix PCIBIOS_* return value confusion") +Signed-off-by: Sasha Levin +--- + drivers/pci/hotplug/cpqphp_pci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c +index 1b2b3f3b648bc..a20875da4ec70 100644 +--- a/drivers/pci/hotplug/cpqphp_pci.c ++++ b/drivers/pci/hotplug/cpqphp_pci.c +@@ -138,7 +138,7 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 o + + if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1) + return -1; +- if (vendID == 0xffffffff) ++ if (PCI_POSSIBLE_ERROR(vendID)) + return -1; + return pci_bus_read_config_dword(bus, devfn, offset, value); + } +@@ -251,7 +251,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num + *dev_num = tdevice; + ctrl->pci_bus->number = tbus; + pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); +- if (!nobridge || (work == 0xffffffff)) ++ if (!nobridge || PCI_POSSIBLE_ERROR(work)) + return 0; + + dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); +-- +2.43.0 + diff --git a/queue-5.10/perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch b/queue-5.10/perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch new file mode 100644 index 00000000000..1dd7b47f496 --- /dev/null +++ b/queue-5.10/perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch @@ -0,0 +1,121 @@ +From 7667e3e4f0fe845394352ccda50bebacc07d419c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Sep 2024 14:57:32 +0100 +Subject: perf cs-etm: Don't flush when packet_queue fills up + +From: James Clark + +[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ] + +cs_etm__flush(), like cs_etm__sample() is an operation that generates a +sample and then swaps the current with the previous packet. Calling +flush after processing the queues results in two swaps which corrupts +the next sample. Therefore it wasn't appropriate to call flush here so +remove it. + +Flushing is still done on a discontinuity to explicitly clear the last +branch buffer, but when the packet_queue fills up before reaching a +timestamp, that's not a discontinuity and the call to +cs_etm__process_traceid_queue() already generated samples and drained +the buffers correctly. + +This is visible by looking for a branch that has the same target as the +previous branch and the following source is before the address of the +last target, which is impossible as execution would have had to have +gone backwards: + + ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94 + (packet_queue fills here before a timestamp, resulting in a flush and + branch target ffff80008011cadc is duplicated.) + ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94 + ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34 + +After removing the flush the correct branch target is used for the +second sample, and ffff8000801117c4 is no longer before the previous +address: + + ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94 + ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0 + ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34 + +Make sure that a final branch stack is output at the end of the trace +by calling cs_etm__end_block(). This is already done for both the +timeless decode paths. + +Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios") +Reported-by: Ganapatrao Kulkarni +Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni@os.amperecomputing.com/ +Reviewed-by: Leo Yan +Signed-off-by: James Clark +Tested-by: Ganapatrao Kulkarni +Cc: Ben Gainey +Cc: Suzuki K Poulose +Cc: Will Deacon +Cc: Mathieu Poirier +Cc: Mike Leach +Cc: Ruidong Tian +Cc: Benjamin Gray +Cc: linux-arm-kernel@lists.infradead.org +Cc: coresight@lists.linaro.org +Cc: John Garry +Cc: scclevenger@os.amperecomputing.com +Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark@linaro.org +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/cs-etm.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c +index a2a369e2fbb67..e3fa32b83367e 100644 +--- a/tools/perf/util/cs-etm.c ++++ b/tools/perf/util/cs-etm.c +@@ -2098,12 +2098,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq) + + /* Ignore return value */ + cs_etm__process_traceid_queue(etmq, tidq); +- +- /* +- * Generate an instruction sample with the remaining +- * branchstack entries. +- */ +- cs_etm__flush(etmq, tidq); + } + } + +@@ -2186,7 +2180,7 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm) + + while (1) { + if (!etm->heap.heap_cnt) +- goto out; ++ break; + + /* Take the entry at the top of the min heap */ + cs_queue_nr = etm->heap.heap_array[0].queue_nr; +@@ -2269,6 +2263,23 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm) + ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, timestamp); + } + ++ for (i = 0; i < etm->queues.nr_queues; i++) { ++ struct int_node *inode; ++ ++ etmq = etm->queues.queue_array[i].priv; ++ if (!etmq) ++ continue; ++ ++ intlist__for_each_entry(inode, etmq->traceid_queues_list) { ++ int idx = (int)(intptr_t)inode->priv; ++ ++ /* Flush any remaining branch stack entries */ ++ tidq = etmq->traceid_queues[idx]; ++ ret = cs_etm__end_block(etmq, tidq); ++ if (ret) ++ return ret; ++ } ++ } + out: + return ret; + } +-- +2.43.0 + diff --git a/queue-5.10/perf-probe-correct-demangled-symbols-in-c-program.patch b/queue-5.10/perf-probe-correct-demangled-symbols-in-c-program.patch new file mode 100644 index 00000000000..47ebb7999ec --- /dev/null +++ b/queue-5.10/perf-probe-correct-demangled-symbols-in-c-program.patch @@ -0,0 +1,141 @@ +From ee61b049ac24bf8752a7c2c05e14f68434266028 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Oct 2024 15:14:32 +0100 +Subject: perf probe: Correct demangled symbols in C++ program + +From: Leo Yan + +[ Upstream commit 314909f13cc12d47c468602c37dace512d225eeb ] + +An issue can be observed when probe C++ demangled symbol with steps: + + # nm test_cpp_mangle | grep print_data + 0000000000000c94 t _GLOBAL__sub_I__Z10print_datai + 0000000000000afc T _Z10print_datai + 0000000000000b38 T _Z10print_dataR5Point + + # perf probe -x /home/niayan01/test_cpp_mangle -F --demangle + ... + print_data(Point&) + print_data(int) + ... + + # perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)" + probe-definition(0): test=print_data(int) + symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null) + 0 arguments + Open Debuginfo file: /home/niayan01/test_cpp_mangle + Try to find probe point from debuginfo. + Symbol print_data(int) address found : afc + Matched function: print_data [2ccf] + Probe point found: print_data+0 + Found 1 probe_trace_events. + Opening /sys/kernel/tracing//uprobe_events write=1 + Opening /sys/kernel/tracing//README write=0 + Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xb38 + ... + +When tried to probe symbol "print_data(int)", the log shows: + + Symbol print_data(int) address found : afc + +The found address is 0xafc - which is right with verifying the output +result from nm. Afterwards when write event, the command uses offset +0xb38 in the last log, which is a wrong address. + +The dwarf_diename() gets a common function name, in above case, it +returns string "print_data". As a result, the tool parses the offset +based on the common name. This leads to probe at the wrong symbol +"print_data(Point&)". + +To fix the issue, use the die_get_linkage_name() function to retrieve +the distinct linkage name - this is the mangled name for the C++ case. +Based on this unique name, the tool can get a correct offset for +probing. Based on DWARF doc, it is possible the linkage name is missed +in the DIE, it rolls back to use dwarf_diename(). + +After: + + # perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)" + probe-definition(0): test=print_data(int) + symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null) + 0 arguments + Open Debuginfo file: /home/niayan01/test_cpp_mangle + Try to find probe point from debuginfo. + Symbol print_data(int) address found : afc + Matched function: print_data [2d06] + Probe point found: print_data+0 + Found 1 probe_trace_events. + Opening /sys/kernel/tracing//uprobe_events write=1 + Opening /sys/kernel/tracing//README write=0 + Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xafc + Added new event: + probe_test_cpp_mangle:test (on print_data(int) in /home/niayan01/test_cpp_mangle) + + You can now use it in all perf tools, such as: + + perf record -e probe_test_cpp_mangle:test -aR sleep 1 + + # perf --debug verbose=3 probe -x test_cpp_mangle --add "test2=print_data(Point&)" + probe-definition(0): test2=print_data(Point&) + symbol:print_data(Point&) file:(null) line:0 offset:0 return:0 lazy:(null) + 0 arguments + Open Debuginfo file: /home/niayan01/test_cpp_mangle + Try to find probe point from debuginfo. + Symbol print_data(Point&) address found : b38 + Matched function: print_data [2ccf] + Probe point found: print_data+0 + Found 1 probe_trace_events. + Opening /sys/kernel/tracing//uprobe_events write=1 + Parsing probe_events: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0x0000000000000afc + Group:probe_test_cpp_mangle Event:test probe:p + Opening /sys/kernel/tracing//README write=0 + Writing event: p:probe_test_cpp_mangle/test2 /home/niayan01/test_cpp_mangle:0xb38 + Added new event: + probe_test_cpp_mangle:test2 (on print_data(Point&) in /home/niayan01/test_cpp_mangle) + + You can now use it in all perf tools, such as: + + perf record -e probe_test_cpp_mangle:test2 -aR sleep 1 + +Fixes: fb1587d869a3 ("perf probe: List probes with line number and file name") +Signed-off-by: Leo Yan +Acked-by: Masami Hiramatsu (Google) +Link: https://lore.kernel.org/r/20241012141432.877894-1-leo.yan@arm.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/probe-finder.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c +index 31c779ce029db..8a98673fea380 100644 +--- a/tools/perf/util/probe-finder.c ++++ b/tools/perf/util/probe-finder.c +@@ -1729,8 +1729,21 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr, + + /* Find a corresponding function (name, baseline and baseaddr) */ + if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { +- /* Get function entry information */ +- func = basefunc = dwarf_diename(&spdie); ++ /* ++ * Get function entry information. ++ * ++ * As described in the document DWARF Debugging Information ++ * Format Version 5, section 2.22 Linkage Names, "mangled names, ++ * are used in various ways, ... to distinguish multiple ++ * entities that have the same name". ++ * ++ * Firstly try to get distinct linkage name, if fail then ++ * rollback to get associated name in DIE. ++ */ ++ func = basefunc = die_get_linkage_name(&spdie); ++ if (!func) ++ func = basefunc = dwarf_diename(&spdie); ++ + if (!func || + die_entrypc(&spdie, &baseaddr) != 0 || + dwarf_decl_line(&spdie, &baseline) != 0) { +-- +2.43.0 + diff --git a/queue-5.10/perf-probe-fix-libdw-memory-leak.patch b/queue-5.10/perf-probe-fix-libdw-memory-leak.patch new file mode 100644 index 00000000000..a3919c4c1e9 --- /dev/null +++ b/queue-5.10/perf-probe-fix-libdw-memory-leak.patch @@ -0,0 +1,69 @@ +From fa366596647c9cc101682fcbc917e14bb2088633 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 16:56:22 -0700 +Subject: perf probe: Fix libdw memory leak + +From: Ian Rogers + +[ Upstream commit 4585038b8e186252141ef86e9f0d8e97f11dce8d ] + +Add missing dwarf_cfi_end to free memory associated with probe_finder +cfi_eh which is allocated and owned via a call to +dwarf_getcfi_elf. Confusingly cfi_dbg shouldn't be freed as its memory +is owned by the passed in debuginfo struct. Add comments to highlight +this. + +This addresses leak sanitizer issues seen in: +tools/perf/tests/shell/test_uprobe_from_different_cu.sh + +Fixes: 270bde1e76f4 ("perf probe: Search both .eh_frame and .debug_frame sections for probe location") +Signed-off-by: Ian Rogers +Cc: David S. Miller +Cc: Steinar H. Gunderson +Cc: Alexander Lobakin +Cc: Masami Hiramatsu (Google) +Cc: Kajol Jain +Cc: Athira Rajeev +Cc: Hemant Kumar +Link: https://lore.kernel.org/r/20241016235622.52166-3-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/probe-finder.c | 4 ++++ + tools/perf/util/probe-finder.h | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c +index fdafbfcef6871..31c779ce029db 100644 +--- a/tools/perf/util/probe-finder.c ++++ b/tools/perf/util/probe-finder.c +@@ -1483,6 +1483,10 @@ int debuginfo__find_trace_events(struct debuginfo *dbg, + if (ret >= 0 && tf.pf.skip_empty_arg) + ret = fill_empty_trace_arg(pev, tf.tevs, tf.ntevs); + ++#if _ELFUTILS_PREREQ(0, 142) ++ dwarf_cfi_end(tf.pf.cfi_eh); ++#endif ++ + if (ret < 0 || tf.ntevs == 0) { + for (i = 0; i < tf.ntevs; i++) + clear_probe_trace_event(&tf.tevs[i]); +diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h +index 2febb58756789..35eae263ffe74 100644 +--- a/tools/perf/util/probe-finder.h ++++ b/tools/perf/util/probe-finder.h +@@ -81,9 +81,9 @@ struct probe_finder { + + /* For variable searching */ + #if _ELFUTILS_PREREQ(0, 142) +- /* Call Frame Information from .eh_frame */ ++ /* Call Frame Information from .eh_frame. Owned by this struct. */ + Dwarf_CFI *cfi_eh; +- /* Call Frame Information from .debug_frame */ ++ /* Call Frame Information from .debug_frame. Not owned. */ + Dwarf_CFI *cfi_dbg; + #endif + Dwarf_Op *fb_ops; /* Frame base attribute */ +-- +2.43.0 + diff --git a/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-syscall.patch b/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-syscall.patch new file mode 100644 index 00000000000..20efb7505fe --- /dev/null +++ b/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-syscall.patch @@ -0,0 +1,63 @@ +From 74160c947438908c0593824ab95f4582a24864b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2024 23:21:27 +0000 +Subject: perf trace: Avoid garbage when not printing a syscall's arguments + +From: Benjamin Peterson + +[ Upstream commit 1302e352b26f34991b619b5d0b621b76d20a3883 ] + +syscall__scnprintf_args may not place anything in the output buffer +(e.g., because the arguments are all zero). If that happened in +trace__fprintf_sys_enter, its fprintf would receive an unitialized +buffer leading to garbage output. + +Fix the problem by passing the (possibly zero) bounds of the argument +buffer to the output fprintf. + +Fixes: a98392bb1e169a04 ("perf trace: Use beautifiers on syscalls:sys_enter_ handlers") +Signed-off-by: Benjamin Peterson +Tested-by: Arnaldo Carvalho de Melo +Tested-by: Howard Chu +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ian Rogers +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: https://lore.kernel.org/r/20241107232128.108981-2-benjamin@engflow.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-trace.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 6fbdabd902802..68189e6347205 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -2361,6 +2361,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel, + char msg[1024]; + void *args, *augmented_args = NULL; + int augmented_args_size; ++ size_t printed = 0; + + if (sc == NULL) + return -1; +@@ -2376,8 +2377,8 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel, + + args = perf_evsel__sc_tp_ptr(evsel, args, sample); + augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls_args_size); +- syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread); +- fprintf(trace->output, "%s", msg); ++ printed += syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread); ++ fprintf(trace->output, "%.*s", (int)printed, msg); + err = 0; + out_put: + thread__put(thread); +-- +2.43.0 + diff --git a/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch b/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch new file mode 100644 index 00000000000..803b68c5d31 --- /dev/null +++ b/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch @@ -0,0 +1,41 @@ +From a6d3cfc04fdc214a5b5a4ee18a6d748c41028e85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 Nov 2024 20:48:16 +0000 +Subject: perf trace: avoid garbage when not printing a trace event's arguments + +From: Benjamin Peterson + +[ Upstream commit 5fb8e56542a3cf469fdf25d77f50e21cbff3ae7e ] + +trace__fprintf_tp_fields may not print any tracepoint arguments. E.g., if the +argument values are all zero. Previously, this would result in a totally +uninitialized buffer being passed to fprintf, which could lead to garbage on the +console. Fix the problem by passing the number of initialized bytes fprintf. + +Fixes: f11b2803bb88 ("perf trace: Allow choosing how to augment the tracepoint arguments") +Signed-off-by: Benjamin Peterson +Tested-by: Howard Chu +Tested-by: Arnaldo Carvalho de Melo +Link: https://lore.kernel.org/r/20241103204816.7834-1-benjamin@engflow.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-trace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 8de0d0a740de4..3143601c1cb1f 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -2748,7 +2748,7 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct evsel *evsel, + printed += syscall_arg_fmt__scnprintf_val(arg, bf + printed, size - printed, &syscall_arg, val); + } + +- return printed + fprintf(trace->output, "%s", bf); ++ return printed + fprintf(trace->output, "%.*s", (int)printed, bf); + } + + static int trace__event_handler(struct trace *trace, struct evsel *evsel, +-- +2.43.0 + diff --git a/queue-5.10/perf-trace-do-not-lose-last-events-in-a-race.patch b/queue-5.10/perf-trace-do-not-lose-last-events-in-a-race.patch new file mode 100644 index 00000000000..4c04e9e0ba8 --- /dev/null +++ b/queue-5.10/perf-trace-do-not-lose-last-events-in-a-race.patch @@ -0,0 +1,74 @@ +From d41d5b8d524bca304216536935dc0275294cbc33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2024 23:21:26 +0000 +Subject: perf trace: Do not lose last events in a race + +From: Benjamin Peterson + +[ Upstream commit 3fd7c36973a250e17a4ee305a31545a9426021f4 ] + +If a perf trace event selector specifies a maximum number of events to output +(i.e., "/nr=N/" syntax), the event printing handler, trace__event_handler, +disables the event selector after the maximum number events are +printed. + +Furthermore, trace__event_handler checked if the event selector was +disabled before doing any work. This avoided exceeding the maximum +number of events to print if more events were in the buffer before the +selector was disabled. + +However, the event selector can be disabled for reasons other than +exceeding the maximum number of events. In particular, when the traced +subprocess exits, the main loop disables all event selectors. This meant +the last events of a traced subprocess might be lost to the printing +handler's short-circuiting logic. + +This nondeterministic problem could be seen by running the following many times: + + $ perf trace -e syscalls:sys_enter_exit_group true + +trace__event_handler should simply check for exceeding the maximum number of +events to print rather than the state of the event selector. + +Fixes: a9c5e6c1e9bff42c ("perf trace: Introduce per-event maximum number of events property") +Signed-off-by: Benjamin Peterson +Tested-by: Howard Chu +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ian Rogers +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: https://lore.kernel.org/r/20241107232128.108981-1-benjamin@engflow.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-trace.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 3143601c1cb1f..6fbdabd902802 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -2757,13 +2757,8 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel, + { + struct thread *thread; + int callchain_ret = 0; +- /* +- * Check if we called perf_evsel__disable(evsel) due to, for instance, +- * this event's max_events having been hit and this is an entry coming +- * from the ring buffer that we should discard, since the max events +- * have already been considered/printed. +- */ +- if (evsel->disabled) ++ ++ if (evsel->nr_events_printed >= evsel->max_events) + return 0; + + thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); +-- +2.43.0 + diff --git a/queue-5.10/pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch b/queue-5.10/pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch new file mode 100644 index 00000000000..e23b45475ec --- /dev/null +++ b/queue-5.10/pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch @@ -0,0 +1,48 @@ +From 8e98b8901ef738946b6aee760e3ea710ebddfa22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Oct 2024 11:04:41 +0800 +Subject: pmdomain: ti-sci: Add missing of_node_put() for args.np + +From: Zhang Zekun + +[ Upstream commit afc2331ef81657493c074592c409dac7c3cb8ccc ] + +of_parse_phandle_with_args() needs to call of_node_put() to decrement +the refcount of args.np. So, Add the missing of_node_put() in the loop. + +Fixes: efa5c01cd7ee ("soc: ti: ti_sci_pm_domains: switch to use multiple genpds instead of one") +Signed-off-by: Zhang Zekun +Reviewed-by: Dhruva Gole +Message-ID: <20241024030442.119506-2-zhangzekun11@huawei.com> +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/soc/ti/ti_sci_pm_domains.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c +index 17984a7bffba5..b21b152ed5d0f 100644 +--- a/drivers/soc/ti/ti_sci_pm_domains.c ++++ b/drivers/soc/ti/ti_sci_pm_domains.c +@@ -165,6 +165,7 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) + break; + + if (args.args_count >= 1 && args.np == dev->of_node) { ++ of_node_put(args.np); + if (args.args[0] > max_id) { + max_id = args.args[0]; + } else { +@@ -192,7 +193,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) + pm_genpd_init(&pd->pd, NULL, true); + + list_add(&pd->node, &pd_provider->pd_list); ++ } else { ++ of_node_put(args.np); + } ++ + index++; + } + } +-- +2.43.0 + diff --git a/queue-5.10/power-supply-bq27xxx-fix-registers-of-bq27426.patch b/queue-5.10/power-supply-bq27xxx-fix-registers-of-bq27426.patch new file mode 100644 index 00000000000..fdf571290b9 --- /dev/null +++ b/queue-5.10/power-supply-bq27xxx-fix-registers-of-bq27426.patch @@ -0,0 +1,88 @@ +From 684aea1875991c541bf5d471dbb2663939b519d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 20:54:05 +0200 +Subject: power: supply: bq27xxx: Fix registers of bq27426 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Barnabás Czémán + +[ Upstream commit 34f99d3b706a519e556841f405c224ca708b1f54 ] + +Correct bq27426 registers, according to technical reference manual +it does not have Design Capacity register so it is not register +compatible with bq27421. + +Fixes: 5ef6a16033b47 ("power: supply: bq27xxx: Add support for BQ27426") +Signed-off-by: Barnabás Czémán +Link: https://lore.kernel.org/r/20241016-fix_bq27426-v2-1-aa6c0f51a9f6@mainlining.org +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/bq27xxx_battery.c | 37 ++++++++++++++++++++++++-- + 1 file changed, 35 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c +index 21f6df21c3cc4..be2aac8fbf430 100644 +--- a/drivers/power/supply/bq27xxx_battery.c ++++ b/drivers/power/supply/bq27xxx_battery.c +@@ -448,9 +448,29 @@ static u8 + [BQ27XXX_REG_AP] = 0x18, + BQ27XXX_DM_REG_ROWS, + }, ++ bq27426_regs[BQ27XXX_REG_MAX] = { ++ [BQ27XXX_REG_CTRL] = 0x00, ++ [BQ27XXX_REG_TEMP] = 0x02, ++ [BQ27XXX_REG_INT_TEMP] = 0x1e, ++ [BQ27XXX_REG_VOLT] = 0x04, ++ [BQ27XXX_REG_AI] = 0x10, ++ [BQ27XXX_REG_FLAGS] = 0x06, ++ [BQ27XXX_REG_TTE] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_TTF] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_NAC] = 0x08, ++ [BQ27XXX_REG_RC] = 0x0c, ++ [BQ27XXX_REG_FCC] = 0x0e, ++ [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_AE] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_SOC] = 0x1c, ++ [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_AP] = 0x18, ++ BQ27XXX_DM_REG_ROWS, ++ }, + #define bq27411_regs bq27421_regs + #define bq27425_regs bq27421_regs +-#define bq27426_regs bq27421_regs + #define bq27441_regs bq27421_regs + #define bq27621_regs bq27421_regs + bq27z561_regs[BQ27XXX_REG_MAX] = { +@@ -747,10 +767,23 @@ static enum power_supply_property bq27421_props[] = { + }; + #define bq27411_props bq27421_props + #define bq27425_props bq27421_props +-#define bq27426_props bq27421_props + #define bq27441_props bq27421_props + #define bq27621_props bq27421_props + ++static enum power_supply_property bq27426_props[] = { ++ POWER_SUPPLY_PROP_STATUS, ++ POWER_SUPPLY_PROP_PRESENT, ++ POWER_SUPPLY_PROP_VOLTAGE_NOW, ++ POWER_SUPPLY_PROP_CURRENT_NOW, ++ POWER_SUPPLY_PROP_CAPACITY, ++ POWER_SUPPLY_PROP_CAPACITY_LEVEL, ++ POWER_SUPPLY_PROP_TEMP, ++ POWER_SUPPLY_PROP_TECHNOLOGY, ++ POWER_SUPPLY_PROP_CHARGE_FULL, ++ POWER_SUPPLY_PROP_CHARGE_NOW, ++ POWER_SUPPLY_PROP_MANUFACTURER, ++}; ++ + static enum power_supply_property bq27z561_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, +-- +2.43.0 + diff --git a/queue-5.10/power-supply-bq27xxx-support-charge_now-for-bq27z561.patch b/queue-5.10/power-supply-bq27xxx-support-charge_now-for-bq27z561.patch new file mode 100644 index 00000000000..f7951531a88 --- /dev/null +++ b/queue-5.10/power-supply-bq27xxx-support-charge_now-for-bq27z561.patch @@ -0,0 +1,237 @@ +From 29482513a4da8210c4c02537c01d744b0e999a8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Dec 2020 19:07:20 +0800 +Subject: power: supply: bq27xxx: Support CHARGE_NOW for + bq27z561/bq28z610/bq34z100 + +From: Hermes Zhang + +[ Upstream commit 3ed510f06e12f8876c20474766cc2f101a41174f ] + +Currently REG_NAC (nominal available capacity) is mapped to +power-supply's CHARGE_NOW property. Some chips do not have +REG_NAC and do not expose CHARGE_NOW at the moment. Some +bq27xxx chips also have another register REG_RM (remaining +capacity). The difference between REG_NAC and REG_RM is load +compensation. + +This patch adds register information for REG_RM for all +supported fuel gauges. On systems having REG_NAC it is +ignored, so behaviour does not change. On systems without +REG_NAC, REG_RM will be used to provide CHARGE_NOW +functionality. + +As a result there are three more chips exposing CHARGE_NOW: +bq27z561, bq28z610 and bq34z100 + +Signed-off-by: Hermes Zhang +Signed-off-by: Sebastian Reichel +Stable-dep-of: 34f99d3b706a ("power: supply: bq27xxx: Fix registers of bq27426") +Signed-off-by: Sasha Levin +--- + drivers/power/supply/bq27xxx_battery.c | 35 +++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c +index 0673e0fe0ffbd..21f6df21c3cc4 100644 +--- a/drivers/power/supply/bq27xxx_battery.c ++++ b/drivers/power/supply/bq27xxx_battery.c +@@ -110,6 +110,7 @@ enum bq27xxx_reg_index { + BQ27XXX_REG_TTES, /* Time-to-Empty Standby */ + BQ27XXX_REG_TTECP, /* Time-to-Empty at Constant Power */ + BQ27XXX_REG_NAC, /* Nominal Available Capacity */ ++ BQ27XXX_REG_RC, /* Remaining Capacity */ + BQ27XXX_REG_FCC, /* Full Charge Capacity */ + BQ27XXX_REG_CYCT, /* Cycle Count */ + BQ27XXX_REG_AE, /* Available Energy */ +@@ -145,6 +146,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = 0x26, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = INVALID_REG_ADDR, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = 0x22, +@@ -169,6 +171,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = 0x26, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = INVALID_REG_ADDR, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -193,6 +196,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1a, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -215,6 +219,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = 0x26, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = 0x22, +@@ -237,6 +242,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1a, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x1e, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -257,6 +263,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = 0x26, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR, + [BQ27XXX_REG_AE] = 0x22, +@@ -277,6 +284,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = 0x26, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = 0x22, +@@ -297,6 +305,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = 0x26, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = 0x22, +@@ -317,6 +326,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1c, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x1e, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -337,6 +347,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_RC] = INVALID_REG_ADDR, + [BQ27XXX_REG_FCC] = INVALID_REG_ADDR, + [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -361,6 +372,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -382,6 +394,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -405,6 +418,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x0c, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -425,6 +439,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = 0x08, ++ [BQ27XXX_REG_RC] = 0x0c, + [BQ27XXX_REG_FCC] = 0x0e, + [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR, + [BQ27XXX_REG_AE] = INVALID_REG_ADDR, +@@ -450,6 +465,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = 0x22, +@@ -470,6 +486,7 @@ static u8 + [BQ27XXX_REG_TTES] = INVALID_REG_ADDR, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_RC] = 0x10, + [BQ27XXX_REG_FCC] = 0x12, + [BQ27XXX_REG_CYCT] = 0x2a, + [BQ27XXX_REG_AE] = 0x22, +@@ -490,6 +507,7 @@ static u8 + [BQ27XXX_REG_TTES] = 0x1e, + [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR, + [BQ27XXX_REG_NAC] = INVALID_REG_ADDR, ++ [BQ27XXX_REG_RC] = 0x04, + [BQ27XXX_REG_FCC] = 0x06, + [BQ27XXX_REG_CYCT] = 0x2c, + [BQ27XXX_REG_AE] = 0x24, +@@ -745,6 +763,7 @@ static enum power_supply_property bq27z561_props[] = { + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CHARGE_FULL, ++ POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_POWER_AVG, +@@ -764,6 +783,7 @@ static enum power_supply_property bq28z610_props[] = { + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CHARGE_FULL, ++ POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_POWER_AVG, +@@ -784,6 +804,7 @@ static enum power_supply_property bq34z100_props[] = { + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CHARGE_FULL, ++ POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_ENERGY_NOW, +@@ -1508,6 +1529,15 @@ static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di) + return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC); + } + ++/* ++ * Return the battery Remaining Capacity in µAh ++ * Or < 0 if something fails. ++ */ ++static inline int bq27xxx_battery_read_rc(struct bq27xxx_device_info *di) ++{ ++ return bq27xxx_battery_read_charge(di, BQ27XXX_REG_RC); ++} ++ + /* + * Return the battery Full Charge Capacity in µAh + * Or < 0 if something fails. +@@ -1979,7 +2009,10 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: +- ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val); ++ if (di->regs[BQ27XXX_REG_NAC] != INVALID_REG_ADDR) ++ ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val); ++ else ++ ret = bq27xxx_simple_value(bq27xxx_battery_read_rc(di), val); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + ret = bq27xxx_simple_value(di->cache.charge_full, val); +-- +2.43.0 + diff --git a/queue-5.10/power-supply-core-remove-might_sleep-from-power_supp.patch b/queue-5.10/power-supply-core-remove-might_sleep-from-power_supp.patch new file mode 100644 index 00000000000..17153d2c9b4 --- /dev/null +++ b/queue-5.10/power-supply-core-remove-might_sleep-from-power_supp.patch @@ -0,0 +1,44 @@ +From abf3cc4ef8379ef2ac10f5b107200f9c1aa0c9f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Sep 2024 12:39:14 -0700 +Subject: power: supply: core: Remove might_sleep() from power_supply_put() + +From: Bart Van Assche + +[ Upstream commit f6da4553ff24a5d1c959c9627c965323adc3d307 ] + +The put_device() call in power_supply_put() may call +power_supply_dev_release(). The latter function does not sleep so +power_supply_put() doesn't sleep either. Hence, remove the might_sleep() +call from power_supply_put(). This patch suppresses false positive +complaints about calling a sleeping function from atomic context if +power_supply_put() is called from atomic context. + +Cc: Kyle Tso +Cc: Krzysztof Kozlowski +Fixes: 1a352462b537 ("power_supply: Add power_supply_put for decrementing device reference counter") +Signed-off-by: Bart Van Assche +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20240917193914.47566-1-bvanassche@acm.org +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/power_supply_core.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c +index 5c8c117b396e7..61ba2b343b938 100644 +--- a/drivers/power/supply/power_supply_core.c ++++ b/drivers/power/supply/power_supply_core.c +@@ -479,8 +479,6 @@ EXPORT_SYMBOL_GPL(power_supply_get_by_name); + */ + void power_supply_put(struct power_supply *psy) + { +- might_sleep(); +- + atomic_dec(&psy->use_cnt); + put_device(&psy->dev); + } +-- +2.43.0 + diff --git a/queue-5.10/powerpc-kexec-fix-return-of-uninitialized-variable.patch b/queue-5.10/powerpc-kexec-fix-return-of-uninitialized-variable.patch new file mode 100644 index 00000000000..4c4a5c6aa2e --- /dev/null +++ b/queue-5.10/powerpc-kexec-fix-return-of-uninitialized-variable.patch @@ -0,0 +1,49 @@ +From 472c72843d35dc36b01bd19e71af63d03d798ec4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 15:56:28 +0800 +Subject: powerpc/kexec: Fix return of uninitialized variable + +From: Zhang Zekun + +[ Upstream commit 83b5a407fbb73e6965adfb4bd0a803724bf87f96 ] + +of_property_read_u64() can fail and leave the variable uninitialized, +which will then be used. Return error if reading the property failed. + +Fixes: 2e6bd221d96f ("powerpc/kexec_file: Enable early kernel OPAL calls") +Signed-off-by: Zhang Zekun +Signed-off-by: Michael Ellerman +Link: https://patch.msgid.link/20240930075628.125138-1-zhangzekun11@huawei.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/kexec/file_load_64.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c +index a8a7cb71086b3..cb3fc0042cc25 100644 +--- a/arch/powerpc/kexec/file_load_64.c ++++ b/arch/powerpc/kexec/file_load_64.c +@@ -909,13 +909,18 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code, + if (dn) { + u64 val; + +- of_property_read_u64(dn, "opal-base-address", &val); ++ ret = of_property_read_u64(dn, "opal-base-address", &val); ++ if (ret) ++ goto out; ++ + ret = kexec_purgatory_get_set_symbol(image, "opal_base", &val, + sizeof(val), false); + if (ret) + goto out; + +- of_property_read_u64(dn, "opal-entry-address", &val); ++ ret = of_property_read_u64(dn, "opal-entry-address", &val); ++ if (ret) ++ goto out; + ret = kexec_purgatory_get_set_symbol(image, "opal_entry", &val, + sizeof(val), false); + } +-- +2.43.0 + diff --git a/queue-5.10/powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch b/queue-5.10/powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch new file mode 100644 index 00000000000..b66518bdab3 --- /dev/null +++ b/queue-5.10/powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch @@ -0,0 +1,153 @@ +From cd29675884e6f4c885424c2163b30c831b51e554 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 22:24:01 +1000 +Subject: powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore + +From: Michael Ellerman + +[ Upstream commit cadae3a45d23aa4f6485938a67cbc47aaaa25e38 ] + +The dtl_access_lock needs to be a rw_sempahore, a sleeping lock, because +the code calls kmalloc() while holding it, which can sleep: + + # echo 1 > /proc/powerpc/vcpudispatch_stats + BUG: sleeping function called from invalid context at include/linux/sched/mm.h:337 + in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 199, name: sh + preempt_count: 1, expected: 0 + 3 locks held by sh/199: + #0: c00000000a0743f8 (sb_writers#3){.+.+}-{0:0}, at: vfs_write+0x324/0x438 + #1: c0000000028c7058 (dtl_enable_mutex){+.+.}-{3:3}, at: vcpudispatch_stats_write+0xd4/0x5f4 + #2: c0000000028c70b8 (dtl_access_lock){+.+.}-{2:2}, at: vcpudispatch_stats_write+0x220/0x5f4 + CPU: 0 PID: 199 Comm: sh Not tainted 6.10.0-rc4 #152 + Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries + Call Trace: + dump_stack_lvl+0x130/0x148 (unreliable) + __might_resched+0x174/0x410 + kmem_cache_alloc_noprof+0x340/0x3d0 + alloc_dtl_buffers+0x124/0x1ac + vcpudispatch_stats_write+0x2a8/0x5f4 + proc_reg_write+0xf4/0x150 + vfs_write+0xfc/0x438 + ksys_write+0x88/0x148 + system_call_exception+0x1c4/0x5a0 + system_call_common+0xf4/0x258 + +Fixes: 06220d78f24a ("powerpc/pseries: Introduce rwlock to gatekeep DTLB usage") +Tested-by: Kajol Jain +Reviewed-by: Nysal Jan K.A +Reviewed-by: Kajol Jain +Signed-off-by: Michael Ellerman +Link: https://patch.msgid.link/20240819122401.513203-1-mpe@ellerman.id.au +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/dtl.h | 4 ++-- + arch/powerpc/platforms/pseries/dtl.c | 8 ++++---- + arch/powerpc/platforms/pseries/lpar.c | 8 ++++---- + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/arch/powerpc/include/asm/dtl.h b/arch/powerpc/include/asm/dtl.h +index 1625888f27ef6..5e40f27aa76e5 100644 +--- a/arch/powerpc/include/asm/dtl.h ++++ b/arch/powerpc/include/asm/dtl.h +@@ -1,8 +1,8 @@ + #ifndef _ASM_POWERPC_DTL_H + #define _ASM_POWERPC_DTL_H + ++#include + #include +-#include + + /* + * Layout of entries in the hypervisor's dispatch trace log buffer. +@@ -35,7 +35,7 @@ struct dtl_entry { + #define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT) + + extern struct kmem_cache *dtl_cache; +-extern rwlock_t dtl_access_lock; ++extern struct rw_semaphore dtl_access_lock; + + /* + * When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE = y, the cpu accounting code controls +diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c +index 982f069e4c318..36a2eb23dbdc4 100644 +--- a/arch/powerpc/platforms/pseries/dtl.c ++++ b/arch/powerpc/platforms/pseries/dtl.c +@@ -181,7 +181,7 @@ static int dtl_enable(struct dtl *dtl) + return -EBUSY; + + /* ensure there are no other conflicting dtl users */ +- if (!read_trylock(&dtl_access_lock)) ++ if (!down_read_trylock(&dtl_access_lock)) + return -EBUSY; + + n_entries = dtl_buf_entries; +@@ -189,7 +189,7 @@ static int dtl_enable(struct dtl *dtl) + if (!buf) { + printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n", + __func__, dtl->cpu); +- read_unlock(&dtl_access_lock); ++ up_read(&dtl_access_lock); + return -ENOMEM; + } + +@@ -207,7 +207,7 @@ static int dtl_enable(struct dtl *dtl) + spin_unlock(&dtl->lock); + + if (rc) { +- read_unlock(&dtl_access_lock); ++ up_read(&dtl_access_lock); + kmem_cache_free(dtl_cache, buf); + } + +@@ -222,7 +222,7 @@ static void dtl_disable(struct dtl *dtl) + dtl->buf = NULL; + dtl->buf_entries = 0; + spin_unlock(&dtl->lock); +- read_unlock(&dtl_access_lock); ++ up_read(&dtl_access_lock); + } + + /* file interface */ +diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c +index aed67f1a1bc56..b19de0faf913c 100644 +--- a/arch/powerpc/platforms/pseries/lpar.c ++++ b/arch/powerpc/platforms/pseries/lpar.c +@@ -166,7 +166,7 @@ struct vcpu_dispatch_data { + */ + #define NR_CPUS_H NR_CPUS + +-DEFINE_RWLOCK(dtl_access_lock); ++DECLARE_RWSEM(dtl_access_lock); + static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data); + static DEFINE_PER_CPU(u64, dtl_entry_ridx); + static DEFINE_PER_CPU(struct dtl_worker, dtl_workers); +@@ -460,7 +460,7 @@ static int dtl_worker_enable(unsigned long *time_limit) + { + int rc = 0, state; + +- if (!write_trylock(&dtl_access_lock)) { ++ if (!down_write_trylock(&dtl_access_lock)) { + rc = -EBUSY; + goto out; + } +@@ -476,7 +476,7 @@ static int dtl_worker_enable(unsigned long *time_limit) + pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n"); + free_dtl_buffers(time_limit); + reset_global_dtl_mask(); +- write_unlock(&dtl_access_lock); ++ up_write(&dtl_access_lock); + rc = -EINVAL; + goto out; + } +@@ -491,7 +491,7 @@ static void dtl_worker_disable(unsigned long *time_limit) + cpuhp_remove_state(dtl_worker_state); + free_dtl_buffers(time_limit); + reset_global_dtl_mask(); +- write_unlock(&dtl_access_lock); ++ up_write(&dtl_access_lock); + } + + static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p, +-- +2.43.0 + diff --git a/queue-5.10/powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch b/queue-5.10/powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch new file mode 100644 index 00000000000..4d9b5a4cd1d --- /dev/null +++ b/queue-5.10/powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch @@ -0,0 +1,76 @@ +From 25b31fc3b578bb24ea66b20b27faf09404564212 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 15:03:49 +0200 +Subject: powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static + +From: Michal Suchanek + +[ Upstream commit a26c4dbb3d9c1821cb0fc11cb2dbc32d5bf3463b ] + +These functions are not used outside of sstep.c + +Fixes: 350779a29f11 ("powerpc: Handle most loads and stores in instruction emulation code") +Signed-off-by: Michal Suchanek +Signed-off-by: Michael Ellerman +Link: https://patch.msgid.link/20241001130356.14664-1-msuchanek@suse.de +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/sstep.h | 5 ----- + arch/powerpc/lib/sstep.c | 12 ++++-------- + 2 files changed, 4 insertions(+), 13 deletions(-) + +diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h +index 972ed0df154d6..35765c30fef2c 100644 +--- a/arch/powerpc/include/asm/sstep.h ++++ b/arch/powerpc/include/asm/sstep.h +@@ -174,9 +174,4 @@ extern int emulate_step(struct pt_regs *regs, struct ppc_inst instr); + */ + extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op); + +-extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, +- const void *mem, bool cross_endian); +-extern void emulate_vsx_store(struct instruction_op *op, +- const union vsx_reg *reg, void *mem, +- bool cross_endian); + extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs); +diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c +index ca4733fbd02de..568a888d169d7 100644 +--- a/arch/powerpc/lib/sstep.c ++++ b/arch/powerpc/lib/sstep.c +@@ -706,8 +706,8 @@ static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea, + #endif /* __powerpc64 */ + + #ifdef CONFIG_VSX +-void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, +- const void *mem, bool rev) ++static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, ++ const void *mem, bool rev) + { + int size, read_size; + int i, j; +@@ -787,11 +787,9 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, + break; + } + } +-EXPORT_SYMBOL_GPL(emulate_vsx_load); +-NOKPROBE_SYMBOL(emulate_vsx_load); + +-void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, +- void *mem, bool rev) ++static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, ++ void *mem, bool rev) + { + int size, write_size; + int i, j; +@@ -863,8 +861,6 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, + break; + } + } +-EXPORT_SYMBOL_GPL(emulate_vsx_store); +-NOKPROBE_SYMBOL(emulate_vsx_store); + + static nokprobe_inline int do_vsx_load(struct instruction_op *op, + unsigned long ea, struct pt_regs *regs, +-- +2.43.0 + diff --git a/queue-5.10/powerpc-vdso-flag-vdso64-entry-points-as-functions.patch b/queue-5.10/powerpc-vdso-flag-vdso64-entry-points-as-functions.patch new file mode 100644 index 00000000000..25906a4cafd --- /dev/null +++ b/queue-5.10/powerpc-vdso-flag-vdso64-entry-points-as-functions.patch @@ -0,0 +1,112 @@ +From 68ce987d25214357b0b0f7c1ccf3770a839b7209 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Oct 2024 00:17:57 +0200 +Subject: powerpc/vdso: Flag VDSO64 entry points as functions + +From: Christophe Leroy + +[ Upstream commit 0161bd38c24312853ed5ae9a425a1c41c4ac674a ] + +On powerpc64 as shown below by readelf, vDSO functions symbols have +type NOTYPE. + +$ powerpc64-linux-gnu-readelf -a arch/powerpc/kernel/vdso/vdso64.so.dbg +ELF Header: + Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 + Class: ELF64 + Data: 2's complement, big endian + Version: 1 (current) + OS/ABI: UNIX - System V + ABI Version: 0 + Type: DYN (Shared object file) + Machine: PowerPC64 + Version: 0x1 +... + +Symbol table '.dynsym' contains 12 entries: + Num: Value Size Type Bind Vis Ndx Name +... + 1: 0000000000000524 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15 +... + 4: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.15 + 5: 00000000000006c0 48 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15 + +Symbol table '.symtab' contains 56 entries: + Num: Value Size Type Bind Vis Ndx Name +... + 45: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.15 + 46: 00000000000006c0 48 NOTYPE GLOBAL DEFAULT 8 __kernel_getcpu + 47: 0000000000000524 84 NOTYPE GLOBAL DEFAULT 8 __kernel_clock_getres + +To overcome that, commit ba83b3239e65 ("selftests: vDSO: fix vDSO +symbols lookup for powerpc64") was applied to have selftests also +look for NOTYPE symbols, but the correct fix should be to flag VDSO +entry points as functions. + +The original commit that brought VDSO support into powerpc/64 has the +following explanation: + + Note that the symbols exposed by the vDSO aren't "normal" function symbols, apps + can't be expected to link against them directly, the vDSO's are both seen + as if they were linked at 0 and the symbols just contain offsets to the + various functions. This is done on purpose to avoid a relocation step + (ppc64 functions normally have descriptors with abs addresses in them). + When glibc uses those functions, it's expected to use it's own trampolines + that know how to reach them. + +The descriptors it's talking about are the OPD function descriptors +used on ABI v1 (big endian). But it would be more correct for a text +symbol to have type function, even if there's no function descriptor +for it. + +glibc has a special case already for handling the VDSO symbols which +creates a fake opd pointing at the kernel symbol. So changing the VDSO +symbol type to function shouldn't affect that. + +For ABI v2, there is no function descriptors and VDSO functions can +safely have function type. + +So lets flag VDSO entry points as functions and revert the +selftest change. + +Link: https://github.com/mpe/linux-fullhistory/commit/5f2dd691b62da9d9cc54b938f8b29c22c93cb805 +Fixes: ba83b3239e65 ("selftests: vDSO: fix vDSO symbols lookup for powerpc64") +Signed-off-by: Christophe Leroy +Reviewed-By: Segher Boessenkool +Signed-off-by: Michael Ellerman +Link: https://patch.msgid.link/b6ad2f1ee9887af3ca5ecade2a56f4acda517a85.1728512263.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/vdso.h | 1 + + tools/testing/selftests/vDSO/parse_vdso.c | 3 +-- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h +index 2ff884853f975..e3768f1161d23 100644 +--- a/arch/powerpc/include/asm/vdso.h ++++ b/arch/powerpc/include/asm/vdso.h +@@ -27,6 +27,7 @@ int vdso_getcpu_init(void); + #ifdef __VDSO64__ + #define V_FUNCTION_BEGIN(name) \ + .globl name; \ ++ .type name,@function; \ + name: \ + + #define V_FUNCTION_END(name) \ +diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c +index d9ccc5acac182..4ae417372e9eb 100644 +--- a/tools/testing/selftests/vDSO/parse_vdso.c ++++ b/tools/testing/selftests/vDSO/parse_vdso.c +@@ -216,8 +216,7 @@ void *vdso_sym(const char *version, const char *name) + ELF(Sym) *sym = &vdso_info.symtab[chain]; + + /* Check for a defined global or weak function w/ right name. */ +- if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC && +- ELF64_ST_TYPE(sym->st_info) != STT_NOTYPE) ++ if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC) + continue; + if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL && + ELF64_ST_BIND(sym->st_info) != STB_WEAK) +-- +2.43.0 + diff --git a/queue-5.10/pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch b/queue-5.10/pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch new file mode 100644 index 00000000000..aa99e05c07d --- /dev/null +++ b/queue-5.10/pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch @@ -0,0 +1,190 @@ +From d1f6febb18315044f2b13013e2b615c9cbc39f50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 15:41:23 -0400 +Subject: pwm: imx27: Workaround of the pwm output bug when decrease the duty + cycle +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Clark Wang + +[ Upstream commit a25351e4c7740eb22561a3ee4ef17611c6f410b0 ] + +Implement workaround for ERR051198 +(https://www.nxp.com/docs/en/errata/IMX8MN_0N14Y.pdf) + +PWM output may not function correctly if the FIFO is empty when a new SAR +value is programmed. + +Description: + When the PWM FIFO is empty, a new value programmed to the PWM Sample + register (PWM_PWMSAR) will be directly applied even if the current timer + period has not expired. If the new SAMPLE value programmed in the + PWM_PWMSAR register is less than the previous value, and the PWM counter + register (PWM_PWMCNR) that contains the current COUNT value is greater + than the new programmed SAMPLE value, the current period will not flip + the level. This may result in an output pulse with a duty cycle of 100%. + +Workaround: + Program the current SAMPLE value in the PWM_PWMSAR register before + updating the new duty cycle to the SAMPLE value in the PWM_PWMSAR + register. This will ensure that the new SAMPLE value is modified during + a non-empty FIFO, and can be successfully updated after the period + expires. + +Write the old SAR value before updating the new duty cycle to SAR. This +avoids writing the new value into an empty FIFO. + +This only resolves the issue when the PWM period is longer than 2us +(or <500kHz) because write register is not quick enough when PWM period is +very short. + +Reproduce steps: + cd /sys/class/pwm/pwmchip1/pwm0 + echo 2000000000 > period # It is easy to observe by using long period + echo 1000000000 > duty_cycle + echo 1 > enable + echo 8000 > duty_cycle # One full high pulse will be seen by scope + +Fixes: 166091b1894d ("[ARM] MXC: add pwm driver for i.MX SoCs") +Reviewed-by: Jun Li +Signed-off-by: Clark Wang +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20241008194123.1943141-1-Frank.Li@nxp.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-imx27.c | 98 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 96 insertions(+), 2 deletions(-) + +diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c +index 86bcafd23e4f6..3c7929ca3b921 100644 +--- a/drivers/pwm/pwm-imx27.c ++++ b/drivers/pwm/pwm-imx27.c +@@ -26,6 +26,7 @@ + #define MX3_PWMSR 0x04 /* PWM Status Register */ + #define MX3_PWMSAR 0x0C /* PWM Sample Register */ + #define MX3_PWMPR 0x10 /* PWM Period Register */ ++#define MX3_PWMCNR 0x14 /* PWM Counter Register */ + + #define MX3_PWMCR_FWM GENMASK(27, 26) + #define MX3_PWMCR_STOPEN BIT(25) +@@ -215,11 +216,13 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip, + static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +- unsigned long period_cycles, duty_cycles, prescale; ++ unsigned long period_cycles, duty_cycles, prescale, period_us, tmp; + struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); + struct pwm_state cstate; + unsigned long long c; + unsigned long long clkrate; ++ unsigned long flags; ++ int val; + int ret; + u32 cr; + +@@ -262,7 +265,98 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, + pwm_imx27_sw_reset(chip); + } + +- writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); ++ val = readl(imx->mmio_base + MX3_PWMPR); ++ val = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val; ++ cr = readl(imx->mmio_base + MX3_PWMCR); ++ tmp = NSEC_PER_SEC * (u64)(val + 2) * MX3_PWMCR_PRESCALER_GET(cr); ++ tmp = DIV_ROUND_UP_ULL(tmp, clkrate); ++ period_us = DIV_ROUND_UP_ULL(tmp, 1000); ++ ++ /* ++ * ERR051198: ++ * PWM: PWM output may not function correctly if the FIFO is empty when ++ * a new SAR value is programmed ++ * ++ * Description: ++ * When the PWM FIFO is empty, a new value programmed to the PWM Sample ++ * register (PWM_PWMSAR) will be directly applied even if the current ++ * timer period has not expired. ++ * ++ * If the new SAMPLE value programmed in the PWM_PWMSAR register is ++ * less than the previous value, and the PWM counter register ++ * (PWM_PWMCNR) that contains the current COUNT value is greater than ++ * the new programmed SAMPLE value, the current period will not flip ++ * the level. This may result in an output pulse with a duty cycle of ++ * 100%. ++ * ++ * Consider a change from ++ * ________ ++ * / \______/ ++ * ^ * ^ ++ * to ++ * ____ ++ * / \__________/ ++ * ^ ^ ++ * At the time marked by *, the new write value will be directly applied ++ * to SAR even the current period is not over if FIFO is empty. ++ * ++ * ________ ____________________ ++ * / \______/ \__________/ ++ * ^ ^ * ^ ^ ++ * |<-- old SAR -->| |<-- new SAR -->| ++ * ++ * That is the output is active for a whole period. ++ * ++ * Workaround: ++ * Check new SAR less than old SAR and current counter is in errata ++ * windows, write extra old SAR into FIFO and new SAR will effect at ++ * next period. ++ * ++ * Sometime period is quite long, such as over 1 second. If add old SAR ++ * into FIFO unconditional, new SAR have to wait for next period. It ++ * may be too long. ++ * ++ * Turn off the interrupt to ensure that not IRQ and schedule happen ++ * during above operations. If any irq and schedule happen, counter ++ * in PWM will be out of data and take wrong action. ++ * ++ * Add a safety margin 1.5us because it needs some time to complete ++ * IO write. ++ * ++ * Use writel_relaxed() to minimize the interval between two writes to ++ * the SAR register to increase the fastest PWM frequency supported. ++ * ++ * When the PWM period is longer than 2us(or <500kHz), this workaround ++ * can solve this problem. No software workaround is available if PWM ++ * period is shorter than IO write. Just try best to fill old data ++ * into FIFO. ++ */ ++ c = clkrate * 1500; ++ do_div(c, NSEC_PER_SEC); ++ ++ local_irq_save(flags); ++ val = FIELD_GET(MX3_PWMSR_FIFOAV, readl_relaxed(imx->mmio_base + MX3_PWMSR)); ++ ++ if (duty_cycles < imx->duty_cycle && (cr & MX3_PWMCR_EN)) { ++ if (period_us < 2) { /* 2us = 500 kHz */ ++ /* Best effort attempt to fix up >500 kHz case */ ++ udelay(3 * period_us); ++ writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR); ++ writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR); ++ } else if (val < MX3_PWMSR_FIFOAV_2WORDS) { ++ val = readl_relaxed(imx->mmio_base + MX3_PWMCNR); ++ /* ++ * If counter is close to period, controller may roll over when ++ * next IO write. ++ */ ++ if ((val + c >= duty_cycles && val < imx->duty_cycle) || ++ val + c >= period_cycles) ++ writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR); ++ } ++ } ++ writel_relaxed(duty_cycles, imx->mmio_base + MX3_PWMSAR); ++ local_irq_restore(flags); ++ + writel(period_cycles, imx->mmio_base + MX3_PWMPR); + + /* +-- +2.43.0 + diff --git a/queue-5.10/rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch b/queue-5.10/rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch new file mode 100644 index 00000000000..8d341fc9d27 --- /dev/null +++ b/queue-5.10/rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch @@ -0,0 +1,80 @@ +From 38f3f0678620ec06d988d712b2d058812baa1ca2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Oct 2024 03:06:54 -0700 +Subject: RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey + +From: Kashyap Desai + +[ Upstream commit 808ca6de989c598bc5af1ae0ad971a66077efac0 ] + +Invalidate rkey is cpu endian and immediate data is in big endian format. +Both immediate data and invalidate the remote key returned by +HW is in little endian format. + +While handling the commit in fixes tag, the difference between +immediate data and invalidate rkey endianness was not considered. + +Without changes of this patch, Kernel ULP was failing while processing +inv_rkey. + +dmesg log snippet - +nvme nvme0: Bogus remote invalidation for rkey 0x2000019Fix in this patch + +Do endianness conversion based on completion queue entry flag. +Also, the HW completions are already converted to host endianness in +bnxt_qplib_cq_process_res_rc and bnxt_qplib_cq_process_res_ud and there +is no need to convert it again in bnxt_re_poll_cq. Modified the union to +hold the correct data type. + +Fixes: 95b087f87b78 ("bnxt_re: Fix imm_data endianness") +Signed-off-by: Kashyap Desai +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1730110014-20755-1-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +++++-- + drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index f16e0b2c7895e..9ffd28ab526a8 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -3334,7 +3334,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, + wc->byte_len = orig_cqe->length; + wc->qp = &gsi_qp->ib_qp; + +- wc->ex.imm_data = cpu_to_be32(le32_to_cpu(orig_cqe->immdata)); ++ wc->ex.imm_data = cpu_to_be32(orig_cqe->immdata); + wc->src_qp = orig_cqe->src_qp; + memcpy(wc->smac, orig_cqe->smac, ETH_ALEN); + if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) { +@@ -3474,7 +3474,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) + continue; + } + wc->qp = &qp->ib_qp; +- wc->ex.imm_data = cpu_to_be32(le32_to_cpu(cqe->immdata)); ++ if (cqe->flags & CQ_RES_RC_FLAGS_IMM) ++ wc->ex.imm_data = cpu_to_be32(cqe->immdata); ++ else ++ wc->ex.invalidate_rkey = cqe->invrkey; + wc->src_qp = cqe->src_qp; + memcpy(wc->smac, cqe->smac, ETH_ALEN); + wc->port_num = 1; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +index 01cb48caa9dbd..6803162261a7d 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h +@@ -372,7 +372,7 @@ struct bnxt_qplib_cqe { + u16 cfa_meta; + u64 wr_id; + union { +- __le32 immdata; ++ u32 immdata; + u32 invrkey; + }; + u64 qp_handle; +-- +2.43.0 + diff --git a/queue-5.10/rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch b/queue-5.10/rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch new file mode 100644 index 00000000000..66821ea91fd --- /dev/null +++ b/queue-5.10/rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch @@ -0,0 +1,57 @@ +From 203d4f3869d2ef1d2a91d03e150e909db2cdd82d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2024 15:57:43 +0800 +Subject: RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg() + +From: Junxian Huang + +[ Upstream commit 6b526d17eed850352d880b93b9bf20b93006bd92 ] + +ib_map_mr_sg() allows ULPs to specify NULL as the sg_offset argument. +The driver needs to check whether it is a NULL pointer before +dereferencing it. + +Fixes: d387d4b54eb8 ("RDMA/hns: Fix missing pagesize and alignment check in FRMR") +Signed-off-by: Junxian Huang +Link: https://patch.msgid.link/20241108075743.2652258-3-huangjunxian6@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_mr.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c +index 5f038bd5571d1..b062301258683 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_mr.c ++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c +@@ -478,15 +478,16 @@ static int hns_roce_set_page(struct ib_mr *ibmr, u64 addr) + } + + int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, +- unsigned int *sg_offset) ++ unsigned int *sg_offset_p) + { ++ unsigned int sg_offset = sg_offset_p ? *sg_offset_p : 0; + struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device); + struct ib_device *ibdev = &hr_dev->ib_dev; + struct hns_roce_mr *mr = to_hr_mr(ibmr); + struct hns_roce_mtr *mtr = &mr->pbl_mtr; + int ret, sg_num = 0; + +- if (!IS_ALIGNED(*sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) || ++ if (!IS_ALIGNED(sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) || + ibmr->page_size < HNS_HW_PAGE_SIZE || + ibmr->page_size > HNS_HW_MAX_PAGE_SIZE) + return sg_num; +@@ -497,7 +498,7 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, + if (!mr->page_list) + return sg_num; + +- sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, hns_roce_set_page); ++ sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset_p, hns_roce_set_page); + if (sg_num < 1) { + ibdev_err(ibdev, "failed to store sg pages %u %u, cnt = %d.\n", + mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, sg_num); +-- +2.43.0 + diff --git a/queue-5.10/regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch b/queue-5.10/regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch new file mode 100644 index 00000000000..a55cda62374 --- /dev/null +++ b/queue-5.10/regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch @@ -0,0 +1,85 @@ +From ed383c6fb72817f8008644f6994f07c119b79632 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Nov 2024 18:55:53 +0200 +Subject: regmap: irq: Set lockdep class for hierarchical IRQ domains + +From: Andy Shevchenko + +[ Upstream commit 953e549471cabc9d4980f1da2e9fa79f4c23da06 ] + +Lockdep gives a false positive splat as it can't distinguish the lock +which is taken by different IRQ descriptors from different IRQ chips +that are organized in a way of a hierarchy: + + ====================================================== + WARNING: possible circular locking dependency detected + 6.12.0-rc5-next-20241101-00148-g9fabf8160b53 #562 Tainted: G W + ------------------------------------------------------ + modprobe/141 is trying to acquire lock: + ffff899446947868 (intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock){+.+.}-{4:4}, at: regmap_update_bits_base+0x33/0x90 + + but task is already holding lock: + ffff899446947c68 (&d->lock){+.+.}-{4:4}, at: __setup_irq+0x682/0x790 + + which lock already depends on the new lock. + + -> #3 (&d->lock){+.+.}-{4:4}: + -> #2 (&desc->request_mutex){+.+.}-{4:4}: + -> #1 (ipclock){+.+.}-{4:4}: + -> #0 (intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock){+.+.}-{4:4}: + + Chain exists of: + intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock --> &desc->request_mutex --> &d->lock + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&d->lock); + lock(&desc->request_mutex); + lock(&d->lock); + lock(intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock); + + *** DEADLOCK *** + + 3 locks held by modprobe/141: + #0: ffff8994419368f8 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xf6/0x250 + #1: ffff89944690b250 (&desc->request_mutex){+.+.}-{4:4}, at: __setup_irq+0x1a2/0x790 + #2: ffff899446947c68 (&d->lock){+.+.}-{4:4}, at: __setup_irq+0x682/0x790 + +Set a lockdep class when we map the IRQ so that it doesn't warn about +a lockdep bug that doesn't exist. + +Fixes: 4af8be67fd99 ("regmap: Convert regmap_irq to use irq_domain") +Signed-off-by: Andy Shevchenko +Link: https://patch.msgid.link/20241101165553.4055617-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/base/regmap/regmap-irq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c +index 4466f8bdab2e1..301e849a87d1c 100644 +--- a/drivers/base/regmap/regmap-irq.c ++++ b/drivers/base/regmap/regmap-irq.c +@@ -539,12 +539,16 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) + return IRQ_NONE; + } + ++static struct lock_class_key regmap_irq_lock_class; ++static struct lock_class_key regmap_irq_request_class; ++ + static int regmap_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) + { + struct regmap_irq_chip_data *data = h->host_data; + + irq_set_chip_data(virq, data); ++ irq_set_lockdep_class(virq, ®map_irq_lock_class, ®map_irq_request_class); + irq_set_chip(virq, &data->irq_chip); + irq_set_nested_thread(virq, 1); + irq_set_parent(virq, data->irq); +-- +2.43.0 + diff --git a/queue-5.10/remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch b/queue-5.10/remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch new file mode 100644 index 00000000000..5682c12b71b --- /dev/null +++ b/queue-5.10/remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch @@ -0,0 +1,42 @@ +From dd3b654b2c9be052948b05bb386dc3b092687260 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 13:00:20 +0530 +Subject: remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region + +From: Sibi Sankar + +[ Upstream commit 7b22b7719fc17d5979a991c918c868ab041be5c8 ] + +Any write access to the IMEM region when the Q6 is setting up XPU +protection on it will result in a XPU violation. Fix this by ensuring +IMEM writes related to the MBA post-mortem logs happen before the Q6 +is brought out of reset. + +Fixes: 318130cc9362 ("remoteproc: qcom_q6v5_mss: Add MBA log extraction support") +Signed-off-by: Sibi Sankar +Reviewed-by: Douglas Anderson +Tested-by: Douglas Anderson +Link: https://lore.kernel.org/r/20240819073020.3291287-1-quic_sibis@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_mss.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c +index 3d975ecd93360..876223e6c9291 100644 +--- a/drivers/remoteproc/qcom_q6v5_mss.c ++++ b/drivers/remoteproc/qcom_q6v5_mss.c +@@ -980,6 +980,9 @@ static int q6v5_mba_load(struct q6v5 *qproc) + goto disable_active_clks; + } + ++ if (qproc->has_mba_logs) ++ qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE); ++ + writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG); + if (qproc->dp_size) { + writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG); +-- +2.43.0 + diff --git a/queue-5.10/revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch b/queue-5.10/revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch new file mode 100644 index 00000000000..c7601fbbb34 --- /dev/null +++ b/queue-5.10/revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch @@ -0,0 +1,43 @@ +From 8d599b0914d975962d1794015911f4c5c68f64e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 08:15:19 +0000 +Subject: Revert "cgroup: Fix memory leak caused by missing cgroup_bpf_offline" + +From: Chen Ridong + +[ Upstream commit feb301c60970bd2a1310a53ce2d6e4375397a51b ] + +This reverts commit 04f8ef5643bcd8bcde25dfdebef998aea480b2ba. + +Only cgroup v2 can be attached by cgroup by BPF programs. Revert this +commit and cgroup_bpf_inherit and cgroup_bpf_offline won't be called in +cgroup v1. The memory leak issue will be fixed with next patch. + +Fixes: 04f8ef5643bc ("cgroup: Fix memory leak caused by missing cgroup_bpf_offline") +Link: https://lore.kernel.org/cgroups/aka2hk5jsel5zomucpwlxsej6iwnfw4qu5jkrmjhyfhesjlfdw@46zxhg5bdnr7/ +Signed-off-by: Chen Ridong +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cgroup.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index e0fd62d56110a..c5e51bad62473 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -2187,10 +2187,8 @@ static void cgroup_kill_sb(struct super_block *sb) + * And don't kill the default root. + */ + if (list_empty(&root->cgrp.self.children) && root != &cgrp_dfl_root && +- !percpu_ref_is_dying(&root->cgrp.self.refcnt)) { +- cgroup_bpf_offline(&root->cgrp); ++ !percpu_ref_is_dying(&root->cgrp.self.refcnt)) + percpu_ref_kill(&root->cgrp.self.refcnt); +- } + cgroup_put(&root->cgrp); + kernfs_kill_sb(sb); + } +-- +2.43.0 + diff --git a/queue-5.10/rpmsg-glink-add-tx_data_cont-command-while-sending.patch b/queue-5.10/rpmsg-glink-add-tx_data_cont-command-while-sending.patch new file mode 100644 index 00000000000..061eed701bf --- /dev/null +++ b/queue-5.10/rpmsg-glink-add-tx_data_cont-command-while-sending.patch @@ -0,0 +1,92 @@ +From 9f1aebe7e7e18f52bdaee9efb5764c26a482f784 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jul 2020 10:48:13 +0530 +Subject: rpmsg: glink: Add TX_DATA_CONT command while sending + +From: Arun Kumar Neelakantam + +[ Upstream commit 8956927faed366b60b0355f4a4317a10e281ced7 ] + +With current design the transport can send packets of size upto +FIFO_SIZE which is 16k and return failure for all packets above 16k. + +Add TX_DATA_CONT command to send packets greater than 16k by splitting +into 8K chunks. + +Signed-off-by: Arun Kumar Neelakantam +Signed-off-by: Deepak Kumar Singh +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/1596086296-28529-4-git-send-email-deesin@codeaurora.org +Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length") +Signed-off-by: Sasha Levin +--- + drivers/rpmsg/qcom_glink_native.c | 38 +++++++++++++++++++++++++++---- + 1 file changed, 34 insertions(+), 4 deletions(-) + +diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c +index 28b6ae0e1a2fd..a8486264f11f3 100644 +--- a/drivers/rpmsg/qcom_glink_native.c ++++ b/drivers/rpmsg/qcom_glink_native.c +@@ -1276,6 +1276,8 @@ static int __qcom_glink_send(struct glink_channel *channel, + } __packed req; + int ret; + unsigned long flags; ++ int chunk_size = len; ++ int left_size = 0; + + if (!glink->intentless) { + while (!intent) { +@@ -1309,18 +1311,46 @@ static int __qcom_glink_send(struct glink_channel *channel, + iid = intent->id; + } + ++ if (wait && chunk_size > SZ_8K) { ++ chunk_size = SZ_8K; ++ left_size = len - chunk_size; ++ } + req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA); + req.msg.param1 = cpu_to_le16(channel->lcid); + req.msg.param2 = cpu_to_le32(iid); +- req.chunk_size = cpu_to_le32(len); +- req.left_size = cpu_to_le32(0); ++ req.chunk_size = cpu_to_le32(chunk_size); ++ req.left_size = cpu_to_le32(left_size); + +- ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait); ++ ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait); + + /* Mark intent available if we failed */ +- if (ret && intent) ++ if (ret && intent) { + intent->in_use = false; ++ return ret; ++ } + ++ while (left_size > 0) { ++ data = (void *)((char *)data + chunk_size); ++ chunk_size = left_size; ++ if (chunk_size > SZ_8K) ++ chunk_size = SZ_8K; ++ left_size -= chunk_size; ++ ++ req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA_CONT); ++ req.msg.param1 = cpu_to_le16(channel->lcid); ++ req.msg.param2 = cpu_to_le32(iid); ++ req.chunk_size = cpu_to_le32(chunk_size); ++ req.left_size = cpu_to_le32(left_size); ++ ++ ret = qcom_glink_tx(glink, &req, sizeof(req), data, ++ chunk_size, wait); ++ ++ /* Mark intent available if we failed */ ++ if (ret && intent) { ++ intent->in_use = false; ++ break; ++ } ++ } + return ret; + } + +-- +2.43.0 + diff --git a/queue-5.10/rpmsg-glink-fix-glink-command-prefix.patch b/queue-5.10/rpmsg-glink-fix-glink-command-prefix.patch new file mode 100644 index 00000000000..5210a3773ad --- /dev/null +++ b/queue-5.10/rpmsg-glink-fix-glink-command-prefix.patch @@ -0,0 +1,284 @@ +From 81ac020c60472c1743f3f035a248b5442023961b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 14:59:33 -0800 +Subject: rpmsg: glink: Fix GLINK command prefix + +From: Bjorn Andersson + +[ Upstream commit 4e816d0318fdfe8932da80dbf04ba318b13e4b3a ] + +The upstream GLINK driver was first introduced to communicate with the +RPM on MSM8996, presumably as an artifact from that era the command +defines was prefixed RPM_CMD, while they actually are GLINK_CMDs. + +Let's rename these, to keep things tidy. No functional change. + +Signed-off-by: Bjorn Andersson +Reviewed-by: Chris Lew +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230214225933.2025595-1-quic_bjorande@quicinc.com +Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length") +Signed-off-by: Sasha Levin +--- + drivers/rpmsg/qcom_glink_native.c | 98 +++++++++++++++---------------- + 1 file changed, 49 insertions(+), 49 deletions(-) + +diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c +index 8128da8646db1..831a5d1cd4806 100644 +--- a/drivers/rpmsg/qcom_glink_native.c ++++ b/drivers/rpmsg/qcom_glink_native.c +@@ -191,20 +191,20 @@ struct glink_channel { + + static const struct rpmsg_endpoint_ops glink_endpoint_ops; + +-#define RPM_CMD_VERSION 0 +-#define RPM_CMD_VERSION_ACK 1 +-#define RPM_CMD_OPEN 2 +-#define RPM_CMD_CLOSE 3 +-#define RPM_CMD_OPEN_ACK 4 +-#define RPM_CMD_INTENT 5 +-#define RPM_CMD_RX_DONE 6 +-#define RPM_CMD_RX_INTENT_REQ 7 +-#define RPM_CMD_RX_INTENT_REQ_ACK 8 +-#define RPM_CMD_TX_DATA 9 +-#define RPM_CMD_CLOSE_ACK 11 +-#define RPM_CMD_TX_DATA_CONT 12 +-#define RPM_CMD_READ_NOTIF 13 +-#define RPM_CMD_RX_DONE_W_REUSE 14 ++#define GLINK_CMD_VERSION 0 ++#define GLINK_CMD_VERSION_ACK 1 ++#define GLINK_CMD_OPEN 2 ++#define GLINK_CMD_CLOSE 3 ++#define GLINK_CMD_OPEN_ACK 4 ++#define GLINK_CMD_INTENT 5 ++#define GLINK_CMD_RX_DONE 6 ++#define GLINK_CMD_RX_INTENT_REQ 7 ++#define GLINK_CMD_RX_INTENT_REQ_ACK 8 ++#define GLINK_CMD_TX_DATA 9 ++#define GLINK_CMD_CLOSE_ACK 11 ++#define GLINK_CMD_TX_DATA_CONT 12 ++#define GLINK_CMD_READ_NOTIF 13 ++#define GLINK_CMD_RX_DONE_W_REUSE 14 + + #define GLINK_FEATURE_INTENTLESS BIT(1) + +@@ -313,7 +313,7 @@ static void qcom_glink_send_read_notify(struct qcom_glink *glink) + { + struct glink_msg msg; + +- msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF); ++ msg.cmd = cpu_to_le16(GLINK_CMD_READ_NOTIF); + msg.param1 = 0; + msg.param2 = 0; + +@@ -375,7 +375,7 @@ static int qcom_glink_send_version(struct qcom_glink *glink) + { + struct glink_msg msg; + +- msg.cmd = cpu_to_le16(RPM_CMD_VERSION); ++ msg.cmd = cpu_to_le16(GLINK_CMD_VERSION); + msg.param1 = cpu_to_le16(GLINK_VERSION_1); + msg.param2 = cpu_to_le32(glink->features); + +@@ -386,7 +386,7 @@ static void qcom_glink_send_version_ack(struct qcom_glink *glink) + { + struct glink_msg msg; + +- msg.cmd = cpu_to_le16(RPM_CMD_VERSION_ACK); ++ msg.cmd = cpu_to_le16(GLINK_CMD_VERSION_ACK); + msg.param1 = cpu_to_le16(GLINK_VERSION_1); + msg.param2 = cpu_to_le32(glink->features); + +@@ -398,7 +398,7 @@ static void qcom_glink_send_open_ack(struct qcom_glink *glink, + { + struct glink_msg msg; + +- msg.cmd = cpu_to_le16(RPM_CMD_OPEN_ACK); ++ msg.cmd = cpu_to_le16(GLINK_CMD_OPEN_ACK); + msg.param1 = cpu_to_le16(channel->rcid); + msg.param2 = cpu_to_le32(0); + +@@ -424,11 +424,11 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink, + } + + /** +- * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote ++ * qcom_glink_send_open_req() - send a GLINK_CMD_OPEN request to the remote + * @glink: Ptr to the glink edge + * @channel: Ptr to the channel that the open req is sent + * +- * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote. ++ * Allocates a local channel id and sends a GLINK_CMD_OPEN message to the remote. + * Will return with refcount held, regardless of outcome. + * + * Returns 0 on success, negative errno otherwise. +@@ -457,7 +457,7 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink, + + channel->lcid = ret; + +- req.msg.cmd = cpu_to_le16(RPM_CMD_OPEN); ++ req.msg.cmd = cpu_to_le16(GLINK_CMD_OPEN); + req.msg.param1 = cpu_to_le16(channel->lcid); + req.msg.param2 = cpu_to_le32(name_len); + strcpy(req.name, channel->name); +@@ -482,7 +482,7 @@ static void qcom_glink_send_close_req(struct qcom_glink *glink, + { + struct glink_msg req; + +- req.cmd = cpu_to_le16(RPM_CMD_CLOSE); ++ req.cmd = cpu_to_le16(GLINK_CMD_CLOSE); + req.param1 = cpu_to_le16(channel->lcid); + req.param2 = 0; + +@@ -494,7 +494,7 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink, + { + struct glink_msg req; + +- req.cmd = cpu_to_le16(RPM_CMD_CLOSE_ACK); ++ req.cmd = cpu_to_le16(GLINK_CMD_CLOSE_ACK); + req.param1 = cpu_to_le16(rcid); + req.param2 = 0; + +@@ -525,7 +525,7 @@ static void qcom_glink_rx_done_work(struct work_struct *work) + iid = intent->id; + reuse = intent->reuse; + +- cmd.id = reuse ? RPM_CMD_RX_DONE_W_REUSE : RPM_CMD_RX_DONE; ++ cmd.id = reuse ? GLINK_CMD_RX_DONE_W_REUSE : GLINK_CMD_RX_DONE; + cmd.lcid = cid; + cmd.liid = iid; + +@@ -637,7 +637,7 @@ static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink, + { + struct glink_msg msg; + +- msg.cmd = cpu_to_le16(RPM_CMD_RX_INTENT_REQ_ACK); ++ msg.cmd = cpu_to_le16(GLINK_CMD_RX_INTENT_REQ_ACK); + msg.param1 = cpu_to_le16(channel->lcid); + msg.param2 = cpu_to_le32(granted); + +@@ -668,7 +668,7 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink, + } __packed; + struct command cmd; + +- cmd.id = cpu_to_le16(RPM_CMD_INTENT); ++ cmd.id = cpu_to_le16(GLINK_CMD_INTENT); + cmd.lcid = cpu_to_le16(channel->lcid); + cmd.count = cpu_to_le32(1); + cmd.size = cpu_to_le32(intent->size); +@@ -1033,42 +1033,42 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data) + param2 = le32_to_cpu(msg.param2); + + switch (cmd) { +- case RPM_CMD_VERSION: +- case RPM_CMD_VERSION_ACK: +- case RPM_CMD_CLOSE: +- case RPM_CMD_CLOSE_ACK: +- case RPM_CMD_RX_INTENT_REQ: ++ case GLINK_CMD_VERSION: ++ case GLINK_CMD_VERSION_ACK: ++ case GLINK_CMD_CLOSE: ++ case GLINK_CMD_CLOSE_ACK: ++ case GLINK_CMD_RX_INTENT_REQ: + ret = qcom_glink_rx_defer(glink, 0); + break; +- case RPM_CMD_OPEN_ACK: ++ case GLINK_CMD_OPEN_ACK: + ret = qcom_glink_rx_open_ack(glink, param1); + qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); + break; +- case RPM_CMD_OPEN: ++ case GLINK_CMD_OPEN: + ret = qcom_glink_rx_defer(glink, param2); + break; +- case RPM_CMD_TX_DATA: +- case RPM_CMD_TX_DATA_CONT: ++ case GLINK_CMD_TX_DATA: ++ case GLINK_CMD_TX_DATA_CONT: + ret = qcom_glink_rx_data(glink, avail); + break; +- case RPM_CMD_READ_NOTIF: ++ case GLINK_CMD_READ_NOTIF: + qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); + + mbox_send_message(glink->mbox_chan, NULL); + mbox_client_txdone(glink->mbox_chan, 0); + break; +- case RPM_CMD_INTENT: ++ case GLINK_CMD_INTENT: + qcom_glink_handle_intent(glink, param1, param2, avail); + break; +- case RPM_CMD_RX_DONE: ++ case GLINK_CMD_RX_DONE: + qcom_glink_handle_rx_done(glink, param1, param2, false); + qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); + break; +- case RPM_CMD_RX_DONE_W_REUSE: ++ case GLINK_CMD_RX_DONE_W_REUSE: + qcom_glink_handle_rx_done(glink, param1, param2, true); + qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); + break; +- case RPM_CMD_RX_INTENT_REQ_ACK: ++ case GLINK_CMD_RX_INTENT_REQ_ACK: + qcom_glink_handle_intent_req_ack(glink, param1, param2); + qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); + break; +@@ -1271,7 +1271,7 @@ static int qcom_glink_request_intent(struct qcom_glink *glink, + + reinit_completion(&channel->intent_req_comp); + +- cmd.id = RPM_CMD_RX_INTENT_REQ; ++ cmd.id = GLINK_CMD_RX_INTENT_REQ; + cmd.cid = channel->lcid; + cmd.size = size; + +@@ -1345,7 +1345,7 @@ static int __qcom_glink_send(struct glink_channel *channel, + chunk_size = SZ_8K; + left_size = len - chunk_size; + } +- req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA); ++ req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA); + req.msg.param1 = cpu_to_le16(channel->lcid); + req.msg.param2 = cpu_to_le32(iid); + req.chunk_size = cpu_to_le32(chunk_size); +@@ -1366,7 +1366,7 @@ static int __qcom_glink_send(struct glink_channel *channel, + chunk_size = SZ_8K; + left_size -= chunk_size; + +- req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA_CONT); ++ req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA_CONT); + req.msg.param1 = cpu_to_le16(channel->lcid); + req.msg.param2 = cpu_to_le32(iid); + req.chunk_size = cpu_to_le32(chunk_size); +@@ -1605,22 +1605,22 @@ static void qcom_glink_work(struct work_struct *work) + param2 = le32_to_cpu(msg->param2); + + switch (cmd) { +- case RPM_CMD_VERSION: ++ case GLINK_CMD_VERSION: + qcom_glink_receive_version(glink, param1, param2); + break; +- case RPM_CMD_VERSION_ACK: ++ case GLINK_CMD_VERSION_ACK: + qcom_glink_receive_version_ack(glink, param1, param2); + break; +- case RPM_CMD_OPEN: ++ case GLINK_CMD_OPEN: + qcom_glink_rx_open(glink, param1, msg->data); + break; +- case RPM_CMD_CLOSE: ++ case GLINK_CMD_CLOSE: + qcom_glink_rx_close(glink, param1); + break; +- case RPM_CMD_CLOSE_ACK: ++ case GLINK_CMD_CLOSE_ACK: + qcom_glink_rx_close_ack(glink, param1); + break; +- case RPM_CMD_RX_INTENT_REQ: ++ case GLINK_CMD_RX_INTENT_REQ: + qcom_glink_handle_intent_req(glink, param1, param2); + break; + default: +-- +2.43.0 + diff --git a/queue-5.10/rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch b/queue-5.10/rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch new file mode 100644 index 00000000000..9b31a9df188 --- /dev/null +++ b/queue-5.10/rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch @@ -0,0 +1,123 @@ +From 24d629a6756e527a18f1f3dbe0d6063222253d15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jul 2020 10:48:16 +0530 +Subject: rpmsg: glink: Send READ_NOTIFY command in FIFO full case + +From: Arun Kumar Neelakantam + +[ Upstream commit b16a37e1846c9573a847a56fa2f31ba833dae45a ] + +The current design sleeps unconditionally in TX FIFO full case and +wakeup only after sleep timer expires which adds random delays in +clients TX path. + +Avoid sleep and use READ_NOTIFY command so that writer can be woken up +when remote notifies about read completion by sending IRQ. + +Signed-off-by: Deepak Kumar Singh +Signed-off-by: Arun Kumar Neelakantam +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/1596086296-28529-7-git-send-email-deesin@codeaurora.org +Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length") +Signed-off-by: Sasha Levin +--- + drivers/rpmsg/qcom_glink_native.c | 36 ++++++++++++++++++++++++++++++- + 1 file changed, 35 insertions(+), 1 deletion(-) + +diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c +index a8486264f11f3..8128da8646db1 100644 +--- a/drivers/rpmsg/qcom_glink_native.c ++++ b/drivers/rpmsg/qcom_glink_native.c +@@ -92,6 +92,8 @@ struct glink_core_rx_intent { + * @rcids: idr of all channels with a known remote channel id + * @features: remote features + * @intentless: flag to indicate that there is no intent ++ * @tx_avail_notify: Waitqueue for pending tx tasks ++ * @sent_read_notify: flag to check cmd sent or not + */ + struct qcom_glink { + struct device *dev; +@@ -118,6 +120,8 @@ struct qcom_glink { + unsigned long features; + + bool intentless; ++ wait_queue_head_t tx_avail_notify; ++ bool sent_read_notify; + }; + + enum { +@@ -305,6 +309,20 @@ static void qcom_glink_tx_write(struct qcom_glink *glink, + glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen); + } + ++static void qcom_glink_send_read_notify(struct qcom_glink *glink) ++{ ++ struct glink_msg msg; ++ ++ msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF); ++ msg.param1 = 0; ++ msg.param2 = 0; ++ ++ qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0); ++ ++ mbox_send_message(glink->mbox_chan, NULL); ++ mbox_client_txdone(glink->mbox_chan, 0); ++} ++ + static int qcom_glink_tx(struct qcom_glink *glink, + const void *hdr, size_t hlen, + const void *data, size_t dlen, bool wait) +@@ -325,12 +343,21 @@ static int qcom_glink_tx(struct qcom_glink *glink, + goto out; + } + ++ if (!glink->sent_read_notify) { ++ glink->sent_read_notify = true; ++ qcom_glink_send_read_notify(glink); ++ } ++ + /* Wait without holding the tx_lock */ + spin_unlock_irqrestore(&glink->tx_lock, flags); + +- usleep_range(10000, 15000); ++ wait_event_timeout(glink->tx_avail_notify, ++ qcom_glink_tx_avail(glink) >= tlen, 10 * HZ); + + spin_lock_irqsave(&glink->tx_lock, flags); ++ ++ if (qcom_glink_tx_avail(glink) >= tlen) ++ glink->sent_read_notify = false; + } + + qcom_glink_tx_write(glink, hdr, hlen, data, dlen); +@@ -991,6 +1018,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data) + unsigned int cmd; + int ret = 0; + ++ /* To wakeup any blocking writers */ ++ wake_up_all(&glink->tx_avail_notify); ++ + for (;;) { + avail = qcom_glink_rx_avail(glink); + if (avail < sizeof(msg)) +@@ -1530,6 +1560,9 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid) + struct glink_channel *channel; + unsigned long flags; + ++ /* To wakeup any blocking writers */ ++ wake_up_all(&glink->tx_avail_notify); ++ + spin_lock_irqsave(&glink->idr_lock, flags); + channel = idr_find(&glink->lcids, lcid); + if (WARN(!channel, "close ack on unknown channel\n")) { +@@ -1691,6 +1724,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, + spin_lock_init(&glink->rx_lock); + INIT_LIST_HEAD(&glink->rx_queue); + INIT_WORK(&glink->rx_work, qcom_glink_work); ++ init_waitqueue_head(&glink->tx_avail_notify); + + spin_lock_init(&glink->idr_lock); + idr_init(&glink->lcids); +-- +2.43.0 + diff --git a/queue-5.10/rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch b/queue-5.10/rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch new file mode 100644 index 00000000000..694be24f26c --- /dev/null +++ b/queue-5.10/rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch @@ -0,0 +1,44 @@ +From 77fcb38297a860a98650e5fd464c3fc46748a515 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2024 19:59:35 -0400 +Subject: rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name + length + +From: Jonathan Marek + +[ Upstream commit 06c59d97f63c1b8af521fa5aef8a716fb988b285 ] + +The name len field of the CMD_OPEN packet is only 16-bits and the upper +16-bits of "param2" are a different "prio" field, which can be nonzero in +certain situations, and CMD_OPEN packets can be unexpectedly dropped +because of this. + +Fix this by masking out the upper 16 bits of param2. + +Fixes: b4f8e52b89f6 ("rpmsg: Introduce Qualcomm RPM glink driver") +Signed-off-by: Jonathan Marek +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20241007235935.6216-1-jonathan@marek.ca +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/rpmsg/qcom_glink_native.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c +index 831a5d1cd4806..82670cb063f5a 100644 +--- a/drivers/rpmsg/qcom_glink_native.c ++++ b/drivers/rpmsg/qcom_glink_native.c +@@ -1045,7 +1045,8 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data) + qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); + break; + case GLINK_CMD_OPEN: +- ret = qcom_glink_rx_defer(glink, param2); ++ /* upper 16 bits of param2 are the "prio" field */ ++ ret = qcom_glink_rx_defer(glink, param2 & 0xffff); + break; + case GLINK_CMD_TX_DATA: + case GLINK_CMD_TX_DATA_CONT: +-- +2.43.0 + diff --git a/queue-5.10/s390-syscalls-avoid-creation-of-arch-arch-directory.patch b/queue-5.10/s390-syscalls-avoid-creation-of-arch-arch-directory.patch new file mode 100644 index 00000000000..9524cf3c5df --- /dev/null +++ b/queue-5.10/s390-syscalls-avoid-creation-of-arch-arch-directory.patch @@ -0,0 +1,54 @@ +From 318d69eed41a142e33d5d095b40bead165c79af4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Nov 2024 22:45:52 +0900 +Subject: s390/syscalls: Avoid creation of arch/arch/ directory + +From: Masahiro Yamada + +[ Upstream commit 0708967e2d56e370231fd07defa0d69f9ad125e8 ] + +Building the kernel with ARCH=s390 creates a weird arch/arch/ directory. + + $ find arch/arch + arch/arch + arch/arch/s390 + arch/arch/s390/include + arch/arch/s390/include/generated + arch/arch/s390/include/generated/asm + arch/arch/s390/include/generated/uapi + arch/arch/s390/include/generated/uapi/asm + +The root cause is 'targets' in arch/s390/kernel/syscalls/Makefile, +where the relative path is incorrect. + +Strictly speaking, 'targets' was not necessary in the first place +because this Makefile uses 'filechk' instead of 'if_changed'. + +However, this commit keeps it, as it will be useful when converting +'filechk' to 'if_changed' later. + +Fixes: 5c75824d915e ("s390/syscalls: add Makefile to generate system call header files") +Signed-off-by: Masahiro Yamada +Link: https://lore.kernel.org/r/20241111134603.2063226-1-masahiroy@kernel.org +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/syscalls/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/kernel/syscalls/Makefile b/arch/s390/kernel/syscalls/Makefile +index b98f25029b8e6..7b77ed779c7b2 100644 +--- a/arch/s390/kernel/syscalls/Makefile ++++ b/arch/s390/kernel/syscalls/Makefile +@@ -12,7 +12,7 @@ kapi-hdrs-y := $(kapi)/unistd_nr.h + uapi-hdrs-y := $(uapi)/unistd_32.h + uapi-hdrs-y += $(uapi)/unistd_64.h + +-targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y)) ++targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y)) + + PHONY += kapi uapi + +-- +2.43.0 + diff --git a/queue-5.10/scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch b/queue-5.10/scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch new file mode 100644 index 00000000000..18822815849 --- /dev/null +++ b/queue-5.10/scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch @@ -0,0 +1,109 @@ +From 99b7db587de1f394405a62ba5d4a2dcb6eb64c1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Oct 2024 09:18:09 +0800 +Subject: scsi: bfa: Fix use-after-free in bfad_im_module_exit() + +From: Ye Bin + +[ Upstream commit 178b8f38932d635e90f5f0e9af1986c6f4a89271 ] + +BUG: KASAN: slab-use-after-free in __lock_acquire+0x2aca/0x3a20 +Read of size 8 at addr ffff8881082d80c8 by task modprobe/25303 + +Call Trace: + + dump_stack_lvl+0x95/0xe0 + print_report+0xcb/0x620 + kasan_report+0xbd/0xf0 + __lock_acquire+0x2aca/0x3a20 + lock_acquire+0x19b/0x520 + _raw_spin_lock+0x2b/0x40 + attribute_container_unregister+0x30/0x160 + fc_release_transport+0x19/0x90 [scsi_transport_fc] + bfad_im_module_exit+0x23/0x60 [bfa] + bfad_init+0xdb/0xff0 [bfa] + do_one_initcall+0xdc/0x550 + do_init_module+0x22d/0x6b0 + load_module+0x4e96/0x5ff0 + init_module_from_file+0xcd/0x130 + idempotent_init_module+0x330/0x620 + __x64_sys_finit_module+0xb3/0x110 + do_syscall_64+0xc1/0x1d0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + +Allocated by task 25303: + kasan_save_stack+0x24/0x50 + kasan_save_track+0x14/0x30 + __kasan_kmalloc+0x7f/0x90 + fc_attach_transport+0x4f/0x4740 [scsi_transport_fc] + bfad_im_module_init+0x17/0x80 [bfa] + bfad_init+0x23/0xff0 [bfa] + do_one_initcall+0xdc/0x550 + do_init_module+0x22d/0x6b0 + load_module+0x4e96/0x5ff0 + init_module_from_file+0xcd/0x130 + idempotent_init_module+0x330/0x620 + __x64_sys_finit_module+0xb3/0x110 + do_syscall_64+0xc1/0x1d0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Freed by task 25303: + kasan_save_stack+0x24/0x50 + kasan_save_track+0x14/0x30 + kasan_save_free_info+0x3b/0x60 + __kasan_slab_free+0x38/0x50 + kfree+0x212/0x480 + bfad_im_module_init+0x7e/0x80 [bfa] + bfad_init+0x23/0xff0 [bfa] + do_one_initcall+0xdc/0x550 + do_init_module+0x22d/0x6b0 + load_module+0x4e96/0x5ff0 + init_module_from_file+0xcd/0x130 + idempotent_init_module+0x330/0x620 + __x64_sys_finit_module+0xb3/0x110 + do_syscall_64+0xc1/0x1d0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Above issue happens as follows: + +bfad_init + error = bfad_im_module_init() + fc_release_transport(bfad_im_scsi_transport_template); + if (error) + goto ext; + +ext: + bfad_im_module_exit(); + fc_release_transport(bfad_im_scsi_transport_template); + --> Trigger double release + +Don't call bfad_im_module_exit() if bfad_im_module_init() failed. + +Fixes: 7725ccfda597 ("[SCSI] bfa: Brocade BFA FC SCSI driver") +Signed-off-by: Ye Bin +Link: https://lore.kernel.org/r/20241023011809.63466-1-yebin@huaweicloud.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/bfa/bfad.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c +index 440ef32be048f..45b5f83ad6da1 100644 +--- a/drivers/scsi/bfa/bfad.c ++++ b/drivers/scsi/bfa/bfad.c +@@ -1705,9 +1705,8 @@ bfad_init(void) + + error = bfad_im_module_init(); + if (error) { +- error = -ENOMEM; + printk(KERN_WARNING "bfad_im_module_init failure\n"); +- goto ext; ++ return -ENOMEM; + } + + if (strcmp(FCPI_NAME, " fcpim") == 0) +-- +2.43.0 + diff --git a/queue-5.10/scsi-fusion-remove-unused-variable-rc.patch b/queue-5.10/scsi-fusion-remove-unused-variable-rc.patch new file mode 100644 index 00000000000..3ba07abd2cb --- /dev/null +++ b/queue-5.10/scsi-fusion-remove-unused-variable-rc.patch @@ -0,0 +1,46 @@ +From c9661ea8708c187c0f17c8487b3b15de2c955e66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Oct 2024 16:44:17 +0800 +Subject: scsi: fusion: Remove unused variable 'rc' + +From: Zeng Heng + +[ Upstream commit bd65694223f7ad11c790ab63ad1af87a771192ee ] + +The return value of scsi_device_reprobe() is currently ignored in +_scsih_reprobe_lun(). Fixing the calling code to deal with the potential +error is non-trivial, so for now just WARN_ON(). + +The handling of scsi_device_reprobe()'s return value refers to +_scsih_reprobe_lun() and the following link: + +https://lore.kernel.org/all/094fdbf57487af4f395238c0525b2a560c8f68f0.1469766027.git.calvinowens@fb.com/ + +Fixes: f99be43b3024 ("[SCSI] fusion: power pc and miscellaneous bug fixs") +Signed-off-by: Zeng Heng +Link: https://lore.kernel.org/r/20241024084417.154655-1-zengheng4@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/message/fusion/mptsas.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c +index 18b91ea1a353f..e56e96671da99 100644 +--- a/drivers/message/fusion/mptsas.c ++++ b/drivers/message/fusion/mptsas.c +@@ -4205,10 +4205,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num, + static void + mptsas_reprobe_lun(struct scsi_device *sdev, void *data) + { +- int rc; +- + sdev->no_uld_attach = data ? 1 : 0; +- rc = scsi_device_reprobe(sdev); ++ WARN_ON(scsi_device_reprobe(sdev)); + } + + static void +-- +2.43.0 + diff --git a/queue-5.10/scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch b/queue-5.10/scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch new file mode 100644 index 00000000000..4fce186001d --- /dev/null +++ b/queue-5.10/scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch @@ -0,0 +1,37 @@ +From c1cc9231e3d46f9b613e3fe9d844a04f1294a377 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Oct 2024 20:57:10 +0800 +Subject: scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb() + +From: Zhen Lei + +[ Upstream commit c62c30429db3eb4ced35c7fcf6f04a61ce3a01bb ] + +Hook "qed_ops->common->sb_init = qed_sb_init" does not release the DMA +memory sb_virt when it fails. Add dma_free_coherent() to free it. This +is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb(). + +Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.") +Signed-off-by: Zhen Lei +Link: https://lore.kernel.org/r/20241026125711.484-2-thunder.leizhen@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qedf/qedf_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c +index 2536da96130ea..912845415d9b4 100644 +--- a/drivers/scsi/qedf/qedf_main.c ++++ b/drivers/scsi/qedf/qedf_main.c +@@ -2725,6 +2725,7 @@ static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf, + sb_id, QED_SB_TYPE_STORAGE); + + if (ret) { ++ dma_free_coherent(&qedf->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys); + QEDF_ERR(&qedf->dbg_ctx, + "Status block initialization failed (0x%x) for id = %d.\n", + ret, sb_id); +-- +2.43.0 + diff --git a/queue-5.10/scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch b/queue-5.10/scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch new file mode 100644 index 00000000000..0ed1b50bd60 --- /dev/null +++ b/queue-5.10/scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch @@ -0,0 +1,37 @@ +From 51255a321ca1896be1fb078549cd9f5ea023e2cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Oct 2024 20:57:11 +0800 +Subject: scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb() + +From: Zhen Lei + +[ Upstream commit 95bbdca4999bc59a72ebab01663d421d6ce5775d ] + +Hook "qedi_ops->common->sb_init = qed_sb_init" does not release the DMA +memory sb_virt when it fails. Add dma_free_coherent() to free it. This +is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb(). + +Fixes: ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.") +Signed-off-by: Zhen Lei +Link: https://lore.kernel.org/r/20241026125711.484-3-thunder.leizhen@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qedi/qedi_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c +index 96e470746767a..3bf75d466b2c6 100644 +--- a/drivers/scsi/qedi/qedi_main.c ++++ b/drivers/scsi/qedi/qedi_main.c +@@ -371,6 +371,7 @@ static int qedi_alloc_and_init_sb(struct qedi_ctx *qedi, + ret = qedi_ops->common->sb_init(qedi->cdev, sb_info, sb_virt, sb_phys, + sb_id, QED_SB_TYPE_STORAGE); + if (ret) { ++ dma_free_coherent(&qedi->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys); + QEDI_ERR(&qedi->dbg_ctx, + "Status block initialization failed for id = %d.\n", + sb_id); +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-add-one-test-for-sockmap-with-strparse.patch b/queue-5.10/selftests-bpf-add-one-test-for-sockmap-with-strparse.patch new file mode 100644 index 00000000000..87ca8dacba5 --- /dev/null +++ b/queue-5.10/selftests-bpf-add-one-test-for-sockmap-with-strparse.patch @@ -0,0 +1,104 @@ +From 4736acd935c7d50ad81cbc56983935d467d52d50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Oct 2021 22:12:16 +0800 +Subject: selftests, bpf: Add one test for sockmap with strparser + +From: Liu Jian + +[ Upstream commit d69672147faa2a7671c0779fa5b9ad99e4fca4e3 ] + +Add the test to check sockmap with strparser is working well. + +Signed-off-by: Liu Jian +Signed-off-by: Daniel Borkmann +Acked-by: John Fastabend +Link: https://lore.kernel.org/bpf/20211029141216.211899-3-liujian56@huawei.com +Stable-dep-of: 523dffccbade ("selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 33 ++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 46a1ca4f699e2..89d215416a34e 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -141,6 +141,7 @@ struct sockmap_options { + bool sendpage; + bool data_test; + bool drop_expected; ++ bool check_recved_len; + int iov_count; + int iov_length; + int rate; +@@ -564,8 +565,12 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + int err, i, flags = MSG_NOSIGNAL; + bool drop = opt->drop_expected; + bool data = opt->data_test; ++ int iov_alloc_length = iov_length; + +- err = msg_alloc_iov(&msg, iov_count, iov_length, data, tx); ++ if (!tx && opt->check_recved_len) ++ iov_alloc_length *= 2; ++ ++ err = msg_alloc_iov(&msg, iov_count, iov_alloc_length, data, tx); + if (err) + goto out_errno; + if (peek_flag) { +@@ -678,6 +683,13 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + if (recv > 0) + s->bytes_recvd += recv; + ++ if (opt->check_recved_len && s->bytes_recvd > total_bytes) { ++ errno = EMSGSIZE; ++ fprintf(stderr, "recv failed(), bytes_recvd:%zd, total_bytes:%f\n", ++ s->bytes_recvd, total_bytes); ++ goto out_errno; ++ } ++ + if (data) { + int chunk_sz = opt->sendpage ? + iov_length : +@@ -759,7 +771,8 @@ static int sendmsg_test(struct sockmap_options *opt) + + rxpid = fork(); + if (rxpid == 0) { +- iov_buf -= (txmsg_pop - txmsg_start_pop + 1); ++ if (txmsg_pop || txmsg_start_pop) ++ iov_buf -= (txmsg_pop - txmsg_start_pop + 1); + if (opt->drop_expected || txmsg_ktls_skb_drop) + _exit(0); + +@@ -1708,6 +1721,19 @@ static void test_txmsg_ingress_parser(int cgrp, struct sockmap_options *opt) + test_exec(cgrp, opt); + } + ++static void test_txmsg_ingress_parser2(int cgrp, struct sockmap_options *opt) ++{ ++ if (ktls == 1) ++ return; ++ skb_use_parser = 10; ++ opt->iov_length = 20; ++ opt->iov_count = 1; ++ opt->rate = 1; ++ opt->check_recved_len = true; ++ test_exec(cgrp, opt); ++ opt->check_recved_len = false; ++} ++ + char *map_names[] = { + "sock_map", + "sock_map_txmsg", +@@ -1802,7 +1828,8 @@ struct _test test[] = { + {"txmsg test pull-data", test_txmsg_pull}, + {"txmsg test pop-data", test_txmsg_pop}, + {"txmsg test push/pop data", test_txmsg_push_pop}, +- {"txmsg text ingress parser", test_txmsg_ingress_parser}, ++ {"txmsg test ingress parser", test_txmsg_ingress_parser}, ++ {"txmsg test ingress parser2", test_txmsg_ingress_parser2}, + }; + + static int check_whitelist(struct _test *t, struct sockmap_options *opt) +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch b/queue-5.10/selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch new file mode 100644 index 00000000000..bbbed5a7016 --- /dev/null +++ b/queue-5.10/selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch @@ -0,0 +1,246 @@ +From 001549ac01a272c0450ddc1dd1fcda0cc018b1ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:16 +0000 +Subject: selftests/bpf: Add push/pop checking for msg_verify_data in + test_sockmap + +From: Zijian Zhang + +[ Upstream commit 862087c3d36219ed44569666eb263efc97f00c9a ] + +Add push/pop checking for msg_verify_data in test_sockmap, except for +pop/push with cork tests, in these tests the logic will be different. +1. With corking, pop/push might not be invoked in each sendmsg, it makes +the layout of the received data difficult +2. It makes it hard to calculate the total_bytes in the recvmsg +Temporarily skip the data integrity test for these cases now, added a TODO + +Fixes: ee9b352ce465 ("selftests/bpf: Fix msg_verify_data in test_sockmap") +Signed-off-by: Zijian Zhang +Reviewed-by: John Fastabend +Link: https://lore.kernel.org/r/20241106222520.527076-5-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 106 ++++++++++++++++++++- + 1 file changed, 101 insertions(+), 5 deletions(-) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 85d6fac7124bd..5b4390d643b21 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -89,6 +89,10 @@ int ktls; + int peek_flag; + int skb_use_parser; + int txmsg_omit_skb_parser; ++int verify_push_start; ++int verify_push_len; ++int verify_pop_start; ++int verify_pop_len; + + static const struct option long_options[] = { + {"help", no_argument, NULL, 'h' }, +@@ -514,12 +518,41 @@ static int msg_alloc_iov(struct msghdr *msg, + return -ENOMEM; + } + +-/* TODO: Add verification logic for push, pull and pop data */ ++/* In push or pop test, we need to do some calculations for msg_verify_data */ ++static void msg_verify_date_prep(void) ++{ ++ int push_range_end = txmsg_start_push + txmsg_end_push - 1; ++ int pop_range_end = txmsg_start_pop + txmsg_pop - 1; ++ ++ if (txmsg_end_push && txmsg_pop && ++ txmsg_start_push <= pop_range_end && txmsg_start_pop <= push_range_end) { ++ /* The push range and the pop range overlap */ ++ int overlap_len; ++ ++ verify_push_start = txmsg_start_push; ++ verify_pop_start = txmsg_start_pop; ++ if (txmsg_start_push < txmsg_start_pop) ++ overlap_len = min(push_range_end - txmsg_start_pop + 1, txmsg_pop); ++ else ++ overlap_len = min(pop_range_end - txmsg_start_push + 1, txmsg_end_push); ++ verify_push_len = max(txmsg_end_push - overlap_len, 0); ++ verify_pop_len = max(txmsg_pop - overlap_len, 0); ++ } else { ++ /* Otherwise */ ++ verify_push_start = txmsg_start_push; ++ verify_pop_start = txmsg_start_pop; ++ verify_push_len = txmsg_end_push; ++ verify_pop_len = txmsg_pop; ++ } ++} ++ + static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz, +- unsigned char *k_p, int *bytes_cnt_p) ++ unsigned char *k_p, int *bytes_cnt_p, ++ int *check_cnt_p, int *push_p) + { +- int i, j, bytes_cnt = *bytes_cnt_p; ++ int bytes_cnt = *bytes_cnt_p, check_cnt = *check_cnt_p, push = *push_p; + unsigned char k = *k_p; ++ int i, j; + + for (i = 0, j = 0; i < msg->msg_iovlen && size; i++, j = 0) { + unsigned char *d = msg->msg_iov[i].iov_base; +@@ -538,6 +571,37 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz, + } + + for (; j < msg->msg_iov[i].iov_len && size; j++) { ++ if (push > 0 && ++ check_cnt == verify_push_start + verify_push_len - push) { ++ int skipped; ++revisit_push: ++ skipped = push; ++ if (j + push >= msg->msg_iov[i].iov_len) ++ skipped = msg->msg_iov[i].iov_len - j; ++ push -= skipped; ++ size -= skipped; ++ j += skipped - 1; ++ check_cnt += skipped; ++ continue; ++ } ++ ++ if (verify_pop_len > 0 && check_cnt == verify_pop_start) { ++ bytes_cnt += verify_pop_len; ++ check_cnt += verify_pop_len; ++ k += verify_pop_len; ++ ++ if (bytes_cnt == chunk_sz) { ++ k = 0; ++ bytes_cnt = 0; ++ check_cnt = 0; ++ push = verify_push_len; ++ } ++ ++ if (push > 0 && ++ check_cnt == verify_push_start + verify_push_len - push) ++ goto revisit_push; ++ } ++ + if (d[j] != k++) { + fprintf(stderr, + "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n", +@@ -545,15 +609,20 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz, + return -EDATAINTEGRITY; + } + bytes_cnt++; ++ check_cnt++; + if (bytes_cnt == chunk_sz) { + k = 0; + bytes_cnt = 0; ++ check_cnt = 0; ++ push = verify_push_len; + } + size--; + } + } + *k_p = k; + *bytes_cnt_p = bytes_cnt; ++ *check_cnt_p = check_cnt; ++ *push_p = push; + return 0; + } + +@@ -608,6 +677,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + struct timeval timeout; + unsigned char k = 0; + int bytes_cnt = 0; ++ int check_cnt = 0; ++ int push = 0; + fd_set w; + + fcntl(fd, fd_flags); +@@ -633,6 +704,10 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + } + total_bytes += txmsg_push_total; + total_bytes -= txmsg_pop_total; ++ if (data) { ++ msg_verify_date_prep(); ++ push = verify_push_len; ++ } + err = clock_gettime(CLOCK_MONOTONIC, &s->start); + if (err < 0) + perror("recv start time"); +@@ -699,7 +774,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + iov_length : + iov_length * iov_count; + +- errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt); ++ errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt, ++ &check_cnt, &push); + if (errno) { + perror("data verify msg failed"); + goto out_errno; +@@ -709,7 +785,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + recvp, + chunk_sz, + &k, +- &bytes_cnt); ++ &bytes_cnt, ++ &check_cnt, ++ &push); + if (errno) { + perror("data verify msg_peek failed"); + goto out_errno; +@@ -1600,6 +1678,8 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt) + + static void test_txmsg_pop(int cgrp, struct sockmap_options *opt) + { ++ bool data = opt->data_test; ++ + /* Test basic pop */ + txmsg_pass = 1; + txmsg_start_pop = 1; +@@ -1618,6 +1698,12 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt) + txmsg_pop = 2; + test_send_many(opt, cgrp); + ++ /* TODO: Test for pop + cork should be different, ++ * - It makes the layout of the received data difficult ++ * - It makes it hard to calculate the total_bytes in the recvmsg ++ * Temporarily skip the data integrity test for this case now. ++ */ ++ opt->data_test = false; + /* Test pop + cork */ + txmsg_redir = 0; + txmsg_cork = 512; +@@ -1631,10 +1717,13 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt) + txmsg_start_pop = 1; + txmsg_pop = 2; + test_send_many(opt, cgrp); ++ opt->data_test = data; + } + + static void test_txmsg_push(int cgrp, struct sockmap_options *opt) + { ++ bool data = opt->data_test; ++ + /* Test basic push */ + txmsg_pass = 1; + txmsg_start_push = 1; +@@ -1653,12 +1742,19 @@ static void test_txmsg_push(int cgrp, struct sockmap_options *opt) + txmsg_end_push = 2; + test_send_many(opt, cgrp); + ++ /* TODO: Test for push + cork should be different, ++ * - It makes the layout of the received data difficult ++ * - It makes it hard to calculate the total_bytes in the recvmsg ++ * Temporarily skip the data integrity test for this case now. ++ */ ++ opt->data_test = false; + /* Test push + cork */ + txmsg_redir = 0; + txmsg_cork = 512; + txmsg_start_push = 1; + txmsg_end_push = 2; + test_send_many(opt, cgrp); ++ opt->data_test = data; + } + + static void test_txmsg_push_pop(int cgrp, struct sockmap_options *opt) +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch b/queue-5.10/selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch new file mode 100644 index 00000000000..9ea42ba7254 --- /dev/null +++ b/queue-5.10/selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch @@ -0,0 +1,80 @@ +From 0bcca23933b607b669783fd98423ecd28d6b545e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:13 +0000 +Subject: selftests/bpf: Add txmsg_pass to pull/push/pop in test_sockmap + +From: Zijian Zhang + +[ Upstream commit 66c54c20408d994be34be2c070fba08472f69eee ] + +Add txmsg_pass to test_txmsg_pull/push/pop. If txmsg_pass is missing, +tx_prog will be NULL, and no program will be attached to the sockmap. +As a result, pull/push/pop are never invoked. + +Fixes: 328aa08a081b ("bpf: Selftests, break down test_sockmap into subtests") +Signed-off-by: Zijian Zhang +Reviewed-by: John Fastabend +Link: https://lore.kernel.org/r/20241106222520.527076-2-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 157a3c7b735e2..cd3ecf12535c1 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -1547,11 +1547,13 @@ static void test_txmsg_cork_hangs(int cgrp, struct sockmap_options *opt) + static void test_txmsg_pull(int cgrp, struct sockmap_options *opt) + { + /* Test basic start/end */ ++ txmsg_pass = 1; + txmsg_start = 1; + txmsg_end = 2; + test_send(opt, cgrp); + + /* Test >4k pull */ ++ txmsg_pass = 1; + txmsg_start = 4096; + txmsg_end = 9182; + test_send_large(opt, cgrp); +@@ -1580,11 +1582,13 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt) + static void test_txmsg_pop(int cgrp, struct sockmap_options *opt) + { + /* Test basic pop */ ++ txmsg_pass = 1; + txmsg_start_pop = 1; + txmsg_pop = 2; + test_send_many(opt, cgrp); + + /* Test pop with >4k */ ++ txmsg_pass = 1; + txmsg_start_pop = 4096; + txmsg_pop = 4096; + test_send_large(opt, cgrp); +@@ -1613,11 +1617,13 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt) + static void test_txmsg_push(int cgrp, struct sockmap_options *opt) + { + /* Test basic push */ ++ txmsg_pass = 1; + txmsg_start_push = 1; + txmsg_end_push = 1; + test_send(opt, cgrp); + + /* Test push 4kB >4k */ ++ txmsg_pass = 1; + txmsg_start_push = 4096; + txmsg_end_push = 4096; + test_send_large(opt, cgrp); +@@ -1638,6 +1644,7 @@ static void test_txmsg_push(int cgrp, struct sockmap_options *opt) + + static void test_txmsg_push_pop(int cgrp, struct sockmap_options *opt) + { ++ txmsg_pass = 1; + txmsg_start_push = 1; + txmsg_end_push = 10; + txmsg_start_pop = 5; +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch b/queue-5.10/selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch new file mode 100644 index 00000000000..5fb92cc7b52 --- /dev/null +++ b/queue-5.10/selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch @@ -0,0 +1,150 @@ +From 2e970d42a024bfe4dac34bbbc64d46c8e32d63c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Oct 2024 20:37:30 +0000 +Subject: selftests/bpf: Fix msg_verify_data in test_sockmap + +From: Zijian Zhang + +[ Upstream commit ee9b352ce4650ffc0d8ca0ac373d7c009c7e561e ] + +Function msg_verify_data should have context of bytes_cnt and k instead of +assuming they are zero. Otherwise, test_sockmap with data integrity test +will report some errors. I also fix the logic related to size and index j + +1/ 6 sockmap::txmsg test passthrough:FAIL +2/ 6 sockmap::txmsg test redirect:FAIL +7/12 sockmap::txmsg test apply:FAIL +10/11 sockmap::txmsg test push_data:FAIL +11/17 sockmap::txmsg test pull-data:FAIL +12/ 9 sockmap::txmsg test pop-data:FAIL +13/ 1 sockmap::txmsg test push/pop data:FAIL +... +Pass: 24 Fail: 52 + +After applying this patch, some of the errors are solved, but for push, +pull and pop, we may need more fixes to msg_verify_data, added a TODO + +10/11 sockmap::txmsg test push_data:FAIL +11/17 sockmap::txmsg test pull-data:FAIL +12/ 9 sockmap::txmsg test pop-data:FAIL +... +Pass: 37 Fail: 15 + +Besides, added a custom errno EDATAINTEGRITY for msg_verify_data, we +shall not ignore the error in txmsg_cork case. + +Fixes: 753fb2ee0934 ("bpf: sockmap, add msg_peek tests to test_sockmap") +Fixes: 16edddfe3c5d ("selftests/bpf: test_sockmap, check test failure") +Acked-by: John Fastabend +Signed-off-by: Zijian Zhang +Link: https://lore.kernel.org/r/20241012203731.1248619-2-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 30 ++++++++++++++-------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 61be5993416e9..48c8f24cf9964 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -58,6 +58,8 @@ static void running_handler(int a); + #define BPF_SOCKHASH_FILENAME "test_sockhash_kern.o" + #define CG_PATH "/sockmap" + ++#define EDATAINTEGRITY 2001 ++ + /* global sockets */ + int s1, s2, c1, c2, p1, p2; + int test_cnt; +@@ -509,23 +511,25 @@ static int msg_alloc_iov(struct msghdr *msg, + return -ENOMEM; + } + +-static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz) ++/* TODO: Add verification logic for push, pull and pop data */ ++static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz, ++ unsigned char *k_p, int *bytes_cnt_p) + { +- int i, j = 0, bytes_cnt = 0; +- unsigned char k = 0; ++ int i, j, bytes_cnt = *bytes_cnt_p; ++ unsigned char k = *k_p; + +- for (i = 0; i < msg->msg_iovlen; i++) { ++ for (i = 0, j = 0; i < msg->msg_iovlen && size; i++, j = 0) { + unsigned char *d = msg->msg_iov[i].iov_base; + + /* Special case test for skb ingress + ktls */ + if (i == 0 && txmsg_ktls_skb) { + if (msg->msg_iov[i].iov_len < 4) +- return -EIO; ++ return -EDATAINTEGRITY; + if (memcmp(d, "PASS", 4) != 0) { + fprintf(stderr, + "detected skb data error with skb ingress update @iov[%i]:%i \"%02x %02x %02x %02x\" != \"PASS\"\n", + i, 0, d[0], d[1], d[2], d[3]); +- return -EIO; ++ return -EDATAINTEGRITY; + } + j = 4; /* advance index past PASS header */ + } +@@ -535,7 +539,7 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz) + fprintf(stderr, + "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n", + i, j, d[j], k - 1, d[j+1], k); +- return -EIO; ++ return -EDATAINTEGRITY; + } + bytes_cnt++; + if (bytes_cnt == chunk_sz) { +@@ -545,6 +549,8 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz) + size--; + } + } ++ *k_p = k; ++ *bytes_cnt_p = bytes_cnt; + return 0; + } + +@@ -593,6 +599,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + float total_bytes, txmsg_pop_total; + int fd_flags = O_NONBLOCK; + struct timeval timeout; ++ unsigned char k = 0; ++ int bytes_cnt = 0; + fd_set w; + + fcntl(fd, fd_flags); +@@ -671,7 +679,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + iov_length * cnt : + iov_length * iov_count; + +- errno = msg_verify_data(&msg, recv, chunk_sz); ++ errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt); + if (errno) { + perror("data verify msg failed"); + goto out_errno; +@@ -679,7 +687,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + if (recvp) { + errno = msg_verify_data(&msg_peek, + recvp, +- chunk_sz); ++ chunk_sz, ++ &k, ++ &bytes_cnt); + if (errno) { + perror("data verify msg_peek failed"); + goto out_errno; +@@ -770,7 +780,7 @@ static int sendmsg_test(struct sockmap_options *opt) + s.bytes_sent, sent_Bps, sent_Bps/giga, + s.bytes_recvd, recvd_Bps, recvd_Bps/giga, + peek_flag ? "(peek_msg)" : ""); +- if (err && txmsg_cork) ++ if (err && err != -EDATAINTEGRITY && txmsg_cork) + err = 0; + exit(err ? 1 : 0); + } else if (rxpid == -1) { +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch b/queue-5.10/selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch new file mode 100644 index 00000000000..7fe4c2a4d62 --- /dev/null +++ b/queue-5.10/selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch @@ -0,0 +1,86 @@ +From a303f2096a15e7a2f582e904f610dace8c32b49b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:14 +0000 +Subject: selftests/bpf: Fix SENDPAGE data logic in test_sockmap + +From: Zijian Zhang + +[ Upstream commit 4095031463d4e99b534d2cd82035a417295764ae ] + +In the SENDPAGE test, "opt->iov_length * cnt" size of data will be sent +cnt times by sendfile. +1. In push/pop tests, they will be invoked cnt times, for the simplicity of +msg_verify_data, change chunk_sz to iov_length +2. Change iov_length in test_send_large from 1024 to 8192. We have pop test +where txmsg_start_pop is 4096. 4096 > 1024, an error will be returned. + +Fixes: 328aa08a081b ("bpf: Selftests, break down test_sockmap into subtests") +Signed-off-by: Zijian Zhang +Reviewed-by: John Fastabend +Link: https://lore.kernel.org/r/20241106222520.527076-3-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index cd3ecf12535c1..46a1ca4f699e2 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -419,16 +419,18 @@ static int msg_loop_sendpage(int fd, int iov_length, int cnt, + { + bool drop = opt->drop_expected; + unsigned char k = 0; ++ int i, j, fp; + FILE *file; +- int i, fp; + + file = tmpfile(); + if (!file) { + perror("create file for sendpage"); + return 1; + } +- for (i = 0; i < iov_length * cnt; i++, k++) +- fwrite(&k, sizeof(char), 1, file); ++ for (i = 0; i < cnt; i++, k = 0) { ++ for (j = 0; j < iov_length; j++, k++) ++ fwrite(&k, sizeof(char), 1, file); ++ } + fflush(file); + fseek(file, 0, SEEK_SET); + +@@ -614,7 +616,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + * This is really only useful for testing edge cases in code + * paths. + */ +- total_bytes = (float)iov_count * (float)iov_length * (float)cnt; ++ total_bytes = (float)iov_length * (float)cnt; ++ if (!opt->sendpage) ++ total_bytes *= (float)iov_count; + if (txmsg_apply) + txmsg_pop_total = txmsg_pop * (total_bytes / txmsg_apply); + else +@@ -676,7 +680,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + + if (data) { + int chunk_sz = opt->sendpage ? +- iov_length * cnt : ++ iov_length : + iov_length * iov_count; + + errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt); +@@ -1425,8 +1429,8 @@ static void test_send_many(struct sockmap_options *opt, int cgrp) + + static void test_send_large(struct sockmap_options *opt, int cgrp) + { +- opt->iov_length = 256; +- opt->iov_count = 1024; ++ opt->iov_length = 8192; ++ opt->iov_count = 32; + opt->rate = 2; + test_exec(cgrp, opt); + } +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch b/queue-5.10/selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch new file mode 100644 index 00000000000..89902f0b579 --- /dev/null +++ b/queue-5.10/selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch @@ -0,0 +1,71 @@ +From 8b23b22ddc044aa73937cc765843bddbae2db7b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 22:25:15 +0000 +Subject: selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap + +From: Zijian Zhang + +[ Upstream commit 523dffccbadea0cfd65f1ff04944b864c558c4a8 ] + +total_bytes in msg_loop_rx should also take push into account, otherwise +total_bytes will be a smaller value, which makes the msg_loop_rx end early. + +Besides, total_bytes has already taken pop into account, so we don't need +to subtract some bytes from iov_buf in sendmsg_test. The additional +subtraction may make total_bytes a negative number, and msg_loop_rx will +just end without checking anything. + +Fixes: 18d4e900a450 ("bpf: Selftests, improve test_sockmap total bytes counter") +Fixes: d69672147faa ("selftests, bpf: Add one test for sockmap with strparser") +Signed-off-by: Zijian Zhang +Reviewed-by: John Fastabend +Link: https://lore.kernel.org/r/20241106222520.527076-4-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 89d215416a34e..85d6fac7124bd 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -602,8 +602,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + } + clock_gettime(CLOCK_MONOTONIC, &s->end); + } else { ++ float total_bytes, txmsg_pop_total, txmsg_push_total; + int slct, recvp = 0, recv, max_fd = fd; +- float total_bytes, txmsg_pop_total; + int fd_flags = O_NONBLOCK; + struct timeval timeout; + unsigned char k = 0; +@@ -624,10 +624,14 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + total_bytes = (float)iov_length * (float)cnt; + if (!opt->sendpage) + total_bytes *= (float)iov_count; +- if (txmsg_apply) ++ if (txmsg_apply) { ++ txmsg_push_total = txmsg_end_push * (total_bytes / txmsg_apply); + txmsg_pop_total = txmsg_pop * (total_bytes / txmsg_apply); +- else ++ } else { ++ txmsg_push_total = txmsg_end_push * cnt; + txmsg_pop_total = txmsg_pop * cnt; ++ } ++ total_bytes += txmsg_push_total; + total_bytes -= txmsg_pop_total; + err = clock_gettime(CLOCK_MONOTONIC, &s->start); + if (err < 0) +@@ -771,8 +775,6 @@ static int sendmsg_test(struct sockmap_options *opt) + + rxpid = fork(); + if (rxpid == 0) { +- if (txmsg_pop || txmsg_start_pop) +- iov_buf -= (txmsg_pop - txmsg_start_pop + 1); + if (opt->drop_expected || txmsg_ktls_skb_drop) + _exit(0); + +-- +2.43.0 + diff --git a/queue-5.10/selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch b/queue-5.10/selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch new file mode 100644 index 00000000000..6901c25811b --- /dev/null +++ b/queue-5.10/selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch @@ -0,0 +1,38 @@ +From 272c3cf81a7cf38295feaf607361d91b148fbd58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Oct 2024 20:37:31 +0000 +Subject: selftests/bpf: Fix txmsg_redir of test_txmsg_pull in test_sockmap + +From: Zijian Zhang + +[ Upstream commit b29e231d66303c12b7b8ac3ac2a057df06b161e8 ] + +txmsg_redir in "Test pull + redirect" case of test_txmsg_pull should be +1 instead of 0. + +Fixes: 328aa08a081b ("bpf: Selftests, break down test_sockmap into subtests") +Acked-by: John Fastabend +Signed-off-by: Zijian Zhang +Link: https://lore.kernel.org/r/20241012203731.1248619-3-zijianzhang@bytedance.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_sockmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c +index 48c8f24cf9964..157a3c7b735e2 100644 +--- a/tools/testing/selftests/bpf/test_sockmap.c ++++ b/tools/testing/selftests/bpf/test_sockmap.c +@@ -1557,7 +1557,7 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt) + test_send_large(opt, cgrp); + + /* Test pull + redirect */ +- txmsg_redir = 0; ++ txmsg_redir = 1; + txmsg_start = 1; + txmsg_end = 2; + test_send(opt, cgrp); +-- +2.43.0 + diff --git a/queue-5.10/selftests-net-really-check-for-bg-process-completion.patch b/queue-5.10/selftests-net-really-check-for-bg-process-completion.patch new file mode 100644 index 00000000000..0a520395482 --- /dev/null +++ b/queue-5.10/selftests-net-really-check-for-bg-process-completion.patch @@ -0,0 +1,43 @@ +From 0617b931f4b510e4cdcf7ff2ad594ae683cd88cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 19:23:51 +0100 +Subject: selftests: net: really check for bg process completion + +From: Paolo Abeni + +[ Upstream commit 52ed077aa6336dbef83a2d6d21c52d1706fb7f16 ] + +A recent refactor transformed the check for process completion +in a true statement, due to a typo. + +As a result, the relevant test-case is unable to catch the +regression it was supposed to detect. + +Restore the correct condition. + +Fixes: 691bb4e49c98 ("selftests: net: avoid just another constant wait") +Signed-off-by: Paolo Abeni +Reviewed-by: David Ahern +Link: https://patch.msgid.link/0e6f213811f8e93a235307e683af8225cc6277ae.1730828007.git.pabeni@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/pmtu.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index 9cd5cf800a5b5..f4116f0723e3f 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -1587,7 +1587,7 @@ check_running() { + pid=${1} + cmd=${2} + +- [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "{cmd}" ] ++ [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "${cmd}" ] + } + + test_cleanup_vxlanX_exception() { +-- +2.43.0 + diff --git a/queue-5.10/selftests-resctrl-protect-against-array-overrun-duri.patch b/queue-5.10/selftests-resctrl-protect-against-array-overrun-duri.patch new file mode 100644 index 00000000000..09a2d9bd533 --- /dev/null +++ b/queue-5.10/selftests-resctrl-protect-against-array-overrun-duri.patch @@ -0,0 +1,67 @@ +From b09717be20895a61d5df76e0a2156deddff3f599 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Oct 2024 14:18:41 -0700 +Subject: selftests/resctrl: Protect against array overrun during iMC config + parsing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Reinette Chatre + +[ Upstream commit 48ed4e799e8fbebae838dca404a8527763d41191 ] + +The MBM and MBA tests need to discover the event and umask with which to +configure the performance event used to measure read memory bandwidth. +This is done by parsing the +/sys/bus/event_source/devices/uncore_imc_/events/cas_count_read +file for each iMC instance that contains the formatted +output: "event=,umask=" + +Parsing of cas_count_read contents is done by initializing an array of +MAX_TOKENS elements with tokens (deliminated by "=,") from this file. +Remove the unnecessary append of a delimiter to the string needing to be +parsed. Per the strtok() man page: "delimiter bytes at the start or end of +the string are ignored". This has no impact on the token placement within +the array. + +After initialization, the actual event and umask is determined by +parsing the tokens directly following the "event" and "umask" tokens +respectively. + +Iterating through the array up to index "i < MAX_TOKENS" but then +accessing index "i + 1" risks array overrun during the final iteration. +Avoid array overrun by ensuring that the index used within for +loop will always be valid. + +Fixes: 1d3f08687d76 ("selftests/resctrl: Read memory bandwidth from perf IMC counter and from resctrl file system") +Signed-off-by: Reinette Chatre +Reviewed-by: Ilpo Järvinen +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/resctrl/resctrl_val.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c +index 8df557894059a..a93fab28f97ec 100644 +--- a/tools/testing/selftests/resctrl/resctrl_val.c ++++ b/tools/testing/selftests/resctrl/resctrl_val.c +@@ -102,13 +102,12 @@ void get_event_and_umask(char *cas_count_cfg, int count, bool op) + char *token[MAX_TOKENS]; + int i = 0; + +- strcat(cas_count_cfg, ","); + token[0] = strtok(cas_count_cfg, "=,"); + + for (i = 1; i < MAX_TOKENS; i++) + token[i] = strtok(NULL, "=,"); + +- for (i = 0; i < MAX_TOKENS; i++) { ++ for (i = 0; i < MAX_TOKENS - 1; i++) { + if (!token[i]) + break; + if (strcmp(token[i], "event") == 0) { +-- +2.43.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 1ad8851164b..c9d7e1e1b3e 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -40,3 +40,194 @@ rcu-tasks-idle-tasks-on-offline-cpus-are-in-quiescen.patch x86-stackprotector-work-around-strict-clang-tls-symb.patch cifs-fix-buffer-overflow-when-parsing-nfs-reparse-po.patch nvme-fix-metadata-handling-in-nvme-passthrough.patch +x86-barrier-do-not-serialize-msr-accesses-on-amd.patch +kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch +x86-xen-pvh-annotate-indirect-branch-as-safe.patch +x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch +x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch +mips-asm-fix-warning-when-disabling-mips_fp_support.patch +initramfs-avoid-filename-buffer-overrun.patch +nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch +m68k-mvme147-fix-scsi-controller-irq-numbers.patch +m68k-mvme16x-add-and-use-mvme16x.h.patch +m68k-mvme147-reinstate-early-console.patch +arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch +acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch +s390-syscalls-avoid-creation-of-arch-arch-directory.patch +hfsplus-don-t-query-the-device-logical-block-size-mu.patch +crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch +firmware-google-unregister-driver_info-on-failure.patch +edac-bluefield-fix-potential-integer-overflow.patch +edac-fsl_ddr-fix-bad-bit-shift-operations.patch +crypto-pcrypt-call-crypto-layer-directly-when-padata.patch +crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch +crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch +crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch +crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch +time-fix-references-to-_msecs_to_jiffies-handling-of.patch +kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch +clkdev-remove-config_clkdev_lookup.patch +clocksource-drivers-sp804-make-user-selectable.patch +clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch +spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch +spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch +soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch +soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch +mmc-mmc_spi-drop-buggy-snprintf.patch +tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch +arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch +arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch +revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch +cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch +pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch +arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch +pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch +regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch +selftests-resctrl-protect-against-array-overrun-duri.patch +firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch +media-atomisp-remove-ifdef-has_no_hmem.patch +media-atomisp-add-check-for-rgby_data-memory-allocat.patch +drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch +wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch +drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch +wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch +wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch +drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch +drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch +drm-v3d-address-race-condition-in-mmu-flush.patch +wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch +wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150 +dt-bindings-vendor-prefixes-add-neofidelity-inc.patch +asoc-fsl_micfil-drop-unnecessary-register-read.patch +asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch +asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch +asoc-fsl_micfil-fix-regmap_write_bits-usage.patch +asoc-dt-bindings-mt6359-update-generic-node-name-and.patch +bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch +xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch +xfrm-store-and-rely-on-direction-to-construct-offloa.patch +netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch +netdevsim-copy-addresses-for-both-in-and-out-paths.patch +drm-bridge-tc358767-fix-link-properties-discovery.patch +selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch +selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch +wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch +drm-fsl-dcu-convert-to-linux-irq-interfaces.patch +drm-fsl-dcu-enable-pixclk-on-ls1021a.patch +octeontx2-af-mbox-changes-for-98xx.patch +octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch +octeontx2-af-forward-error-correction-configuration.patch +octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch +octeontx2-pf-ethtool-fec-mode-support.patch +octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch +drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch +drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch +drm-etnaviv-rework-linear-window-offset-calculation.patch +drm-etnaviv-request-pages-from-dma32-zone-on-address.patch +drm-etnaviv-dump-fix-sparse-warnings.patch +drm-etnaviv-fix-power-register-offset-on-gc300.patch +drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch +wifi-wfx-fix-error-handling-in-wfx_core_init.patch +drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch +netlink-typographical-error-in-nlmsg_type-constants-.patch +selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch +selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch +selftests-bpf-add-one-test-for-sockmap-with-strparse.patch +selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch +selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch +bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch +bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch +bpf-sockmap-fix-sk_msg_reset_curr.patch +selftests-net-really-check-for-bg-process-completion.patch +drm-amdkfd-fix-wrong-usage-of-init_work.patch +net-rfkill-gpio-add-check-for-clk_enable.patch +alsa-usx2y-fix-spaces.patch +alsa-usx2y-coding-style-fixes.patch +alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch +alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch +alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch +alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch +alsa-6fire-release-resources-at-card-release.patch +driver-core-introduce-device_find_any_child-helper.patch +bluetooth-fix-use-after-free-in-device_for_each_chil.patch +netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch +wireguard-selftests-load-nf_conntrack-if-not-present.patch +trace-trace_event_perf-remove-duplicate-samples-on-t.patch +powerpc-vdso-flag-vdso64-entry-points-as-functions.patch +mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch +mfd-da9052-spi-change-read-mask-to-write-mask.patch +mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch +mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch +mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch +mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch +cpufreq-loongson2-unregister-platform_driver-on-fail.patch +mtd-rawnand-atmel-fix-possible-memory-leak.patch +powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch +rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch +mfd-rt5033-fix-missing-regmap_del_irq_chip.patch +scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch +scsi-fusion-remove-unused-variable-rc.patch +scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch +scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch +rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch +ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch +powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch +powerpc-kexec-fix-return-of-uninitialized-variable.patch +fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch +fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch +dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch +dt-bindings-clock-axi-clkgen-include-axi-clk.patch +clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch +clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch +perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch +perf-probe-fix-libdw-memory-leak.patch +perf-probe-correct-demangled-symbols-in-c-program.patch +pci-cpqphp-use-pci_possible_error-to-check-config-re.patch +pci-cpqphp-fix-pcibios_-return-value-confusion.patch +f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch +f2fs-avoid-using-native-allocate_segment_by_default.patch +f2fs-remove-struct-segment_allocation-default_salloc.patch +f2fs-open-code-allocate_segment_by_default.patch +f2fs-remove-the-unused-flush-argument-to-change_curs.patch +f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch +perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch +m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch +m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch +perf-trace-do-not-lose-last-events-in-a-race.patch +perf-trace-avoid-garbage-when-not-printing-a-syscall.patch +rpmsg-glink-add-tx_data_cont-command-while-sending.patch +rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch +rpmsg-glink-fix-glink-command-prefix.patch +rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch +remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch +nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch +nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch +nfsd-fix-nfsd4_shutdown_copy.patch +vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch +vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch +fs_parser-update-mount_api-doc-to-match-function-sig.patch +power-supply-core-remove-might_sleep-from-power_supp.patch +power-supply-bq27xxx-support-charge_now-for-bq27z561.patch +power-supply-bq27xxx-fix-registers-of-bq27426.patch +net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch +tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch +net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch +marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch +net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch +spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch +net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch +net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch +bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch +ipmr-convert-proc-handlers-to-rcu_read_lock.patch +ipmr-fix-tables-suspicious-rcu-usage.patch +iio-light-al3010-fix-an-error-handling-path-in-al301.patch +usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch +usb-yurex-make-waiting-on-yurex_write-interruptible.patch +usb-chaoskey-fail-open-after-removal.patch +usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch +misc-apds990x-fix-missing-pm_runtime_disable.patch +staging-greybus-uart-clean-up-tiocgserial.patch +staging-greybus-uart-fix-atomicity-violation-in-get_.patch +alsa-hda-realtek-add-type-for-alc287.patch +alsa-hda-realtek-update-alc256-depop-procedure.patch +apparmor-fix-do-simple-duplicate-message-elimination.patch diff --git a/queue-5.10/soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch b/queue-5.10/soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch new file mode 100644 index 00000000000..b8210cf187a --- /dev/null +++ b/queue-5.10/soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch @@ -0,0 +1,40 @@ +From 113682d80d99f9b4ebf05801a26f45d3bab7bc90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 10:51:31 +0300 +Subject: soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get() + +From: Dan Carpenter + +[ Upstream commit 78261cb08f06c93d362cab5c5034bf5899bc7552 ] + +This loop is supposed to break if the frequency returned from +clk_round_rate() is the same as on the previous iteration. However, +that check doesn't make sense on the first iteration through the loop. +It leads to reading before the start of these->clk_perf_tbl[] array. + +Fixes: eddac5af0654 ("soc: qcom: Add GENI based QUP Wrapper driver") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/8cd12678-f44a-4b16-a579-c8f11175ee8c@stanley.mountain +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/qcom-geni-se.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c +index 0dbca679bd32f..0d4b48f135855 100644 +--- a/drivers/soc/qcom/qcom-geni-se.c ++++ b/drivers/soc/qcom/qcom-geni-se.c +@@ -553,7 +553,8 @@ int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl) + + for (i = 0; i < MAX_CLK_PERF_LEVEL; i++) { + freq = clk_round_rate(se->clk, freq + 1); +- if (freq <= 0 || freq == se->clk_perf_tbl[i - 1]) ++ if (freq <= 0 || ++ (i > 0 && freq == se->clk_perf_tbl[i - 1])) + break; + se->clk_perf_tbl[i] = freq; + } +-- +2.43.0 + diff --git a/queue-5.10/soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch b/queue-5.10/soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch new file mode 100644 index 00000000000..0186bde6ed4 --- /dev/null +++ b/queue-5.10/soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch @@ -0,0 +1,45 @@ +From 54f388470c66c0e5e0ff03f9bad3c8db56e241e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2024 11:41:47 +0800 +Subject: soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit 16a0a69244240cfa32c525c021c40f85e090557a ] + +If request_irq() fails in sr_late_init(), there is no need to enable +the irq, and if it succeeds, disable_irq() after request_irq() still has +a time gap in which interrupts can come. + +request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when +request IRQ. + +Fixes: 1279ba5916f6 ("OMAP3+: SR: disable interrupt by default") +Signed-off-by: Jinjie Ruan +Link: https://lore.kernel.org/r/20240912034147.3014213-1-ruanjinjie@huawei.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + drivers/soc/ti/smartreflex.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c +index 1228a0cba1320..8330098b45df9 100644 +--- a/drivers/soc/ti/smartreflex.c ++++ b/drivers/soc/ti/smartreflex.c +@@ -213,10 +213,10 @@ static int sr_late_init(struct omap_sr *sr_info) + + if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { + ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq, +- sr_interrupt, 0, sr_info->name, sr_info); ++ sr_interrupt, IRQF_NO_AUTOEN, ++ sr_info->name, sr_info); + if (ret) + goto error; +- disable_irq(sr_info->irq); + } + + if (pdata && pdata->enable_on_init) +-- +2.43.0 + diff --git a/queue-5.10/spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch b/queue-5.10/spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch new file mode 100644 index 00000000000..88f632d6401 --- /dev/null +++ b/queue-5.10/spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch @@ -0,0 +1,43 @@ +From 08893b2c6b5872c908f46f4721aa620328307071 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 15:13:02 +0100 +Subject: spi: atmel-quadspi: Fix register name in verbose logging function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Csókás, Bence + +[ Upstream commit 2ac40e6d0ccdd93031f8b1af61b0fe5cdd704923 ] + +`atmel_qspi_reg_name()` is used for pretty-printing register offsets +for verbose logging of register accesses. However, due to a typo +(likely a copy-paste error), QSPI_RD's offset prints as "MR", the +name of the previous register. Fix this typo. + +Fixes: c528ecfbef04 ("spi: atmel-quadspi: Add verbose debug facilities to monitor register accesses") +Signed-off-by: Csókás, Bence +Reviewed-by: Alexander Dahl +Link: https://patch.msgid.link/20241122141302.2599636-1-csokas.bence@prolan.hu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/atmel-quadspi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c +index 8aa89d93db118..17217cc5e4052 100644 +--- a/drivers/spi/atmel-quadspi.c ++++ b/drivers/spi/atmel-quadspi.c +@@ -182,7 +182,7 @@ static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz) + case QSPI_MR: + return "MR"; + case QSPI_RD: +- return "MR"; ++ return "RD"; + case QSPI_TD: + return "TD"; + case QSPI_SR: +-- +2.43.0 + diff --git a/queue-5.10/spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch b/queue-5.10/spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch new file mode 100644 index 00000000000..bf7e9fa8e7d --- /dev/null +++ b/queue-5.10/spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch @@ -0,0 +1,38 @@ +From 8bcedf8c260791a7cd106395d4f4615df0ef32fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 May 2023 09:28:49 +0200 +Subject: spi: spi-fsl-lpspi: downgrade log level for pio mode + +From: Alexander Stein + +[ Upstream commit d5786c88cacbb859f465e8e93c26154585c1008d ] + +Having no DMA is not an error. The simplest reason is not having it +configured. SPI will still be usable, so raise a warning instead to +get still some attention. + +Signed-off-by: Alexander Stein +Link: https://lore.kernel.org/r/20230531072850.739021-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Stable-dep-of: 003c7e01916c ("spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq()") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-fsl-lpspi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c +index 8ab3105ae8c07..efd2a9b6a9b26 100644 +--- a/drivers/spi/spi-fsl-lpspi.c ++++ b/drivers/spi/spi-fsl-lpspi.c +@@ -909,7 +909,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) + if (ret == -EPROBE_DEFER) + goto out_pm_get; + if (ret < 0) +- dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret); ++ dev_warn(&pdev->dev, "dma setup error %d, use pio\n", ret); + else + /* + * disable LPSPI module IRQ when enable DMA mode successfully, +-- +2.43.0 + diff --git a/queue-5.10/spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch b/queue-5.10/spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch new file mode 100644 index 00000000000..2618c47d0a5 --- /dev/null +++ b/queue-5.10/spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch @@ -0,0 +1,56 @@ +From cdcbe683f03d64da2a40349de2ded83fbb1dc0d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Sep 2024 10:28:28 +0800 +Subject: spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit 003c7e01916c5e2af95add9b0cbda2e6163873e8 ] + +disable_irq() after request_irq() still has a time gap in which +interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will +disable IRQ auto-enable when request IRQ. + +Fixes: 9728fb3ce117 ("spi: lpspi: disable lpspi module irq in DMA mode") +Signed-off-by: Jinjie Ruan +Link: https://patch.msgid.link/20240906022828.891812-1-ruanjinjie@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-fsl-lpspi.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c +index efd2a9b6a9b26..bf3f600bdd2c8 100644 +--- a/drivers/spi/spi-fsl-lpspi.c ++++ b/drivers/spi/spi-fsl-lpspi.c +@@ -871,7 +871,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) + goto out_controller_put; + } + +- ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0, ++ ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, IRQF_NO_AUTOEN, + dev_name(&pdev->dev), fsl_lpspi); + if (ret) { + dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret); +@@ -908,14 +908,10 @@ static int fsl_lpspi_probe(struct platform_device *pdev) + ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller); + if (ret == -EPROBE_DEFER) + goto out_pm_get; +- if (ret < 0) ++ if (ret < 0) { + dev_warn(&pdev->dev, "dma setup error %d, use pio\n", ret); +- else +- /* +- * disable LPSPI module IRQ when enable DMA mode successfully, +- * to prevent the unexpected LPSPI module IRQ events. +- */ +- disable_irq(irq); ++ enable_irq(irq); ++ } + + ret = devm_spi_register_controller(&pdev->dev, controller); + if (ret < 0) { +-- +2.43.0 + diff --git a/queue-5.10/staging-greybus-uart-clean-up-tiocgserial.patch b/queue-5.10/staging-greybus-uart-clean-up-tiocgserial.patch new file mode 100644 index 00000000000..170fb3c961f --- /dev/null +++ b/queue-5.10/staging-greybus-uart-clean-up-tiocgserial.patch @@ -0,0 +1,60 @@ +From 3c894fa939bbe56314fa7c33ece04c809acb1565 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Apr 2021 12:23:25 +0200 +Subject: staging: greybus: uart: clean up TIOCGSERIAL + +From: Johan Hovold + +[ Upstream commit d38be702452137fa82a56ff7cc577d829add1637 ] + +TIOCSSERIAL is a horrid, underspecified, legacy interface which for most +serial devices is only useful for setting the close_delay and +closing_wait parameters. + +The xmit_fifo_size parameter could be used to set the hardware transmit +fifo size of a legacy UART when it could not be detected, but the +interface is limited to eight bits and should be left unset when not +used. + +Similarly, baud_base could be used to set the UART base clock when it +could not be detected but might as well be left unset when it is not +known. + +The type parameter could be used to set the UART type, but is +better left unspecified (type unknown) when it isn't used. + +Note that some applications have historically expected TIOCGSERIAL to be +implemented, but judging from the Debian sources, the port type not +being PORT_UNKNOWN is only used to check for the existence of legacy +serial ports (ttySn). Notably USB serial drivers like ftdi_sio have been +using PORT_UNKNOWN for twenty years without any problems. + +Drop the bogus values provided by the greybus implementation. + +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210407102334.32361-8-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: fe0ebeafc3b7 ("staging: greybus: uart: Fix atomicity violation in get_serial_info()") +Signed-off-by: Sasha Levin +--- + drivers/staging/greybus/uart.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c +index edaa83a693d27..5cdc5dff9f55b 100644 +--- a/drivers/staging/greybus/uart.c ++++ b/drivers/staging/greybus/uart.c +@@ -610,10 +610,7 @@ static int get_serial_info(struct tty_struct *tty, + { + struct gb_tty *gb_tty = tty->driver_data; + +- ss->type = PORT_16550A; + ss->line = gb_tty->minor; +- ss->xmit_fifo_size = 16; +- ss->baud_base = 9600; + ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10; + ss->closing_wait = + gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? +-- +2.43.0 + diff --git a/queue-5.10/staging-greybus-uart-fix-atomicity-violation-in-get_.patch b/queue-5.10/staging-greybus-uart-fix-atomicity-violation-in-get_.patch new file mode 100644 index 00000000000..f12e0027df4 --- /dev/null +++ b/queue-5.10/staging-greybus-uart-fix-atomicity-violation-in-get_.patch @@ -0,0 +1,49 @@ +From 063dd345b5a511167552b9dfcd2dd8fc565f48bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Nov 2024 19:33:37 +0800 +Subject: staging: greybus: uart: Fix atomicity violation in get_serial_info() + +From: Qiu-ji Chen + +[ Upstream commit fe0ebeafc3b723b2f8edf27ecec6d353b08397df ] + +Our static checker found a bug where set_serial_info() uses a mutex, but +get_serial_info() does not. Fortunately, the impact of this is relatively +minor. It doesn't cause a crash or any other serious issues. However, if a +race condition occurs between set_serial_info() and get_serial_info(), +there is a chance that the data returned by get_serial_info() will be +meaningless. + +Signed-off-by: Qiu-ji Chen +Fixes: 0aad5ad563c8 ("greybus/uart: switch to ->[sg]et_serial()") +Reviewed-by: Johan Hovold +Reviewed-by: Dan Carpenter +Reviewed-by: Alex Elder +Link: https://lore.kernel.org/r/20241107113337.402042-1-chenqiuji666@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/greybus/uart.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c +index 5cdc5dff9f55b..257f917a93745 100644 +--- a/drivers/staging/greybus/uart.c ++++ b/drivers/staging/greybus/uart.c +@@ -611,11 +611,13 @@ static int get_serial_info(struct tty_struct *tty, + struct gb_tty *gb_tty = tty->driver_data; + + ss->line = gb_tty->minor; ++ mutex_lock(&gb_tty->port.mutex); + ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10; + ss->closing_wait = + gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : + jiffies_to_msecs(gb_tty->port.closing_wait) / 10; ++ mutex_unlock(&gb_tty->port.mutex); + + return 0; + } +-- +2.43.0 + diff --git a/queue-5.10/tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch b/queue-5.10/tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch new file mode 100644 index 00000000000..ce2b23fc380 --- /dev/null +++ b/queue-5.10/tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch @@ -0,0 +1,61 @@ +From 3862196fd9b065cf8ac75077473f132492ea6e9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Nov 2024 21:57:41 -0800 +Subject: tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets + +From: Pavan Chebbi + +[ Upstream commit 614f4d166eeeb9bd709b0ad29552f691c0f45776 ] + +The hardware on Broadcom 1G chipsets have a known limitation +where they cannot handle DMA addresses that cross over 4GB. +When such an address is encountered, the hardware sets the +address overflow error bit in the DMA status register and +triggers a reset. + +However, BCM57766 hardware is setting the overflow bit and +triggering a reset in some cases when there is no actual +underlying address overflow. The hardware team analyzed the +issue and concluded that it is happening when the status +block update has an address with higher (b16 to b31) bits +as 0xffff following a previous update that had lowest bits +as 0xffff. + +To work around this bug in the BCM57766 hardware, set the +coherent dma mask from the current 64b to 31b. This will +ensure that upper bits of the status block DMA address are +always at most 0x7fff, thus avoiding the improper overflow +check described above. This work around is intended for only +status block and ring memories and has no effect on TX and +RX buffers as they do not require coherent memory. + +Fixes: 72f2afb8a685 ("[TG3]: Add DMA address workaround") +Reported-by: Salam Noureddine +Reviewed-by: Kalesh AP +Reviewed-by: Somnath Kotur +Signed-off-by: Pavan Chebbi +Reviewed-by: Michal Kubiak +Link: https://patch.msgid.link/20241119055741.147144-1-pavan.chebbi@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/tg3.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index fe2c9b110e606..937579817f226 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -17807,6 +17807,9 @@ static int tg3_init_one(struct pci_dev *pdev, + } else + persist_dma_mask = dma_mask = DMA_BIT_MASK(64); + ++ if (tg3_asic_rev(tp) == ASIC_REV_57766) ++ persist_dma_mask = DMA_BIT_MASK(31); ++ + /* Configure DMA attributes. */ + if (dma_mask > DMA_BIT_MASK(32)) { + err = pci_set_dma_mask(pdev, dma_mask); +-- +2.43.0 + diff --git a/queue-5.10/time-fix-references-to-_msecs_to_jiffies-handling-of.patch b/queue-5.10/time-fix-references-to-_msecs_to_jiffies-handling-of.patch new file mode 100644 index 00000000000..58810152d2c --- /dev/null +++ b/queue-5.10/time-fix-references-to-_msecs_to_jiffies-handling-of.patch @@ -0,0 +1,55 @@ +From 43aba77dab02a79d1b698d83b5221eeca448f606 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Oct 2024 13:01:41 +0200 +Subject: time: Fix references to _msecs_to_jiffies() handling of values + +From: Miguel Ojeda + +[ Upstream commit 92b043fd995a63a57aae29ff85a39b6f30cd440c ] + +The details about the handling of the "normal" values were moved +to the _msecs_to_jiffies() helpers in commit ca42aaf0c861 ("time: +Refactor msecs_to_jiffies"). However, the same commit still mentioned +__msecs_to_jiffies() in the added documentation. + +Thus point to _msecs_to_jiffies() instead. + +Fixes: ca42aaf0c861 ("time: Refactor msecs_to_jiffies") +Signed-off-by: Miguel Ojeda +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/all/20241025110141.157205-2-ojeda@kernel.org +Signed-off-by: Sasha Levin +--- + include/linux/jiffies.h | 2 +- + kernel/time/time.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h +index 5e13f801c9021..3778e26f7b14c 100644 +--- a/include/linux/jiffies.h ++++ b/include/linux/jiffies.h +@@ -349,7 +349,7 @@ static inline unsigned long _msecs_to_jiffies(const unsigned int m) + * - all other values are converted to jiffies by either multiplying + * the input value by a factor or dividing it with a factor and + * handling any 32-bit overflows. +- * for the details see __msecs_to_jiffies() ++ * for the details see _msecs_to_jiffies() + * + * msecs_to_jiffies() checks for the passed in value being a constant + * via __builtin_constant_p() allowing gcc to eliminate most of the +diff --git a/kernel/time/time.c b/kernel/time/time.c +index 3985b2b32d083..483f8a3e24d0c 100644 +--- a/kernel/time/time.c ++++ b/kernel/time/time.c +@@ -539,7 +539,7 @@ EXPORT_SYMBOL(ns_to_timespec64); + * - all other values are converted to jiffies by either multiplying + * the input value by a factor or dividing it with a factor and + * handling any 32-bit overflows. +- * for the details see __msecs_to_jiffies() ++ * for the details see _msecs_to_jiffies() + * + * msecs_to_jiffies() checks for the passed in value being a constant + * via __builtin_constant_p() allowing gcc to eliminate most of the +-- +2.43.0 + diff --git a/queue-5.10/tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch b/queue-5.10/tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch new file mode 100644 index 00000000000..fc9139bbf6e --- /dev/null +++ b/queue-5.10/tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch @@ -0,0 +1,83 @@ +From e41f4d728dc2387fb2e126353359772ecd0ff42d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Sep 2024 19:19:51 -0400 +Subject: tpm: fix signed/unsigned bug when checking event logs + +From: Gregory Price + +[ Upstream commit e6d654e9f5a97742cfe794b1c4bb5d3fb2d25e98 ] + +A prior bugfix that fixes a signed/unsigned error causes +another signed unsigned error. + +A situation where log_tbl->size is invalid can cause the +size passed to memblock_reserve to become negative. + +log_size from the main event log is an unsigned int, and +the code reduces to the following + +u64 value = (int)unsigned_value; + +This results in sign extension, and the value sent to +memblock_reserve becomes effectively negative. + +Fixes: be59d57f9806 ("efi/tpm: Fix sanity check of unsigned tbl_size being less than zero") +Signed-off-by: Gregory Price +Reviewed-by: Ilias Apalodimas +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/tpm.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c +index e8d69bd548f3f..9c3613e6af158 100644 +--- a/drivers/firmware/efi/tpm.c ++++ b/drivers/firmware/efi/tpm.c +@@ -40,7 +40,8 @@ int __init efi_tpm_eventlog_init(void) + { + struct linux_efi_tpm_eventlog *log_tbl; + struct efi_tcg2_final_events_table *final_tbl; +- int tbl_size; ++ unsigned int tbl_size; ++ int final_tbl_size; + int ret = 0; + + if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) { +@@ -80,26 +81,26 @@ int __init efi_tpm_eventlog_init(void) + goto out; + } + +- tbl_size = 0; ++ final_tbl_size = 0; + if (final_tbl->nr_events != 0) { + void *events = (void *)efi.tpm_final_log + + sizeof(final_tbl->version) + + sizeof(final_tbl->nr_events); + +- tbl_size = tpm2_calc_event_log_size(events, +- final_tbl->nr_events, +- log_tbl->log); ++ final_tbl_size = tpm2_calc_event_log_size(events, ++ final_tbl->nr_events, ++ log_tbl->log); + } + +- if (tbl_size < 0) { ++ if (final_tbl_size < 0) { + pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n"); + ret = -EINVAL; + goto out_calc; + } + + memblock_reserve(efi.tpm_final_log, +- tbl_size + sizeof(*final_tbl)); +- efi_tpm_final_log_size = tbl_size; ++ final_tbl_size + sizeof(*final_tbl)); ++ efi_tpm_final_log_size = final_tbl_size; + + out_calc: + early_memunmap(final_tbl, sizeof(*final_tbl)); +-- +2.43.0 + diff --git a/queue-5.10/trace-trace_event_perf-remove-duplicate-samples-on-t.patch b/queue-5.10/trace-trace_event_perf-remove-duplicate-samples-on-t.patch new file mode 100644 index 00000000000..2afb88b9e9d --- /dev/null +++ b/queue-5.10/trace-trace_event_perf-remove-duplicate-samples-on-t.patch @@ -0,0 +1,83 @@ +From 6e99234923ab7be15830c0a961633c304763e5e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Sep 2024 03:13:47 +0100 +Subject: trace/trace_event_perf: remove duplicate samples on the first + tracepoint event + +From: Levi Yun + +[ Upstream commit afe5960dc208fe069ddaaeb0994d857b24ac19d1 ] + +When a tracepoint event is created with attr.freq = 1, +'hwc->period_left' is not initialized correctly. As a result, +in the perf_swevent_overflow() function, when the first time the event occurs, +it calculates the event overflow and the perf_swevent_set_period() returns 3, +this leads to the event are recorded for three duplicate times. + +Step to reproduce: + 1. Enable the tracepoint event & starting tracing + $ echo 1 > /sys/kernel/tracing/events/module/module_free + $ echo 1 > /sys/kernel/tracing/tracing_on + + 2. Record with perf + $ perf record -a --strict-freq -F 1 -e "module:module_free" + + 3. Trigger module_free event. + $ modprobe -i sunrpc + $ modprobe -r sunrpc + +Result: + - Trace pipe result: + $ cat trace_pipe + modprobe-174509 [003] ..... 6504.868896: module_free: sunrpc + + - perf sample: + modprobe 174509 [003] 6504.868980: module:module_free: sunrpc + modprobe 174509 [003] 6504.868980: module:module_free: sunrpc + modprobe 174509 [003] 6504.868980: module:module_free: sunrpc + +By setting period_left via perf_swevent_set_period() as other sw_event did, +This problem could be solved. + +After patch: + - Trace pipe result: + $ cat trace_pipe + modprobe 1153096 [068] 613468.867774: module:module_free: xfs + + - perf sample + modprobe 1153096 [068] 613468.867794: module:module_free: xfs + +Link: https://lore.kernel.org/20240913021347.595330-1-yeoreum.yun@arm.com +Fixes: bd2b5b12849a ("perf_counter: More aggressive frequency adjustment") +Signed-off-by: Levi Yun +Acked-by: Namhyung Kim +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + kernel/trace/trace_event_perf.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c +index eb81ad523a553..b3a863c10c0a7 100644 +--- a/kernel/trace/trace_event_perf.c ++++ b/kernel/trace/trace_event_perf.c +@@ -355,10 +355,16 @@ void perf_uprobe_destroy(struct perf_event *p_event) + int perf_trace_add(struct perf_event *p_event, int flags) + { + struct trace_event_call *tp_event = p_event->tp_event; ++ struct hw_perf_event *hwc = &p_event->hw; + + if (!(flags & PERF_EF_START)) + p_event->hw.state = PERF_HES_STOPPED; + ++ if (is_sampling_event(p_event)) { ++ hwc->last_period = hwc->sample_period; ++ perf_swevent_set_period(p_event); ++ } ++ + /* + * If TRACE_REG_PERF_ADD returns false; no custom action was performed + * and we need to take the default action of enqueueing our event on +-- +2.43.0 + diff --git a/queue-5.10/usb-chaoskey-fail-open-after-removal.patch b/queue-5.10/usb-chaoskey-fail-open-after-removal.patch new file mode 100644 index 00000000000..53d73a84b8c --- /dev/null +++ b/queue-5.10/usb-chaoskey-fail-open-after-removal.patch @@ -0,0 +1,146 @@ +From 63240ff71145aff1c3d12f0257b5014a60786578 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Oct 2024 15:21:41 +0200 +Subject: USB: chaoskey: fail open after removal + +From: Oliver Neukum + +[ Upstream commit 422dc0a4d12d0b80dd3aab3fe5943f665ba8f041 ] + +chaoskey_open() takes the lock only to increase the +counter of openings. That means that the mutual exclusion +with chaoskey_disconnect() cannot prevent an increase +of the counter and chaoskey_open() returning a success. + +If that race is hit, chaoskey_disconnect() will happily +free all resources associated with the device after +it has dropped the lock, as it has read the counter +as zero. + +To prevent this race chaoskey_open() has to check +the presence of the device under the lock. +However, the current per device lock cannot be used, +because it is a part of the data structure to be +freed. Hence an additional global mutex is needed. +The issue is as old as the driver. + +Signed-off-by: Oliver Neukum +Reported-by: syzbot+422188bce66e76020e55@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=422188bce66e76020e55 +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Rule: add +Link: https://lore.kernel.org/stable/20241002132201.552578-1-oneukum%40suse.com +Link: https://lore.kernel.org/r/20241002132201.552578-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 35 ++++++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 11 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index 87067c3d6109b..32fa7fd50c380 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -27,6 +27,8 @@ static struct usb_class_driver chaoskey_class; + static int chaoskey_rng_read(struct hwrng *rng, void *data, + size_t max, bool wait); + ++static DEFINE_MUTEX(chaoskey_list_lock); ++ + #define usb_dbg(usb_if, format, arg...) \ + dev_dbg(&(usb_if)->dev, format, ## arg) + +@@ -231,6 +233,7 @@ static void chaoskey_disconnect(struct usb_interface *interface) + if (dev->hwrng_registered) + hwrng_unregister(&dev->hwrng); + ++ mutex_lock(&chaoskey_list_lock); + usb_deregister_dev(interface, &chaoskey_class); + + usb_set_intfdata(interface, NULL); +@@ -245,6 +248,7 @@ static void chaoskey_disconnect(struct usb_interface *interface) + } else + mutex_unlock(&dev->lock); + ++ mutex_unlock(&chaoskey_list_lock); + usb_dbg(interface, "disconnect done"); + } + +@@ -252,6 +256,7 @@ static int chaoskey_open(struct inode *inode, struct file *file) + { + struct chaoskey *dev; + struct usb_interface *interface; ++ int rv = 0; + + /* get the interface from minor number and driver information */ + interface = usb_find_interface(&chaoskey_driver, iminor(inode)); +@@ -267,18 +272,23 @@ static int chaoskey_open(struct inode *inode, struct file *file) + } + + file->private_data = dev; ++ mutex_lock(&chaoskey_list_lock); + mutex_lock(&dev->lock); +- ++dev->open; ++ if (dev->present) ++ ++dev->open; ++ else ++ rv = -ENODEV; + mutex_unlock(&dev->lock); ++ mutex_unlock(&chaoskey_list_lock); + +- usb_dbg(interface, "open success"); +- return 0; ++ return rv; + } + + static int chaoskey_release(struct inode *inode, struct file *file) + { + struct chaoskey *dev = file->private_data; + struct usb_interface *interface; ++ int rv = 0; + + if (dev == NULL) + return -ENODEV; +@@ -287,14 +297,15 @@ static int chaoskey_release(struct inode *inode, struct file *file) + + usb_dbg(interface, "release"); + ++ mutex_lock(&chaoskey_list_lock); + mutex_lock(&dev->lock); + + usb_dbg(interface, "open count at release is %d", dev->open); + + if (dev->open <= 0) { + usb_dbg(interface, "invalid open count (%d)", dev->open); +- mutex_unlock(&dev->lock); +- return -ENODEV; ++ rv = -ENODEV; ++ goto bail; + } + + --dev->open; +@@ -303,13 +314,15 @@ static int chaoskey_release(struct inode *inode, struct file *file) + if (dev->open == 0) { + mutex_unlock(&dev->lock); + chaoskey_free(dev); +- } else +- mutex_unlock(&dev->lock); +- } else +- mutex_unlock(&dev->lock); +- ++ goto destruction; ++ } ++ } ++bail: ++ mutex_unlock(&dev->lock); ++destruction: ++ mutex_lock(&chaoskey_list_lock); + usb_dbg(interface, "release success"); +- return 0; ++ return rv; + } + + static void chaos_read_callback(struct urb *urb) +-- +2.43.0 + diff --git a/queue-5.10/usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch b/queue-5.10/usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch new file mode 100644 index 00000000000..a8af459ebfb --- /dev/null +++ b/queue-5.10/usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch @@ -0,0 +1,154 @@ +From a9777dd9f357252360e83c5418a92955cd7e8c3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Oct 2024 22:52:07 +0800 +Subject: USB: chaoskey: Fix possible deadlock chaoskey_list_lock + +From: Edward Adam Davis + +[ Upstream commit d73dc7b182be4238b75278bfae16afb4c5564a58 ] + +[Syzbot reported two possible deadlocks] +The first possible deadlock is: +WARNING: possible recursive locking detected +6.12.0-rc1-syzkaller-00027-g4a9fe2a8ac53 #0 Not tainted +-------------------------------------------- +syz-executor363/2651 is trying to acquire lock: +ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_release+0x15d/0x2c0 drivers/usb/misc/chaoskey.c:322 + +but task is already holding lock: +ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_release+0x7f/0x2c0 drivers/usb/misc/chaoskey.c:299 + +other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(chaoskey_list_lock); + lock(chaoskey_list_lock); + + *** DEADLOCK *** + +The second possible deadlock is: +WARNING: possible circular locking dependency detected +6.12.0-rc1-syzkaller-00027-g4a9fe2a8ac53 #0 Not tainted +------------------------------------------------------ +kworker/0:2/804 is trying to acquire lock: +ffffffff899dadb0 (minor_rwsem){++++}-{3:3}, at: usb_deregister_dev+0x7c/0x1e0 drivers/usb/core/file.c:186 + +but task is already holding lock: +ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_disconnect+0xa8/0x2a0 drivers/usb/misc/chaoskey.c:235 + +which lock already depends on the new lock. + +the existing dependency chain (in reverse order) is: + +-> #1 (chaoskey_list_lock){+.+.}-{3:3}: + __mutex_lock_common kernel/locking/mutex.c:608 [inline] + __mutex_lock+0x175/0x9c0 kernel/locking/mutex.c:752 + chaoskey_open+0xdd/0x220 drivers/usb/misc/chaoskey.c:274 + usb_open+0x186/0x220 drivers/usb/core/file.c:47 + chrdev_open+0x237/0x6a0 fs/char_dev.c:414 + do_dentry_open+0x6cb/0x1390 fs/open.c:958 + vfs_open+0x82/0x3f0 fs/open.c:1088 + do_open fs/namei.c:3774 [inline] + path_openat+0x1e6a/0x2d60 fs/namei.c:3933 + do_filp_open+0x1dc/0x430 fs/namei.c:3960 + do_sys_openat2+0x17a/0x1e0 fs/open.c:1415 + do_sys_open fs/open.c:1430 [inline] + __do_sys_openat fs/open.c:1446 [inline] + __se_sys_openat fs/open.c:1441 [inline] + __x64_sys_openat+0x175/0x210 fs/open.c:1441 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +-> #0 (minor_rwsem){++++}-{3:3}: + check_prev_add kernel/locking/lockdep.c:3161 [inline] + check_prevs_add kernel/locking/lockdep.c:3280 [inline] + validate_chain kernel/locking/lockdep.c:3904 [inline] + __lock_acquire+0x250b/0x3ce0 kernel/locking/lockdep.c:5202 + lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5825 + down_write+0x93/0x200 kernel/locking/rwsem.c:1577 + usb_deregister_dev+0x7c/0x1e0 drivers/usb/core/file.c:186 + chaoskey_disconnect+0xb7/0x2a0 drivers/usb/misc/chaoskey.c:236 + usb_unbind_interface+0x1e8/0x970 drivers/usb/core/driver.c:461 + device_remove drivers/base/dd.c:569 [inline] + device_remove+0x122/0x170 drivers/base/dd.c:561 + __device_release_driver drivers/base/dd.c:1273 [inline] + device_release_driver_internal+0x44a/0x610 drivers/base/dd.c:1296 + bus_remove_device+0x22f/0x420 drivers/base/bus.c:576 + device_del+0x396/0x9f0 drivers/base/core.c:3864 + usb_disable_device+0x36c/0x7f0 drivers/usb/core/message.c:1418 + usb_disconnect+0x2e1/0x920 drivers/usb/core/hub.c:2304 + hub_port_connect drivers/usb/core/hub.c:5361 [inline] + hub_port_connect_change drivers/usb/core/hub.c:5661 [inline] + port_event drivers/usb/core/hub.c:5821 [inline] + hub_event+0x1bed/0x4f40 drivers/usb/core/hub.c:5903 + process_one_work+0x9c5/0x1ba0 kernel/workqueue.c:3229 + process_scheduled_works kernel/workqueue.c:3310 [inline] + worker_thread+0x6c8/0xf00 kernel/workqueue.c:3391 + kthread+0x2c1/0x3a0 kernel/kthread.c:389 + ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + +other info that might help us debug this: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(chaoskey_list_lock); + lock(minor_rwsem); + lock(chaoskey_list_lock); + lock(minor_rwsem); + + *** DEADLOCK *** +[Analysis] +The first is AA lock, it because wrong logic, it need a unlock. +The second is AB lock, it needs to rearrange the order of lock usage. + +Fixes: 422dc0a4d12d ("USB: chaoskey: fail open after removal") +Reported-by: syzbot+685e14d04fe35692d3bc@syzkaller.appspotmail.com +Reported-by: syzbot+1f8ca5ee82576ec01f12@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=685e14d04fe35692d3bc +Signed-off-by: Edward Adam Davis +Tested-by: syzbot+685e14d04fe35692d3bc@syzkaller.appspotmail.com +Reported-by: syzbot+5f1ce62e956b7b19610e@syzkaller.appspotmail.com +Tested-by: syzbot+5f1ce62e956b7b19610e@syzkaller.appspotmail.com +Tested-by: syzbot+1f8ca5ee82576ec01f12@syzkaller.appspotmail.com +Link: https://lore.kernel.org/r/tencent_84EB865C89862EC22EE94CB3A7C706C59206@qq.com +Cc: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index 32fa7fd50c380..d99d424c05a7a 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -233,10 +233,10 @@ static void chaoskey_disconnect(struct usb_interface *interface) + if (dev->hwrng_registered) + hwrng_unregister(&dev->hwrng); + +- mutex_lock(&chaoskey_list_lock); + usb_deregister_dev(interface, &chaoskey_class); + + usb_set_intfdata(interface, NULL); ++ mutex_lock(&chaoskey_list_lock); + mutex_lock(&dev->lock); + + dev->present = false; +@@ -320,7 +320,7 @@ static int chaoskey_release(struct inode *inode, struct file *file) + bail: + mutex_unlock(&dev->lock); + destruction: +- mutex_lock(&chaoskey_list_lock); ++ mutex_unlock(&chaoskey_list_lock); + usb_dbg(interface, "release success"); + return rv; + } +-- +2.43.0 + diff --git a/queue-5.10/usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch b/queue-5.10/usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch new file mode 100644 index 00000000000..7f1ada2d2c7 --- /dev/null +++ b/queue-5.10/usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch @@ -0,0 +1,130 @@ +From bd9d187e33d3a1ea250d8f9f9aaf0b45711fb5dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Sep 2024 19:34:03 +0900 +Subject: usb: using mutex lock and supporting O_NONBLOCK flag in + iowarrior_read() + +From: Jeongjun Park + +[ Upstream commit 44feafbaa66ec86232b123bb8437a6a262442025 ] + +iowarrior_read() uses the iowarrior dev structure, but does not use any +lock on the structure. This can cause various bugs including data-races, +so it is more appropriate to use a mutex lock to safely protect the +iowarrior dev structure. When using a mutex lock, you should split the +branch to prevent blocking when the O_NONBLOCK flag is set. + +In addition, it is unnecessary to check for NULL on the iowarrior dev +structure obtained by reading file->private_data. Therefore, it is +better to remove the check. + +Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.") +Signed-off-by: Jeongjun Park +Link: https://lore.kernel.org/r/20240919103403.3986-1-aha310510@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/iowarrior.c | 46 ++++++++++++++++++++++++++++-------- + 1 file changed, 36 insertions(+), 10 deletions(-) + +diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c +index 51a5d626134c3..c06238ce70eaa 100644 +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -277,28 +277,45 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer, + struct iowarrior *dev; + int read_idx; + int offset; ++ int retval; + + dev = file->private_data; + ++ if (file->f_flags & O_NONBLOCK) { ++ retval = mutex_trylock(&dev->mutex); ++ if (!retval) ++ return -EAGAIN; ++ } else { ++ retval = mutex_lock_interruptible(&dev->mutex); ++ if (retval) ++ return -ERESTARTSYS; ++ } ++ + /* verify that the device wasn't unplugged */ +- if (!dev || !dev->present) +- return -ENODEV; ++ if (!dev->present) { ++ retval = -ENODEV; ++ goto exit; ++ } + + dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n", + dev->minor, count); + + /* read count must be packet size (+ time stamp) */ + if ((count != dev->report_size) +- && (count != (dev->report_size + 1))) +- return -EINVAL; ++ && (count != (dev->report_size + 1))) { ++ retval = -EINVAL; ++ goto exit; ++ } + + /* repeat until no buffer overrun in callback handler occur */ + do { + atomic_set(&dev->overflow_flag, 0); + if ((read_idx = read_index(dev)) == -1) { + /* queue empty */ +- if (file->f_flags & O_NONBLOCK) +- return -EAGAIN; ++ if (file->f_flags & O_NONBLOCK) { ++ retval = -EAGAIN; ++ goto exit; ++ } + else { + //next line will return when there is either new data, or the device is unplugged + int r = wait_event_interruptible(dev->read_wait, +@@ -309,28 +326,37 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer, + -1)); + if (r) { + //we were interrupted by a signal +- return -ERESTART; ++ retval = -ERESTART; ++ goto exit; + } + if (!dev->present) { + //The device was unplugged +- return -ENODEV; ++ retval = -ENODEV; ++ goto exit; + } + if (read_idx == -1) { + // Can this happen ??? +- return 0; ++ retval = 0; ++ goto exit; + } + } + } + + offset = read_idx * (dev->report_size + 1); + if (copy_to_user(buffer, dev->read_queue + offset, count)) { +- return -EFAULT; ++ retval = -EFAULT; ++ goto exit; + } + } while (atomic_read(&dev->overflow_flag)); + + read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx; + atomic_set(&dev->read_idx, read_idx); ++ mutex_unlock(&dev->mutex); + return count; ++ ++exit: ++ mutex_unlock(&dev->mutex); ++ return retval; + } + + /* +-- +2.43.0 + diff --git a/queue-5.10/usb-yurex-make-waiting-on-yurex_write-interruptible.patch b/queue-5.10/usb-yurex-make-waiting-on-yurex_write-interruptible.patch new file mode 100644 index 00000000000..d08d7c67cd8 --- /dev/null +++ b/queue-5.10/usb-yurex-make-waiting-on-yurex_write-interruptible.patch @@ -0,0 +1,68 @@ +From 606105af8fc6671a35ecaef9702880400957289e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Sep 2024 10:43:45 +0200 +Subject: usb: yurex: make waiting on yurex_write interruptible + +From: Oliver Neukum + +[ Upstream commit e0aa9614ab0fd35b404e4b16ebe879f9fc152591 ] + +The IO yurex_write() needs to wait for in order to have a device +ready for writing again can take a long time time. +Consequently the sleep is done in an interruptible state. +Therefore others waiting for yurex_write() itself to finish should +use mutex_lock_interruptible. + +Signed-off-by: Oliver Neukum +Fixes: 6bc235a2e24a5 ("USB: add driver for Meywa-Denki & Kayac YUREX") +Rule: add +Link: https://lore.kernel.org/stable/20240924084415.300557-1-oneukum%40suse.com +Link: https://lore.kernel.org/r/20240924084415.300557-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/iowarrior.c | 4 ---- + drivers/usb/misc/yurex.c | 5 ++++- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c +index c06238ce70eaa..2a0036d8fc292 100644 +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -915,7 +915,6 @@ static int iowarrior_probe(struct usb_interface *interface, + static void iowarrior_disconnect(struct usb_interface *interface) + { + struct iowarrior *dev = usb_get_intfdata(interface); +- int minor = dev->minor; + + usb_deregister_dev(interface, &iowarrior_class); + +@@ -939,9 +938,6 @@ static void iowarrior_disconnect(struct usb_interface *interface) + mutex_unlock(&dev->mutex); + iowarrior_delete(dev); + } +- +- dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n", +- minor - IOWARRIOR_MINOR_BASE); + } + + /* usb specific object needed to register this driver with the usb subsystem */ +diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c +index 8bc7c683bf836..36192fbf915a6 100644 +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -440,7 +440,10 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, + if (count == 0) + goto error; + +- mutex_lock(&dev->io_mutex); ++ retval = mutex_lock_interruptible(&dev->io_mutex); ++ if (retval < 0) ++ return -EINTR; ++ + if (dev->disconnected) { /* already disconnected */ + mutex_unlock(&dev->io_mutex); + retval = -ENODEV; +-- +2.43.0 + diff --git a/queue-5.10/vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch b/queue-5.10/vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch new file mode 100644 index 00000000000..c9ea25d968d --- /dev/null +++ b/queue-5.10/vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch @@ -0,0 +1,53 @@ +From 238fd661ec829672734ebe68c1abe2711154702b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 21 Oct 2024 16:40:40 +0300 +Subject: vdpa/mlx5: Fix suboptimal range on iotlb iteration + +From: Si-Wei Liu + +[ Upstream commit 35025963326e44d8bced3eecd42d2f040f4f0024 ] + +The starting iova address to iterate iotlb map entry within a range +was set to an irrelevant value when passing to the itree_next() +iterator, although luckily it doesn't affect the outcome of finding +out the granule of the smallest iotlb map size. Fix the code to make +it consistent with the following for-loop. + +Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code") +Signed-off-by: Si-Wei Liu +Signed-off-by: Dragos Tatulea +Message-Id: <20241021134040.975221-3-dtatulea@nvidia.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/core/mr.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c +index 48489beb6e0a7..4615f827cd0cb 100644 +--- a/drivers/vdpa/mlx5/core/mr.c ++++ b/drivers/vdpa/mlx5/core/mr.c +@@ -226,7 +226,6 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr + unsigned long lgcd = 0; + int log_entity_size; + unsigned long size; +- u64 start = 0; + int err; + struct page *pg; + unsigned int nsg; +@@ -237,10 +236,9 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr + struct device *dma = mvdev->mdev->device; + + for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1); +- map; map = vhost_iotlb_itree_next(map, start, mr->end - 1)) { ++ map; map = vhost_iotlb_itree_next(map, mr->start, mr->end - 1)) { + size = maplen(map, mr); + lgcd = gcd(lgcd, size); +- start += size; + } + log_entity_size = ilog2(lgcd); + +-- +2.43.0 + diff --git a/queue-5.10/vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch b/queue-5.10/vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch new file mode 100644 index 00000000000..4cab782ae08 --- /dev/null +++ b/queue-5.10/vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch @@ -0,0 +1,115 @@ +From 854687013d12fc0733e08c640a55eeea9316476b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Nov 2024 16:27:39 +0200 +Subject: vfio/pci: Properly hide first-in-list PCIe extended capability + +From: Avihai Horon + +[ Upstream commit fe4bf8d0b6716a423b16495d55b35d3fe515905d ] + +There are cases where a PCIe extended capability should be hidden from +the user. For example, an unknown capability (i.e., capability with ID +greater than PCI_EXT_CAP_ID_MAX) or a capability that is intentionally +chosen to be hidden from the user. + +Hiding a capability is done by virtualizing and modifying the 'Next +Capability Offset' field of the previous capability so it points to the +capability after the one that should be hidden. + +The special case where the first capability in the list should be hidden +is handled differently because there is no previous capability that can +be modified. In this case, the capability ID and version are zeroed +while leaving the next pointer intact. This hides the capability and +leaves an anchor for the rest of the capability list. + +However, today, hiding the first capability in the list is not done +properly if the capability is unknown, as struct +vfio_pci_core_device->pci_config_map is set to the capability ID during +initialization but the capability ID is not properly checked later when +used in vfio_config_do_rw(). This leads to the following warning [1] and +to an out-of-bounds access to ecap_perms array. + +Fix it by checking cap_id in vfio_config_do_rw(), and if it is greater +than PCI_EXT_CAP_ID_MAX, use an alternative struct perm_bits for direct +read only access instead of the ecap_perms array. + +Note that this is safe since the above is the only case where cap_id can +exceed PCI_EXT_CAP_ID_MAX (except for the special capabilities, which +are already checked before). + +[1] + +WARNING: CPU: 118 PID: 5329 at drivers/vfio/pci/vfio_pci_config.c:1900 vfio_pci_config_rw+0x395/0x430 [vfio_pci_core] +CPU: 118 UID: 0 PID: 5329 Comm: simx-qemu-syste Not tainted 6.12.0+ #1 +(snip) +Call Trace: + + ? show_regs+0x69/0x80 + ? __warn+0x8d/0x140 + ? vfio_pci_config_rw+0x395/0x430 [vfio_pci_core] + ? report_bug+0x18f/0x1a0 + ? handle_bug+0x63/0xa0 + ? exc_invalid_op+0x19/0x70 + ? asm_exc_invalid_op+0x1b/0x20 + ? vfio_pci_config_rw+0x395/0x430 [vfio_pci_core] + ? vfio_pci_config_rw+0x244/0x430 [vfio_pci_core] + vfio_pci_rw+0x101/0x1b0 [vfio_pci_core] + vfio_pci_core_read+0x1d/0x30 [vfio_pci_core] + vfio_device_fops_read+0x27/0x40 [vfio] + vfs_read+0xbd/0x340 + ? vfio_device_fops_unl_ioctl+0xbb/0x740 [vfio] + ? __rseq_handle_notify_resume+0xa4/0x4b0 + __x64_sys_pread64+0x96/0xc0 + x64_sys_call+0x1c3d/0x20d0 + do_syscall_64+0x4d/0x120 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 89e1f7d4c66d ("vfio: Add PCI device driver") +Signed-off-by: Avihai Horon +Reviewed-by: Yi Liu +Tested-by: Yi Liu +Link: https://lore.kernel.org/r/20241124142739.21698-1-avihaih@nvidia.com +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/vfio_pci_config.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c +index 47f21a6ca7fe9..401c3c776c6b5 100644 +--- a/drivers/vfio/pci/vfio_pci_config.c ++++ b/drivers/vfio/pci/vfio_pci_config.c +@@ -312,6 +312,10 @@ static int vfio_virt_config_read(struct vfio_pci_device *vdev, int pos, + return count; + } + ++static struct perm_bits direct_ro_perms = { ++ .readfn = vfio_direct_config_read, ++}; ++ + /* Default capability regions to read-only, no-virtualization */ + static struct perm_bits cap_perms[PCI_CAP_ID_MAX + 1] = { + [0 ... PCI_CAP_ID_MAX] = { .readfn = vfio_direct_config_read } +@@ -1840,9 +1844,17 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf, + cap_start = *ppos; + } else { + if (*ppos >= PCI_CFG_SPACE_SIZE) { +- WARN_ON(cap_id > PCI_EXT_CAP_ID_MAX); ++ /* ++ * We can get a cap_id that exceeds PCI_EXT_CAP_ID_MAX ++ * if we're hiding an unknown capability at the start ++ * of the extended capability list. Use default, ro ++ * access, which will virtualize the id and next values. ++ */ ++ if (cap_id > PCI_EXT_CAP_ID_MAX) ++ perm = &direct_ro_perms; ++ else ++ perm = &ecap_perms[cap_id]; + +- perm = &ecap_perms[cap_id]; + cap_start = vfio_find_cap_start(vdev, *ppos); + } else { + WARN_ON(cap_id > PCI_CAP_ID_MAX); +-- +2.43.0 + diff --git a/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch b/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch new file mode 100644 index 00000000000..a67fb90512e --- /dev/null +++ b/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch @@ -0,0 +1,52 @@ +From ab9a1c5fbe3ee180b2f164108ca2477fb0ea4e21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Jul 2024 10:03:43 +0800 +Subject: wifi: ath10k: fix invalid VHT parameters in + supported_vht_mcs_rate_nss1 + +From: Baochen Qiang + +[ Upstream commit d50886b27850447d90c0cd40c725238097909d1e ] + +In supported_vht_mcs_rate_nss1, the rate for MCS9 & VHT20 is defined as +{780, 867}, this does not align with firmware's definition and therefore +fails the verification in ath10k_mac_get_rate_flags_vht(): + + invalid vht params rate 960 100kbps nss 1 mcs 9 + +Change it to {865, 960} to align with firmware, so this issue could be +fixed. + +Since ath10k_hw_params::supports_peer_stats_info is enabled only for +QCA6174, this change does not affect other chips. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00309-QCARMSWPZ-1 + +Fixes: 3344b99d69ab ("ath10k: add bitrate parse for peer stats info") +Reported-by: Paul Menzel +Closes: https://lore.kernel.org/lkml/fba24cd3-4a1e-4072-8585-8402272788ff@molgen.mpg.de/ +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240711020344.98040-2-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 15f02bf23e9bd..2bf3e66c83f63 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -8955,7 +8955,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss1[ + {6, {2633, 2925}, {1215, 1350}, {585, 650} }, + {7, {2925, 3250}, {1350, 1500}, {650, 722} }, + {8, {3510, 3900}, {1620, 1800}, {780, 867} }, +- {9, {3900, 4333}, {1800, 2000}, {780, 867} } ++ {9, {3900, 4333}, {1800, 2000}, {865, 960} } + }; + + /*MCS parameters with Nss = 2 */ +-- +2.43.0 + diff --git a/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150 b/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150 new file mode 100644 index 00000000000..edb17efc115 --- /dev/null +++ b/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150 @@ -0,0 +1,56 @@ +From dc84a9a07f72440dbeb5e3f65b4b2d9a764fdadc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Jul 2024 10:03:44 +0800 +Subject: wifi: ath10k: fix invalid VHT parameters in + supported_vht_mcs_rate_nss2 + +From: Baochen Qiang + +[ Upstream commit 52db16ec5bae7bd027804265b968259d1a6c3970 ] + +In supported_vht_mcs_rate_nss2, the rate for MCS9 & VHT20 is defined as +{1560, 1733}, this does not align with firmware's definition and therefore +fails the verification in ath10k_mac_get_rate_flags_vht(): + + invalid vht params rate 1730 100kbps nss 2 mcs 9 + +and: + + invalid vht params rate 1920 100kbps nss 2 mcs 9 + +Change it to {1730, 1920} to align with firmware to fix the issue. + +Since ath10k_hw_params::supports_peer_stats_info is enabled only for +QCA6174, this change does not affect other chips. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00309-QCARMSWPZ-1 + +Fixes: 3344b99d69ab ("ath10k: add bitrate parse for peer stats info") +Reported-by: Paul Menzel +Closes: https://lore.kernel.org/lkml/fba24cd3-4a1e-4072-8585-8402272788ff@molgen.mpg.de/ +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +Tested-by: Paul Menzel # Dell XPS 13 9360 +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240711020344.98040-3-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 2bf3e66c83f63..323b6763cb0f5 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -8970,7 +8970,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss2[ + {6, {5265, 5850}, {2430, 2700}, {1170, 1300} }, + {7, {5850, 6500}, {2700, 3000}, {1300, 1444} }, + {8, {7020, 7800}, {3240, 3600}, {1560, 1733} }, +- {9, {7800, 8667}, {3600, 4000}, {1560, 1733} } ++ {9, {7800, 8667}, {3600, 4000}, {1730, 1920} } + }; + + static void ath10k_mac_get_rate_flags_ht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs, +-- +2.43.0 + diff --git a/queue-5.10/wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch b/queue-5.10/wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch new file mode 100644 index 00000000000..9fb1826918c --- /dev/null +++ b/queue-5.10/wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch @@ -0,0 +1,61 @@ +From 2c123c9fce25c23cceb98fd94491c9add6681678 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Sep 2024 12:06:03 +0300 +Subject: wifi: ath9k: add range check for conn_rsp_epid in + htc_connect_service() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jeongjun Park + +[ Upstream commit 8619593634cbdf5abf43f5714df49b04e4ef09ab ] + +I found the following bug in my fuzzer: + + UBSAN: array-index-out-of-bounds in drivers/net/wireless/ath/ath9k/htc_hst.c:26:51 + index 255 is out of range for type 'htc_endpoint [22]' + CPU: 0 UID: 0 PID: 8 Comm: kworker/0:0 Not tainted 6.11.0-rc6-dirty #14 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 + Workqueue: events request_firmware_work_func + Call Trace: + + dump_stack_lvl+0x180/0x1b0 + __ubsan_handle_out_of_bounds+0xd4/0x130 + htc_issue_send.constprop.0+0x20c/0x230 + ? _raw_spin_unlock_irqrestore+0x3c/0x70 + ath9k_wmi_cmd+0x41d/0x610 + ? mark_held_locks+0x9f/0xe0 + ... + +Since this bug has been confirmed to be caused by insufficient verification +of conn_rsp_epid, I think it would be appropriate to add a range check for +conn_rsp_epid to htc_connect_service() to prevent the bug from occurring. + +Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") +Signed-off-by: Jeongjun Park +Acked-by: Toke Høiland-Jørgensen +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240909103855.68006-1-aha310510@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath9k/htc_hst.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c +index 99667aba289df..00dc97ac53b9d 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_hst.c ++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c +@@ -294,6 +294,9 @@ int htc_connect_service(struct htc_target *target, + return -ETIMEDOUT; + } + ++ if (target->conn_rsp_epid < 0 || target->conn_rsp_epid >= ENDPOINT_MAX) ++ return -EINVAL; ++ + *conn_rsp_epid = target->conn_rsp_epid; + return 0; + err: +-- +2.43.0 + diff --git a/queue-5.10/wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch b/queue-5.10/wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch new file mode 100644 index 00000000000..f0d9e0ebdf0 --- /dev/null +++ b/queue-5.10/wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch @@ -0,0 +1,56 @@ +From 9eb632efd38bd02c4dcf88a747a9ce399a226cf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 01:20:54 +0300 +Subject: wifi: mwifiex: Fix memcpy() field-spanning write warning in + mwifiex_config_scan() + +From: Alper Nebi Yasak + +[ Upstream commit d241a139c2e9f8a479f25c75ebd5391e6a448500 ] + +Replace one-element array with a flexible-array member in `struct +mwifiex_ie_types_wildcard_ssid_params` to fix the following warning +on a MT8173 Chromebook (mt8173-elm-hana): + +[ 356.775250] ------------[ cut here ]------------ +[ 356.784543] memcpy: detected field-spanning write (size 6) of single field "wildcard_ssid_tlv->ssid" at drivers/net/wireless/marvell/mwifiex/scan.c:904 (size 1) +[ 356.813403] WARNING: CPU: 3 PID: 742 at drivers/net/wireless/marvell/mwifiex/scan.c:904 mwifiex_scan_networks+0x4fc/0xf28 [mwifiex] + +The "(size 6)" above is exactly the length of the SSID of the network +this device was connected to. The source of the warning looks like: + + ssid_len = user_scan_in->ssid_list[i].ssid_len; + [...] + memcpy(wildcard_ssid_tlv->ssid, + user_scan_in->ssid_list[i].ssid, ssid_len); + +There is a #define WILDCARD_SSID_TLV_MAX_SIZE that uses sizeof() on this +struct, but it already didn't account for the size of the one-element +array, so it doesn't need to be changed. + +Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") +Signed-off-by: Alper Nebi Yasak +Acked-by: Brian Norris +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20241007222301.24154-1-alpernebiyasak@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/marvell/mwifiex/fw.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h +index 284671618e9ce..50205b6ae4ca2 100644 +--- a/drivers/net/wireless/marvell/mwifiex/fw.h ++++ b/drivers/net/wireless/marvell/mwifiex/fw.h +@@ -854,7 +854,7 @@ struct mwifiex_ietypes_chanstats { + struct mwifiex_ie_types_wildcard_ssid_params { + struct mwifiex_ie_types_header header; + u8 max_ssid_length; +- u8 ssid[1]; ++ u8 ssid[]; + } __packed; + + #define TSF_DATA_SIZE 8 +-- +2.43.0 + diff --git a/queue-5.10/wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch new file mode 100644 index 00000000000..de3a992f8ce --- /dev/null +++ b/queue-5.10/wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch @@ -0,0 +1,48 @@ +From 8bf08be35238d0ab611908cbf76dcb9e9e4b3cf4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 20:43:13 +0800 +Subject: wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit 9a98dd48b6d834d7a3fe5e8e7b8c3a1d006f9685 ] + +disable_irq() after request_irq() still has a time gap in which +interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will +disable IRQ auto-enable when request IRQ. + +Fixes: 853402a00823 ("mwifiex: Enable WoWLAN for both sdio and pcie") +Signed-off-by: Jinjie Ruan +Acked-by: Brian Norris +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240910124314.698896-3-ruanjinjie@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/marvell/mwifiex/main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c +index b8b79fe50dbc2..6991bb0e8e9b6 100644 +--- a/drivers/net/wireless/marvell/mwifiex/main.c ++++ b/drivers/net/wireless/marvell/mwifiex/main.c +@@ -1600,7 +1600,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) + } + + ret = devm_request_irq(dev, adapter->irq_wakeup, +- mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW, ++ mwifiex_irq_wakeup_handler, ++ IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN, + "wifi_wake", adapter); + if (ret) { + dev_err(dev, "Failed to request irq_wakeup %d (%d)\n", +@@ -1608,7 +1609,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) + goto err_exit; + } + +- disable_irq(adapter->irq_wakeup); + if (device_init_wakeup(dev, true)) { + dev_err(dev, "fail to init wakeup for mwifiex\n"); + goto err_exit; +-- +2.43.0 + diff --git a/queue-5.10/wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch new file mode 100644 index 00000000000..828f450d3ab --- /dev/null +++ b/queue-5.10/wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch @@ -0,0 +1,47 @@ +From e8b1d014971afd3c39c804119597221f28531275 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 20:43:12 +0800 +Subject: wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq() + +From: Jinjie Ruan + +[ Upstream commit bcd1371bd85e560ccc9159b7747f94bfe43b77a6 ] + +disable_irq() after request_irq() still has a time gap in which +interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will +disable IRQ auto-enable when request IRQ. + +Fixes: cd8d3d321285 ("p54spi: p54spi driver") +Signed-off-by: Jinjie Ruan +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240910124314.698896-2-ruanjinjie@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intersil/p54/p54spi.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c +index cdb57819684ae..8a9168aac7281 100644 +--- a/drivers/net/wireless/intersil/p54/p54spi.c ++++ b/drivers/net/wireless/intersil/p54/p54spi.c +@@ -623,7 +623,7 @@ static int p54spi_probe(struct spi_device *spi) + gpio_direction_input(p54spi_gpio_irq); + + ret = request_irq(gpio_to_irq(p54spi_gpio_irq), +- p54spi_interrupt, 0, "p54spi", ++ p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi", + priv->spi); + if (ret < 0) { + dev_err(&priv->spi->dev, "request_irq() failed"); +@@ -632,8 +632,6 @@ static int p54spi_probe(struct spi_device *spi) + + irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); + +- disable_irq(gpio_to_irq(p54spi_gpio_irq)); +- + INIT_WORK(&priv->work, p54spi_work); + init_completion(&priv->fw_comp); + INIT_LIST_HEAD(&priv->tx_pending); +-- +2.43.0 + diff --git a/queue-5.10/wifi-wfx-fix-error-handling-in-wfx_core_init.patch b/queue-5.10/wifi-wfx-fix-error-handling-in-wfx_core_init.patch new file mode 100644 index 00000000000..f08a50fb715 --- /dev/null +++ b/queue-5.10/wifi-wfx-fix-error-handling-in-wfx_core_init.patch @@ -0,0 +1,60 @@ +From 9d1bff97c7febbfaf94093c47f849c0c0597aac4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Oct 2024 17:04:53 +0800 +Subject: wifi: wfx: Fix error handling in wfx_core_init() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yuan Can + +[ Upstream commit 3b88a9876779b55478a4dde867e73f7a100ffa23 ] + +The wfx_core_init() returns without checking the retval from +sdio_register_driver(). +If the sdio_register_driver() failed, the module failed to install, +leaving the wfx_spi_driver not unregistered. + +Fixes: a7a91ca5a23d ("staging: wfx: add infrastructure for new driver") +Signed-off-by: Yuan Can +Reviewed-by: Jérôme Pouiller +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20241022090453.84679-1-yuancan@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/staging/wfx/main.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c +index d5dacd5583c6e..5a54dd22fad53 100644 +--- a/drivers/staging/wfx/main.c ++++ b/drivers/staging/wfx/main.c +@@ -477,10 +477,23 @@ static int __init wfx_core_init(void) + { + int ret = 0; + +- if (IS_ENABLED(CONFIG_SPI)) ++ if (IS_ENABLED(CONFIG_SPI)) { + ret = spi_register_driver(&wfx_spi_driver); +- if (IS_ENABLED(CONFIG_MMC) && !ret) ++ if (ret) ++ goto out; ++ } ++ if (IS_ENABLED(CONFIG_MMC)) { + ret = sdio_register_driver(&wfx_sdio_driver); ++ if (ret) ++ goto unregister_spi; ++ } ++ ++ return 0; ++ ++unregister_spi: ++ if (IS_ENABLED(CONFIG_SPI)) ++ spi_unregister_driver(&wfx_spi_driver); ++out: + return ret; + } + module_init(wfx_core_init); +-- +2.43.0 + diff --git a/queue-5.10/wireguard-selftests-load-nf_conntrack-if-not-present.patch b/queue-5.10/wireguard-selftests-load-nf_conntrack-if-not-present.patch new file mode 100644 index 00000000000..bb9c9e2527c --- /dev/null +++ b/queue-5.10/wireguard-selftests-load-nf_conntrack-if-not-present.patch @@ -0,0 +1,40 @@ +From cbfb55799f480df5cb8092fa4cfaa5dcc2944493 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Nov 2024 22:20:29 +0100 +Subject: wireguard: selftests: load nf_conntrack if not present + +From: Hangbin Liu + +[ Upstream commit 0290abc9860917f1ee8b58309c2bbd740a39ee8e ] + +Some distros may not load nf_conntrack by default, which will cause +subsequent nf_conntrack sets to fail. Load this module if it is not +already loaded. + +Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") +Signed-off-by: Hangbin Liu +Reviewed-by: Simon Horman +[ Jason: add [[ -e ... ]] check so this works in the qemu harness. ] +Signed-off-by: Jason A. Donenfeld +Link: https://patch.msgid.link/20241117212030.629159-4-Jason@zx2c4.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/wireguard/netns.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/wireguard/netns.sh b/tools/testing/selftests/wireguard/netns.sh +index 93e44410f170e..4732c23e35ee5 100755 +--- a/tools/testing/selftests/wireguard/netns.sh ++++ b/tools/testing/selftests/wireguard/netns.sh +@@ -320,6 +320,7 @@ waitiface $netns1 vethc + waitiface $netns2 veths + + n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward' ++[[ -e /proc/sys/net/netfilter/nf_conntrack_udp_timeout ]] || modprobe nf_conntrack + n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout' + n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream' + n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to 10.0.0.1 +-- +2.43.0 + diff --git a/queue-5.10/x86-barrier-do-not-serialize-msr-accesses-on-amd.patch b/queue-5.10/x86-barrier-do-not-serialize-msr-accesses-on-amd.patch new file mode 100644 index 00000000000..5eb90bf7434 --- /dev/null +++ b/queue-5.10/x86-barrier-do-not-serialize-msr-accesses-on-amd.patch @@ -0,0 +1,211 @@ +From 21268e7087ec47c8606767bec63dbe13d7e4fbbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 14:24:16 +0200 +Subject: x86/barrier: Do not serialize MSR accesses on AMD + +From: Borislav Petkov (AMD) + +commit 04c3024560d3a14acd18d0a51a1d0a89d29b7eb5 upstream. + +AMD does not have the requirement for a synchronization barrier when +acccessing a certain group of MSRs. Do not incur that unnecessary +penalty there. + +There will be a CPUID bit which explicitly states that a MFENCE is not +needed. Once that bit is added to the APM, this will be extended with +it. + +While at it, move to processor.h to avoid include hell. Untangling that +file properly is a matter for another day. + +Some notes on the performance aspect of why this is relevant, courtesy +of Kishon VijayAbraham : + +On a AMD Zen4 system with 96 cores, a modified ipi-bench[1] on a VM +shows x2AVIC IPI rate is 3% to 4% lower than AVIC IPI rate. The +ipi-bench is modified so that the IPIs are sent between two vCPUs in the +same CCX. This also requires to pin the vCPU to a physical core to +prevent any latencies. This simulates the use case of pinning vCPUs to +the thread of a single CCX to avoid interrupt IPI latency. + +In order to avoid run-to-run variance (for both x2AVIC and AVIC), the +below configurations are done: + + 1) Disable Power States in BIOS (to prevent the system from going to + lower power state) + + 2) Run the system at fixed frequency 2500MHz (to prevent the system + from increasing the frequency when the load is more) + +With the above configuration: + +*) Performance measured using ipi-bench for AVIC: + Average Latency: 1124.98ns [Time to send IPI from one vCPU to another vCPU] + + Cumulative throughput: 42.6759M/s [Total number of IPIs sent in a second from + 48 vCPUs simultaneously] + +*) Performance measured using ipi-bench for x2AVIC: + Average Latency: 1172.42ns [Time to send IPI from one vCPU to another vCPU] + + Cumulative throughput: 40.9432M/s [Total number of IPIs sent in a second from + 48 vCPUs simultaneously] + +From above, x2AVIC latency is ~4% more than AVIC. However, the expectation is +x2AVIC performance to be better or equivalent to AVIC. Upon analyzing +the perf captures, it is observed significant time is spent in +weak_wrmsr_fence() invoked by x2apic_send_IPI(). + +With the fix to skip weak_wrmsr_fence() + +*) Performance measured using ipi-bench for x2AVIC: + Average Latency: 1117.44ns [Time to send IPI from one vCPU to another vCPU] + + Cumulative throughput: 42.9608M/s [Total number of IPIs sent in a second from + 48 vCPUs simultaneously] + +Comparing the performance of x2AVIC with and without the fix, it can be seen +the performance improves by ~4%. + +Performance captured using an unmodified ipi-bench using the 'mesh-ipi' option +with and without weak_wrmsr_fence() on a Zen4 system also showed significant +performance improvement without weak_wrmsr_fence(). The 'mesh-ipi' option ignores +CCX or CCD and just picks random vCPU. + + Average throughput (10 iterations) with weak_wrmsr_fence(), + Cumulative throughput: 4933374 IPI/s + + Average throughput (10 iterations) without weak_wrmsr_fence(), + Cumulative throughput: 6355156 IPI/s + +[1] https://github.com/bytedance/kvm-utils/tree/master/microbenchmark/ipi-bench + +Signed-off-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/20230622095212.20940-1-bp@alien8.de +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/barrier.h | 18 ------------------ + arch/x86/include/asm/cpufeatures.h | 1 + + arch/x86/include/asm/processor.h | 18 ++++++++++++++++++ + arch/x86/kernel/cpu/amd.c | 3 +++ + arch/x86/kernel/cpu/common.c | 7 +++++++ + arch/x86/kernel/cpu/hygon.c | 3 +++ + 6 files changed, 32 insertions(+), 18 deletions(-) + +diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h +index 4819d5e5a3353..7f828fe497978 100644 +--- a/arch/x86/include/asm/barrier.h ++++ b/arch/x86/include/asm/barrier.h +@@ -84,22 +84,4 @@ do { \ + + #include + +-/* +- * Make previous memory operations globally visible before +- * a WRMSR. +- * +- * MFENCE makes writes visible, but only affects load/store +- * instructions. WRMSR is unfortunately not a load/store +- * instruction and is unaffected by MFENCE. The LFENCE ensures +- * that the WRMSR is not reordered. +- * +- * Most WRMSRs are full serializing instructions themselves and +- * do not require this barrier. This is only required for the +- * IA32_TSC_DEADLINE and X2APIC MSRs. +- */ +-static inline void weak_wrmsr_fence(void) +-{ +- asm volatile("mfence; lfence" : : : "memory"); +-} +- + #endif /* _ASM_X86_BARRIER_H */ +diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h +index 23f563493e810..f3365ec973763 100644 +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -305,6 +305,7 @@ + #define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */ + #define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */ + #define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */ ++#define X86_FEATURE_APIC_MSRS_FENCE (11*32+27) /* "" IA32_TSC_DEADLINE and X2APIC MSRs need fencing */ + + /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ + #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ +diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h +index c682a14299e0e..5defef9f286e1 100644 +--- a/arch/x86/include/asm/processor.h ++++ b/arch/x86/include/asm/processor.h +@@ -858,4 +858,22 @@ enum mds_mitigations { + + extern bool gds_ucode_mitigated(void); + ++/* ++ * Make previous memory operations globally visible before ++ * a WRMSR. ++ * ++ * MFENCE makes writes visible, but only affects load/store ++ * instructions. WRMSR is unfortunately not a load/store ++ * instruction and is unaffected by MFENCE. The LFENCE ensures ++ * that the WRMSR is not reordered. ++ * ++ * Most WRMSRs are full serializing instructions themselves and ++ * do not require this barrier. This is only required for the ++ * IA32_TSC_DEADLINE and X2APIC MSRs. ++ */ ++static inline void weak_wrmsr_fence(void) ++{ ++ alternative("mfence; lfence", "", ALT_NOT(X86_FEATURE_APIC_MSRS_FENCE)); ++} ++ + #endif /* _ASM_X86_PROCESSOR_H */ +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 3b02cb8b05338..c10f7dcaa7b7c 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -1186,6 +1186,9 @@ static void init_amd(struct cpuinfo_x86 *c) + if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && + cpu_has_amd_erratum(c, amd_erratum_1485)) + msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT); ++ ++ /* AMD CPUs don't need fencing after x2APIC/TSC_DEADLINE MSR writes. */ ++ clear_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE); + } + + #ifdef CONFIG_X86_32 +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index f8e5598408bfd..97da1dcf5a399 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -1716,6 +1716,13 @@ static void identify_cpu(struct cpuinfo_x86 *c) + c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); + #endif + ++ ++ /* ++ * Set default APIC and TSC_DEADLINE MSR fencing flag. AMD and ++ * Hygon will clear it in ->c_init() below. ++ */ ++ set_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE); ++ + /* + * Vendor-specific initialization. In this section we + * canonicalize the feature flags, meaning if there are +diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c +index 3f5c00b15e2c1..b49f662f68718 100644 +--- a/arch/x86/kernel/cpu/hygon.c ++++ b/arch/x86/kernel/cpu/hygon.c +@@ -363,6 +363,9 @@ static void init_hygon(struct cpuinfo_x86 *c) + set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); + + check_null_seg_clears_base(c); ++ ++ /* Hygon CPUs don't need fencing after x2APIC/TSC_DEADLINE MSR writes. */ ++ clear_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE); + } + + static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c) +-- +2.43.0 + diff --git a/queue-5.10/x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch b/queue-5.10/x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch new file mode 100644 index 00000000000..1f9aed3a4c6 --- /dev/null +++ b/queue-5.10/x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch @@ -0,0 +1,54 @@ +From 981a05a2e3d15cf30f556fa08c217a6c8f0eda22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Oct 2024 18:04:40 +0200 +Subject: x86/pvh: Call C code via the kernel virtual mapping + +From: Ard Biesheuvel + +[ Upstream commit e8fbc0d9cab6c1ee6403f42c0991b0c1d5dbc092 ] + +Calling C code via a different mapping than it was linked at is +problematic, because the compiler assumes that RIP-relative and absolute +symbol references are interchangeable. GCC in particular may use +RIP-relative per-CPU variable references even when not using -fpic. + +So call xen_prepare_pvh() via its kernel virtual mapping on x86_64, so +that those RIP-relative references produce the correct values. This +matches the pre-existing behavior for i386, which also invokes +xen_prepare_pvh() via the kernel virtual mapping before invoking +startup_32 with paging disabled again. + +Fixes: 7243b93345f7 ("xen/pvh: Bootstrap PVH guest") +Tested-by: Jason Andryuk +Reviewed-by: Jason Andryuk +Signed-off-by: Ard Biesheuvel +Message-ID: <20241009160438.3884381-8-ardb+git@google.com> +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + arch/x86/platform/pvh/head.S | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S +index cfabc3340362b..eadadd2ecd847 100644 +--- a/arch/x86/platform/pvh/head.S ++++ b/arch/x86/platform/pvh/head.S +@@ -106,7 +106,14 @@ SYM_CODE_START_LOCAL(pvh_start_xen) + movq %rbp, %rbx + subq $_pa(pvh_start_xen), %rbx + movq %rbx, phys_base(%rip) +- call xen_prepare_pvh ++ ++ /* Call xen_prepare_pvh() via the kernel virtual mapping */ ++ leaq xen_prepare_pvh(%rip), %rax ++ subq phys_base(%rip), %rax ++ addq $__START_KERNEL_map, %rax ++ ANNOTATE_RETPOLINE_SAFE ++ call *%rax ++ + /* + * Clear phys_base. __startup_64 will *add* to its value, + * so reset to 0. +-- +2.43.0 + diff --git a/queue-5.10/x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch b/queue-5.10/x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch new file mode 100644 index 00000000000..e15049b518f --- /dev/null +++ b/queue-5.10/x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch @@ -0,0 +1,52 @@ +From f250731baac8e75ace3cec56e22c979aadb1f1ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 15:36:28 -0400 +Subject: x86/pvh: Set phys_base when calling xen_prepare_pvh() + +From: Jason Andryuk + +[ Upstream commit b464b461d27d564125db760938643374864c1b1f ] + +phys_base needs to be set for __pa() to work in xen_pvh_init() when +finding the hypercall page. Set it before calling into +xen_prepare_pvh(), which calls xen_pvh_init(). Clear it afterward to +avoid __startup_64() adding to it and creating an incorrect value. + +Signed-off-by: Jason Andryuk +Reviewed-by: Juergen Gross +Message-ID: <20240823193630.2583107-4-jason.andryuk@amd.com> +Signed-off-by: Juergen Gross +Stable-dep-of: e8fbc0d9cab6 ("x86/pvh: Call C code via the kernel virtual mapping") +Signed-off-by: Sasha Levin +--- + arch/x86/platform/pvh/head.S | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S +index b0490701da2ab..cfabc3340362b 100644 +--- a/arch/x86/platform/pvh/head.S ++++ b/arch/x86/platform/pvh/head.S +@@ -99,7 +99,20 @@ SYM_CODE_START_LOCAL(pvh_start_xen) + xor %edx, %edx + wrmsr + ++ /* ++ * Calculate load offset and store in phys_base. __pa() needs ++ * phys_base set to calculate the hypercall page in xen_pvh_init(). ++ */ ++ movq %rbp, %rbx ++ subq $_pa(pvh_start_xen), %rbx ++ movq %rbx, phys_base(%rip) + call xen_prepare_pvh ++ /* ++ * Clear phys_base. __startup_64 will *add* to its value, ++ * so reset to 0. ++ */ ++ xor %rbx, %rbx ++ movq %rbx, phys_base(%rip) + + /* startup_64 expects boot_params in %rsi. */ + mov $_pa(pvh_bootparams), %rsi +-- +2.43.0 + diff --git a/queue-5.10/x86-xen-pvh-annotate-indirect-branch-as-safe.patch b/queue-5.10/x86-xen-pvh-annotate-indirect-branch-as-safe.patch new file mode 100644 index 00000000000..478e12e8f4f --- /dev/null +++ b/queue-5.10/x86-xen-pvh-annotate-indirect-branch-as-safe.patch @@ -0,0 +1,46 @@ +From d216a9dab1baf7ef71df9b038a4ee12234f421b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 15:29:30 -0600 +Subject: x86/xen/pvh: Annotate indirect branch as safe + +From: Josh Poimboeuf + +[ Upstream commit 82694854caa8badab7c5d3a19c0139e8b471b1d3 ] + +This indirect jump is harmless; annotate it to keep objtool's retpoline +validation happy. + +Cc: Boris Ostrovsky +Cc: Juergen Gross +Signed-off-by: Josh Poimboeuf +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/4797c72a258b26e06741c58ccd4a75c42db39c1d.1611263462.git.jpoimboe@redhat.com +Stable-dep-of: e8fbc0d9cab6 ("x86/pvh: Call C code via the kernel virtual mapping") +Signed-off-by: Sasha Levin +--- + arch/x86/platform/pvh/head.S | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S +index afbf0bb252da5..b0490701da2ab 100644 +--- a/arch/x86/platform/pvh/head.S ++++ b/arch/x86/platform/pvh/head.S +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + + __HEAD +@@ -103,6 +104,7 @@ SYM_CODE_START_LOCAL(pvh_start_xen) + /* startup_64 expects boot_params in %rsi. */ + mov $_pa(pvh_bootparams), %rsi + mov $_pa(startup_64), %rax ++ ANNOTATE_RETPOLINE_SAFE + jmp *%rax + + #else /* CONFIG_X86_64 */ +-- +2.43.0 + diff --git a/queue-5.10/xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch b/queue-5.10/xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch new file mode 100644 index 00000000000..39a9d2cbade --- /dev/null +++ b/queue-5.10/xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch @@ -0,0 +1,126 @@ +From 73603a61b5c78794e4c8e5c73735940c42d191b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 May 2022 13:06:40 +0300 +Subject: xfrm: rename xfrm_state_offload struct to allow reuse + +From: Leon Romanovsky + +[ Upstream commit 87e0a94e60ea2e29be9dec6bc146fbc9861a4055 ] + +The struct xfrm_state_offload has all fields needed to hold information +for offloaded policies too. In order to do not create new struct with +same fields, let's rename existing one and reuse it later. + +Reviewed-by: Raed Salem +Signed-off-by: Leon Romanovsky +Acked-by: David S. Miller +Signed-off-by: Steffen Klassert +Stable-dep-of: 2cf567f421db ("netdevsim: copy addresses for both in and out paths") +Signed-off-by: Sasha Levin +--- + include/net/xfrm.h | 10 +++++----- + net/xfrm/xfrm_device.c | 2 +- + net/xfrm/xfrm_state.c | 4 ++-- + net/xfrm/xfrm_user.c | 2 +- + 4 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/include/net/xfrm.h b/include/net/xfrm.h +index 798df30c2d253..987c603806aee 100644 +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -126,7 +126,7 @@ struct xfrm_state_walk { + struct xfrm_address_filter *filter; + }; + +-struct xfrm_state_offload { ++struct xfrm_dev_offload { + struct net_device *dev; + struct net_device *real_dev; + unsigned long offload_handle; +@@ -240,7 +240,7 @@ struct xfrm_state { + struct xfrm_lifetime_cur curlft; + struct hrtimer mtimer; + +- struct xfrm_state_offload xso; ++ struct xfrm_dev_offload xso; + + /* used to fix curlft->add_time when changing date */ + long saved_tmo; +@@ -1892,7 +1892,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); + + static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x) + { +- struct xfrm_state_offload *xso = &x->xso; ++ struct xfrm_dev_offload *xso = &x->xso; + + if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn) + xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x); +@@ -1918,7 +1918,7 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) + + static inline void xfrm_dev_state_delete(struct xfrm_state *x) + { +- struct xfrm_state_offload *xso = &x->xso; ++ struct xfrm_dev_offload *xso = &x->xso; + + if (xso->dev) + xso->dev->xfrmdev_ops->xdo_dev_state_delete(x); +@@ -1926,7 +1926,7 @@ static inline void xfrm_dev_state_delete(struct xfrm_state *x) + + static inline void xfrm_dev_state_free(struct xfrm_state *x) + { +- struct xfrm_state_offload *xso = &x->xso; ++ struct xfrm_dev_offload *xso = &x->xso; + struct net_device *dev = xso->dev; + + if (dev && dev->xfrmdev_ops) { +diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c +index 4d13f7a372ab6..61aa0fd9d2a0c 100644 +--- a/net/xfrm/xfrm_device.c ++++ b/net/xfrm/xfrm_device.c +@@ -225,7 +225,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, + int err; + struct dst_entry *dst; + struct net_device *dev; +- struct xfrm_state_offload *xso = &x->xso; ++ struct xfrm_dev_offload *xso = &x->xso; + xfrm_address_t *saddr; + xfrm_address_t *daddr; + +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index ba73014805a4f..94179ff475f2f 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -726,7 +726,7 @@ xfrm_dev_state_flush_secctx_check(struct net *net, struct net_device *dev, bool + + for (i = 0; i <= net->xfrm.state_hmask; i++) { + struct xfrm_state *x; +- struct xfrm_state_offload *xso; ++ struct xfrm_dev_offload *xso; + + hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { + xso = &x->xso; +@@ -810,7 +810,7 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali + err = -ESRCH; + for (i = 0; i <= net->xfrm.state_hmask; i++) { + struct xfrm_state *x; +- struct xfrm_state_offload *xso; ++ struct xfrm_dev_offload *xso; + restart: + hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { + xso = &x->xso; +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index e28e49499713f..b12a305a2d7a4 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -843,7 +843,7 @@ static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) + return 0; + } + +-static int copy_user_offload(struct xfrm_state_offload *xso, struct sk_buff *skb) ++static int copy_user_offload(struct xfrm_dev_offload *xso, struct sk_buff *skb) + { + struct xfrm_user_offload *xuo; + struct nlattr *attr; +-- +2.43.0 + diff --git a/queue-5.10/xfrm-store-and-rely-on-direction-to-construct-offloa.patch b/queue-5.10/xfrm-store-and-rely-on-direction-to-construct-offloa.patch new file mode 100644 index 00000000000..12a4dd3b1b7 --- /dev/null +++ b/queue-5.10/xfrm-store-and-rely-on-direction-to-construct-offloa.patch @@ -0,0 +1,96 @@ +From 2fc8606ea6ecd9997ccc3d43c0de145de5c0876a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 May 2022 13:06:41 +0300 +Subject: xfrm: store and rely on direction to construct offload flags + +From: Leon Romanovsky + +[ Upstream commit 482db2f1dd211f73ad9d71e33ae15c1df6379982 ] + +XFRM state doesn't need anything from flags except to understand +direction, so store it separately. For future patches, such change +will allow us to reuse xfrm_dev_offload for policy offload too, which +has three possible directions instead of two. + +Reviewed-by: Raed Salem +Signed-off-by: Leon Romanovsky +Signed-off-by: Steffen Klassert +Stable-dep-of: 2cf567f421db ("netdevsim: copy addresses for both in and out paths") +Signed-off-by: Sasha Levin +--- + include/net/xfrm.h | 6 ++++++ + net/xfrm/xfrm_device.c | 8 +++++++- + net/xfrm/xfrm_user.c | 3 ++- + 3 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/include/net/xfrm.h b/include/net/xfrm.h +index 987c603806aee..2c1feca282036 100644 +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -126,12 +126,18 @@ struct xfrm_state_walk { + struct xfrm_address_filter *filter; + }; + ++enum { ++ XFRM_DEV_OFFLOAD_IN = 1, ++ XFRM_DEV_OFFLOAD_OUT, ++}; ++ + struct xfrm_dev_offload { + struct net_device *dev; + struct net_device *real_dev; + unsigned long offload_handle; + unsigned int num_exthdrs; + u8 flags; ++ u8 dir : 2; + }; + + struct xfrm_mode { +diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c +index 61aa0fd9d2a0c..7690d23bcf8bb 100644 +--- a/net/xfrm/xfrm_device.c ++++ b/net/xfrm/xfrm_device.c +@@ -129,7 +129,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur + + sp = skb_sec_path(skb); + x = sp->xvec[sp->len - 1]; +- if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND) ++ if (xo->flags & XFRM_GRO || x->xso.dir == XFRM_DEV_OFFLOAD_IN) + return skb; + + /* This skb was already validated on the upper/virtual dev */ +@@ -285,11 +285,17 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, + /* Don't forward bit that is not implemented */ + xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6; + ++ if (xuo->flags & XFRM_OFFLOAD_INBOUND) ++ xso->dir = XFRM_DEV_OFFLOAD_IN; ++ else ++ xso->dir = XFRM_DEV_OFFLOAD_OUT; ++ + err = dev->xfrmdev_ops->xdo_dev_state_add(x); + if (err) { + xso->num_exthdrs = 0; + xso->flags = 0; + xso->dev = NULL; ++ xso->dir = 0; + xso->real_dev = NULL; + dev_put(dev); + +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index b12a305a2d7a4..aa509857b6660 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -855,7 +855,8 @@ static int copy_user_offload(struct xfrm_dev_offload *xso, struct sk_buff *skb) + xuo = nla_data(attr); + memset(xuo, 0, sizeof(*xuo)); + xuo->ifindex = xso->dev->ifindex; +- xuo->flags = xso->flags; ++ if (xso->dir == XFRM_DEV_OFFLOAD_IN) ++ xuo->flags = XFRM_OFFLOAD_INBOUND; + + return 0; + } +-- +2.43.0 +