From: Greg Kroah-Hartman Date: Mon, 11 Jan 2021 09:10:53 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v4.4.251~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f296af7083228c22216c6b7359994e7b606b83ee;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: alsa-hda-conexant-add-a-new-hda-codec-cx11970.patch alsa-hda-realtek-add-mute-led-quirk-for-more-hp-laptops.patch alsa-hda-realtek-add-two-intel-reference-board-ssid-in-the-alc256.patch alsa-hda-realtek-enable-mute-and-micmute-led-on-hp-elitebook-850-g7.patch alsa-hda-realtek-fix-speaker-volume-control-on-lenovo-c940.patch alsa-hda-via-fix-runtime-pm-for-clevo-w35xss.patch alsa-usb-audio-fix-ubsan-warnings-for-midi-jacks.patch arm64-link-with-z-norelro-for-lld-or-aarch64-elf.patch bcache-check-unsupported-feature-sets-for-bcache-register.patch bcache-fix-typo-from-suup-to-supp-in-features.h.patch bcache-introduce-bch_feature_incompat_log_large_bucket_size-for-large-bucket.patch blk-iocost-fix-null-iocg-deref-from-racing-against-initialization.patch btrfs-qgroup-don-t-try-to-wait-flushing-if-we-re-already-holding-a-transaction.patch btrfs-send-fix-wrong-file-path-when-there-is-an-inode-with-a-pending-rmdir.patch dmabuf-fix-use-after-free-of-dmabuf-s-file-f_inode.patch drm-i915-clear-the-gpu-reloc-batch.patch drm-i915-clear-the-shadow-batch.patch hwmon-amd_energy-fix-allocation-of-hwmon_channel_info-config.patch iommu-vt-d-move-intel_iommu-info-from-struct-intel_svm-to-struct-intel_svm_dev.patch kvm-check-tlbs_dirty-directly.patch kvm-x86-mmu-ensure-tdp-mmu-roots-are-freed-after-yield.patch kvm-x86-mmu-get-root-level-from-walkers-when-retrieving-mmio-spte.patch kvm-x86-mmu-use-1-to-flag-an-undefined-spte-in-get_mmio_spte.patch mm-make-wait_on_page_writeback-wait-for-multiple-pending-writebacks.patch revert-device-property-keep-secondary-firmware-node-secondary-by-type.patch usb-chipidea-ci_hdrc_imx-add-missing-put_device-call-in-usbmisc_get_init_data.patch usb-dwc3-gadget-clear-wait-flag-on-dequeue.patch usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch usb-dwc3-meson-g12a-disable-clk-on-error-handling-path-in-probe.patch usb-dwc3-ulpi-fix-usb2.0-hs-fs-ls-phy-suspend-regression.patch usb-dwc3-ulpi-replace-cpu-based-busyloop-with-protocol-based-one.patch usb-dwc3-ulpi-use-vstsdone-to-detect-phy-regs-access-completion.patch usb-gadget-configfs-fix-use-after-free-issue-with-udc_name.patch usb-gadget-configfs-preserve-function-ordering-after-bind-failure.patch usb-gadget-dummy-hcd-fix-shift-out-of-bounds-bug.patch usb-gadget-f_uac2-reset-wmaxpacketsize.patch usb-gadget-fix-spinlock-lockup-on-usb_function_deactivate.patch usb-gadget-function-printer-fix-a-memory-leak-for-interface-descriptor.patch usb-gadget-legacy-fix-return-error-code-in-acm_ms_bind.patch usb-gadget-select-config_crc32.patch usb-gadget-u_ether-fix-mtu-size-mismatch-with-rx-packet-size.patch usb-serial-iuu_phoenix-fix-dma-from-stack.patch usb-serial-keyspan_pda-remove-unused-variable.patch usb-serial-option-add-longsung-m5710-module-support.patch usb-serial-option-add-quectel-em160r-gl.patch usb-uas-add-pny-usb-portable-ssd-to-unusual_uas.patch usb-usbip-vhci_hcd-protect-shift-size.patch usb-usblp-fix-dma-to-stack.patch usb-xhci-fix-u1-u2-handling-for-hardware-with-xhci_intel_host-quirk-set.patch usb-yurex-fix-control-urb-timeout-handling.patch x86-mm-fix-leak-of-pmd-ptlock.patch x86-resctrl-don-t-move-a-task-to-the-same-resource-group.patch x86-resctrl-use-an-ipi-instead-of-task_work_add-to-update-pqr_assoc-msr.patch --- diff --git a/queue-5.10/alsa-hda-conexant-add-a-new-hda-codec-cx11970.patch b/queue-5.10/alsa-hda-conexant-add-a-new-hda-codec-cx11970.patch new file mode 100644 index 00000000000..f46ba77e586 --- /dev/null +++ b/queue-5.10/alsa-hda-conexant-add-a-new-hda-codec-cx11970.patch @@ -0,0 +1,34 @@ +From 744a11abc56405c5a106e63da30a941b6d27f737 Mon Sep 17 00:00:00 2001 +From: bo liu +Date: Tue, 29 Dec 2020 11:52:26 +0800 +Subject: ALSA: hda/conexant: add a new hda codec CX11970 + +From: bo liu + +commit 744a11abc56405c5a106e63da30a941b6d27f737 upstream. + +The current kernel does not support the cx11970 codec chip. +Add a codec configuration item to kernel. + +[ Minor coding style fix by tiwai ] + +Signed-off-by: bo liu +Cc: +Link: https://lore.kernel.org/r/20201229035226.62120-1-bo.liu@senarytech.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_conexant.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -1070,6 +1070,7 @@ static int patch_conexant_auto(struct hd + static const struct hda_device_id snd_hda_id_conexant[] = { + HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto), ++ HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto), diff --git a/queue-5.10/alsa-hda-realtek-add-mute-led-quirk-for-more-hp-laptops.patch b/queue-5.10/alsa-hda-realtek-add-mute-led-quirk-for-more-hp-laptops.patch new file mode 100644 index 00000000000..6230d032e32 --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-add-mute-led-quirk-for-more-hp-laptops.patch @@ -0,0 +1,35 @@ +From 484229585a5e91eeb00ee10e05d5204e1ca6c481 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Manuel=20Jim=C3=A9nez?= +Date: Tue, 29 Dec 2020 15:38:56 +0100 +Subject: ALSA: hda/realtek: Add mute LED quirk for more HP laptops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Manuel Jiménez + +commit 484229585a5e91eeb00ee10e05d5204e1ca6c481 upstream. + +HP Pavilion 13-bb0000 (SSID 103c:87c8) needs the same +quirk as other models with ALC287. + +Signed-off-by: Manuel Jiménez +Cc: +Link: https://lore.kernel.org/r/X+s/gKNydVrI6nLj@HP-Pavilion-13 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7969,6 +7969,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), ++ SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), diff --git a/queue-5.10/alsa-hda-realtek-add-two-intel-reference-board-ssid-in-the-alc256.patch b/queue-5.10/alsa-hda-realtek-add-two-intel-reference-board-ssid-in-the-alc256.patch new file mode 100644 index 00000000000..7543e679ea6 --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-add-two-intel-reference-board-ssid-in-the-alc256.patch @@ -0,0 +1,33 @@ +From ce2e79b223867b9e586021b55dee7035517a236b Mon Sep 17 00:00:00 2001 +From: PeiSen Hou +Date: Thu, 31 Dec 2020 11:57:28 +0100 +Subject: ALSA: hda/realtek: Add two "Intel Reference board" SSID in the ALC256. + +From: PeiSen Hou + +commit ce2e79b223867b9e586021b55dee7035517a236b upstream. + +Add two "Intel Reference boad" SSID in the alc256. +Enable "power saving mode" and Enable "headset jack mode". + +Signed-off-by: PeiSen Hou +Cc: +Link: https://lore.kernel.org/r/5978d2267f034c28973d117925ec9c63@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8028,6 +8028,8 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), + SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), + SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), ++ SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), ++ SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE), + SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), + SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), diff --git a/queue-5.10/alsa-hda-realtek-enable-mute-and-micmute-led-on-hp-elitebook-850-g7.patch b/queue-5.10/alsa-hda-realtek-enable-mute-and-micmute-led-on-hp-elitebook-850-g7.patch new file mode 100644 index 00000000000..5559d58efef --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-enable-mute-and-micmute-led-on-hp-elitebook-850-g7.patch @@ -0,0 +1,32 @@ +From a598098cc9737f612dbab52294433fc26c51cc9b Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Wed, 30 Dec 2020 20:56:35 +0800 +Subject: ALSA: hda/realtek: Enable mute and micmute LED on HP EliteBook 850 G7 + +From: Kai-Heng Feng + +commit a598098cc9737f612dbab52294433fc26c51cc9b upstream. + +HP EliteBook 850 G7 uses the same GPIO pins as ALC285_FIXUP_HP_GPIO_LED +to enable mute and micmute LED. So apply the quirk to enable the LEDs. + +Signed-off-by: Kai-Heng Feng +Cc: +Link: https://lore.kernel.org/r/20201230125636.45028-1-kai.heng.feng@canonical.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -7964,6 +7964,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), ++ SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), diff --git a/queue-5.10/alsa-hda-realtek-fix-speaker-volume-control-on-lenovo-c940.patch b/queue-5.10/alsa-hda-realtek-fix-speaker-volume-control-on-lenovo-c940.patch new file mode 100644 index 00000000000..a966662e1ef --- /dev/null +++ b/queue-5.10/alsa-hda-realtek-fix-speaker-volume-control-on-lenovo-c940.patch @@ -0,0 +1,56 @@ +From f86de9b1c0663b0a3ca2dcddec9aa910ff0fbf2c Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Fri, 23 Oct 2020 14:46:47 +0800 +Subject: ALSA: hda/realtek - Fix speaker volume control on Lenovo C940 + +From: Kailang Yang + +commit f86de9b1c0663b0a3ca2dcddec9aa910ff0fbf2c upstream. + +Cannot adjust speaker's volume on Lenovo C940. +Applying the alc298_fixup_speaker_volume function can fix the issue. + +[ Additional note: C940 has I2S amp for the speaker and this needs the + same initialization as Dell machines. + The patch was slightly modified so that the quirk entry is moved + next to the corresponding Dell quirk entry. -- tiwai ] + +Signed-off-by: Kailang Yang +Cc: +Link: https://lore.kernel.org/r/ea25b4e5c468491aa2e9d6cb1f2fced3@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6289,6 +6289,7 @@ enum { + ALC221_FIXUP_HP_FRONT_MIC, + ALC292_FIXUP_TPT460, + ALC298_FIXUP_SPK_VOLUME, ++ ALC298_FIXUP_LENOVO_SPK_VOLUME, + ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, + ALC269_FIXUP_ATIV_BOOK_8, + ALC221_FIXUP_HP_MIC_NO_PRESENCE, +@@ -7119,6 +7120,10 @@ static const struct hda_fixup alc269_fix + .chained = true, + .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, + }, ++ [ALC298_FIXUP_LENOVO_SPK_VOLUME] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc298_fixup_speaker_volume, ++ }, + [ALC295_FIXUP_DISABLE_DAC3] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc295_fixup_disable_dac3, +@@ -8126,6 +8131,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), ++ SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), diff --git a/queue-5.10/alsa-hda-via-fix-runtime-pm-for-clevo-w35xss.patch b/queue-5.10/alsa-hda-via-fix-runtime-pm-for-clevo-w35xss.patch new file mode 100644 index 00000000000..6bca07a60e9 --- /dev/null +++ b/queue-5.10/alsa-hda-via-fix-runtime-pm-for-clevo-w35xss.patch @@ -0,0 +1,85 @@ +From 4bfd6247fa9164c8e193a55ef9c0ea3ee22f82d8 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 4 Jan 2021 16:30:46 +0100 +Subject: ALSA: hda/via: Fix runtime PM for Clevo W35xSS + +From: Takashi Iwai + +commit 4bfd6247fa9164c8e193a55ef9c0ea3ee22f82d8 upstream. + +Clevo W35xSS_370SS with VIA codec has had the runtime PM problem that +looses the power state of some nodes after the runtime resume. This +was worked around by disabling the default runtime PM via a denylist +entry. Since 5.10.x made the runtime PM applied (casually) even +though it's disabled in the denylist, this problem was revisited. The +result was that disabling power_save_node feature suffices for the +runtime PM problem. + +This patch implements the disablement of power_save_node feature in +VIA codec for the device. It also drops the former denylist entry, +too, as the runtime PM should work in the codec side properly now. + +Fixes: b529ef2464ad ("ALSA: hda: Add Clevo W35xSS_370SS to the power_save blacklist") +Reported-by: Christian Labisch +Cc: +Link: https://lore.kernel.org/r/20210104153046.19993-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/hda_intel.c | 2 -- + sound/pci/hda/patch_via.c | 13 +++++++++++++ + 2 files changed, 13 insertions(+), 2 deletions(-) + +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2220,8 +2220,6 @@ static const struct snd_pci_quirk power_ + SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ + SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), +- /* https://bugzilla.redhat.com/show_bug.cgi?id=1581607 */ +- SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ + SND_PCI_QUIRK(0x1558, 0x6504, "Clevo W65_67SB", 0), + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ +--- a/sound/pci/hda/patch_via.c ++++ b/sound/pci/hda/patch_via.c +@@ -1002,6 +1002,7 @@ static const struct hda_verb vt1802_init + enum { + VIA_FIXUP_INTMIC_BOOST, + VIA_FIXUP_ASUS_G75, ++ VIA_FIXUP_POWER_SAVE, + }; + + static void via_fixup_intmic_boost(struct hda_codec *codec, +@@ -1011,6 +1012,13 @@ static void via_fixup_intmic_boost(struc + override_mic_boost(codec, 0x30, 0, 2, 40); + } + ++static void via_fixup_power_save(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ codec->power_save_node = 0; ++} ++ + static const struct hda_fixup via_fixups[] = { + [VIA_FIXUP_INTMIC_BOOST] = { + .type = HDA_FIXUP_FUNC, +@@ -1025,11 +1033,16 @@ static const struct hda_fixup via_fixups + { } + } + }, ++ [VIA_FIXUP_POWER_SAVE] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = via_fixup_power_save, ++ }, + }; + + static const struct snd_pci_quirk vt2002p_fixups[] = { + SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), + SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), ++ SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", VIA_FIXUP_POWER_SAVE), + {} + }; + diff --git a/queue-5.10/alsa-usb-audio-fix-ubsan-warnings-for-midi-jacks.patch b/queue-5.10/alsa-usb-audio-fix-ubsan-warnings-for-midi-jacks.patch new file mode 100644 index 00000000000..807dc628344 --- /dev/null +++ b/queue-5.10/alsa-usb-audio-fix-ubsan-warnings-for-midi-jacks.patch @@ -0,0 +1,46 @@ +From c06ccf3ebb7503706ea49fd248e709287ef385a3 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 23 Dec 2020 18:45:57 +0100 +Subject: ALSA: usb-audio: Fix UBSAN warnings for MIDI jacks + +From: Takashi Iwai + +commit c06ccf3ebb7503706ea49fd248e709287ef385a3 upstream. + +The calculation of in_cables and out_cables bitmaps are done with the +bit shift by the value from the descriptor, which is an arbitrary +value, and can lead to UBSAN shift-out-of-bounds warnings. + +Fix it by filtering the bad descriptor values with the check of the +upper bound 0x10 (the cable bitmaps are 16 bits). + +Reported-by: syzbot+92e45ae45543f89e8c88@syzkaller.appspotmail.com +Cc: +Link: https://lore.kernel.org/r/20201223174557.10249-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/midi.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -1889,6 +1889,8 @@ static int snd_usbmidi_get_ms_info(struc + ms_ep = find_usb_ms_endpoint_descriptor(hostep); + if (!ms_ep) + continue; ++ if (ms_ep->bNumEmbMIDIJack > 0x10) ++ continue; + if (usb_endpoint_dir_out(ep)) { + if (endpoints[epidx].out_ep) { + if (++epidx >= MIDI_MAX_ENDPOINTS) { +@@ -2141,6 +2143,8 @@ static int snd_usbmidi_detect_roland(str + cs_desc[1] == USB_DT_CS_INTERFACE && + cs_desc[2] == 0xf1 && + cs_desc[3] == 0x02) { ++ if (cs_desc[4] > 0x10 || cs_desc[5] > 0x10) ++ continue; + endpoint->in_cables = (1 << cs_desc[4]) - 1; + endpoint->out_cables = (1 << cs_desc[5]) - 1; + return snd_usbmidi_detect_endpoints(umidi, endpoint, 1); diff --git a/queue-5.10/arm64-link-with-z-norelro-for-lld-or-aarch64-elf.patch b/queue-5.10/arm64-link-with-z-norelro-for-lld-or-aarch64-elf.patch new file mode 100644 index 00000000000..4f00d29b2de --- /dev/null +++ b/queue-5.10/arm64-link-with-z-norelro-for-lld-or-aarch64-elf.patch @@ -0,0 +1,85 @@ +From 311bea3cb9ee20ef150ca76fc60a592bf6b159f5 Mon Sep 17 00:00:00 2001 +From: Nick Desaulniers +Date: Thu, 17 Dec 2020 16:24:32 -0800 +Subject: arm64: link with -z norelro for LLD or aarch64-elf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nick Desaulniers + +commit 311bea3cb9ee20ef150ca76fc60a592bf6b159f5 upstream. + +With GNU binutils 2.35+, linking with BFD produces warnings for vmlinux: +aarch64-linux-gnu-ld: warning: -z norelro ignored + +BFD can produce this warning when the target emulation mode does not +support RELRO program headers, and -z relro or -z norelro is passed. + +Alan Modra clarifies: + The default linker emulation for an aarch64-linux ld.bfd is + -maarch64linux, the default for an aarch64-elf linker is + -maarch64elf. They are not equivalent. If you choose -maarch64elf + you get an emulation that doesn't support -z relro. + +The ARCH=arm64 kernel prefers -maarch64elf, but may fall back to +-maarch64linux based on the toolchain configuration. + +LLD will always create RELRO program header regardless of target +emulation. + +To avoid the above warning when linking with BFD, pass -z norelro only +when linking with LLD or with -maarch64linux. + +Fixes: 3b92fa7485eb ("arm64: link with -z norelro regardless of CONFIG_RELOCATABLE") +Fixes: 3bbd3db86470 ("arm64: relocatable: fix inconsistencies in linker script and options") +Cc: # 5.0.x- +Reported-by: kernelci.org bot +Reported-by: Quentin Perret +Signed-off-by: Nick Desaulniers +Reviewed-by: Nathan Chancellor +Acked-by: Ard Biesheuvel +Cc: Alan Modra +Cc: Fāng-ruì Sòng +Link: https://lore.kernel.org/r/20201218002432.788499-1-ndesaulniers@google.com +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/Makefile | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -10,7 +10,7 @@ + # + # Copyright (C) 1995-2001 by Russell King + +-LDFLAGS_vmlinux :=--no-undefined -X -z norelro ++LDFLAGS_vmlinux :=--no-undefined -X + + ifeq ($(CONFIG_RELOCATABLE), y) + # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour +@@ -110,16 +110,20 @@ KBUILD_CPPFLAGS += -mbig-endian + CHECKFLAGS += -D__AARCH64EB__ + # Prefer the baremetal ELF build target, but not all toolchains include + # it so fall back to the standard linux version if needed. +-KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb) ++KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb -z norelro) + UTS_MACHINE := aarch64_be + else + KBUILD_CPPFLAGS += -mlittle-endian + CHECKFLAGS += -D__AARCH64EL__ + # Same as above, prefer ELF but fall back to linux target if needed. +-KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux) ++KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux -z norelro) + UTS_MACHINE := aarch64 + endif + ++ifeq ($(CONFIG_LD_IS_LLD), y) ++KBUILD_LDFLAGS += -z norelro ++endif ++ + CHECKFLAGS += -D__aarch64__ + + ifeq ($(CONFIG_DYNAMIC_FTRACE_WITH_REGS),y) diff --git a/queue-5.10/bcache-check-unsupported-feature-sets-for-bcache-register.patch b/queue-5.10/bcache-check-unsupported-feature-sets-for-bcache-register.patch new file mode 100644 index 00000000000..08b4d97db91 --- /dev/null +++ b/queue-5.10/bcache-check-unsupported-feature-sets-for-bcache-register.patch @@ -0,0 +1,77 @@ +From 1dfc0686c29a9bbd3a446a29f9ccde3dec3bc75a Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Mon, 4 Jan 2021 15:41:20 +0800 +Subject: bcache: check unsupported feature sets for bcache register + +From: Coly Li + +commit 1dfc0686c29a9bbd3a446a29f9ccde3dec3bc75a upstream. + +This patch adds the check for features which is incompatible for +current supported feature sets. + +Now if the bcache device created by bcache-tools has features that +current kernel doesn't support, read_super() will fail with error +messoage. E.g. if an unsupported incompatible feature detected, +bcache register will fail with dmesg "bcache: register_bcache() error : +Unsupported incompatible feature found". + +Fixes: d721a43ff69c ("bcache: increase super block version for cache device and backing device") +Fixes: ffa470327572 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket") +Signed-off-by: Coly Li +Cc: stable@vger.kernel.org # 5.9+ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bcache/features.h | 15 +++++++++++++++ + drivers/md/bcache/super.c | 14 ++++++++++++++ + 2 files changed, 29 insertions(+) + +--- a/drivers/md/bcache/features.h ++++ b/drivers/md/bcache/features.h +@@ -79,6 +79,21 @@ static inline void bch_clear_feature_##n + + BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET); + ++static inline bool bch_has_unknown_compat_features(struct cache_sb *sb) ++{ ++ return ((sb->feature_compat & ~BCH_FEATURE_COMPAT_SUPP) != 0); ++} ++ ++static inline bool bch_has_unknown_ro_compat_features(struct cache_sb *sb) ++{ ++ return ((sb->feature_ro_compat & ~BCH_FEATURE_RO_COMPAT_SUPP) != 0); ++} ++ ++static inline bool bch_has_unknown_incompat_features(struct cache_sb *sb) ++{ ++ return ((sb->feature_incompat & ~BCH_FEATURE_INCOMPAT_SUPP) != 0); ++} ++ + int bch_print_cache_set_feature_compat(struct cache_set *c, char *buf, int size); + int bch_print_cache_set_feature_ro_compat(struct cache_set *c, char *buf, int size); + int bch_print_cache_set_feature_incompat(struct cache_set *c, char *buf, int size); +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -228,6 +228,20 @@ static const char *read_super(struct cac + sb->feature_compat = le64_to_cpu(s->feature_compat); + sb->feature_incompat = le64_to_cpu(s->feature_incompat); + sb->feature_ro_compat = le64_to_cpu(s->feature_ro_compat); ++ ++ /* Check incompatible features */ ++ err = "Unsupported compatible feature found"; ++ if (bch_has_unknown_compat_features(sb)) ++ goto err; ++ ++ err = "Unsupported read-only compatible feature found"; ++ if (bch_has_unknown_ro_compat_features(sb)) ++ goto err; ++ ++ err = "Unsupported incompatible feature found"; ++ if (bch_has_unknown_incompat_features(sb)) ++ goto err; ++ + err = read_super_common(sb, bdev, s); + if (err) + goto err; diff --git a/queue-5.10/bcache-fix-typo-from-suup-to-supp-in-features.h.patch b/queue-5.10/bcache-fix-typo-from-suup-to-supp-in-features.h.patch new file mode 100644 index 00000000000..2037affb59b --- /dev/null +++ b/queue-5.10/bcache-fix-typo-from-suup-to-supp-in-features.h.patch @@ -0,0 +1,40 @@ +From f7b4943dea48a572ad751ce1f18a245d43debe7e Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Mon, 4 Jan 2021 15:41:19 +0800 +Subject: bcache: fix typo from SUUP to SUPP in features.h + +From: Coly Li + +commit f7b4943dea48a572ad751ce1f18a245d43debe7e upstream. + +This patch fixes the following typos, +from BCH_FEATURE_COMPAT_SUUP to BCH_FEATURE_COMPAT_SUPP +from BCH_FEATURE_INCOMPAT_SUUP to BCH_FEATURE_INCOMPAT_SUPP +from BCH_FEATURE_INCOMPAT_SUUP to BCH_FEATURE_RO_COMPAT_SUPP + +Fixes: d721a43ff69c ("bcache: increase super block version for cache device and backing device") +Fixes: ffa470327572 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket") +Signed-off-by: Coly Li +Cc: stable@vger.kernel.org # 5.9+ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bcache/features.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/md/bcache/features.h ++++ b/drivers/md/bcache/features.h +@@ -15,9 +15,9 @@ + /* Incompat feature set */ + #define BCH_FEATURE_INCOMPAT_LARGE_BUCKET 0x0001 /* 32bit bucket size */ + +-#define BCH_FEATURE_COMPAT_SUUP 0 +-#define BCH_FEATURE_RO_COMPAT_SUUP 0 +-#define BCH_FEATURE_INCOMPAT_SUUP BCH_FEATURE_INCOMPAT_LARGE_BUCKET ++#define BCH_FEATURE_COMPAT_SUPP 0 ++#define BCH_FEATURE_RO_COMPAT_SUPP 0 ++#define BCH_FEATURE_INCOMPAT_SUPP BCH_FEATURE_INCOMPAT_LARGE_BUCKET + + #define BCH_HAS_COMPAT_FEATURE(sb, mask) \ + ((sb)->feature_compat & (mask)) diff --git a/queue-5.10/bcache-introduce-bch_feature_incompat_log_large_bucket_size-for-large-bucket.patch b/queue-5.10/bcache-introduce-bch_feature_incompat_log_large_bucket_size-for-large-bucket.patch new file mode 100644 index 00000000000..28f9e40ecf5 --- /dev/null +++ b/queue-5.10/bcache-introduce-bch_feature_incompat_log_large_bucket_size-for-large-bucket.patch @@ -0,0 +1,141 @@ +From b16671e8f493e3df40b1fb0dff4078f391c5099a Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Mon, 4 Jan 2021 15:41:21 +0800 +Subject: bcache: introduce BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE for large bucket + +From: Coly Li + +commit b16671e8f493e3df40b1fb0dff4078f391c5099a upstream. + +When large bucket feature was added, BCH_FEATURE_INCOMPAT_LARGE_BUCKET +was introduced into the incompat feature set. It used bucket_size_hi +(which was added at the tail of struct cache_sb_disk) to extend current +16bit bucket size to 32bit with existing bucket_size in struct +cache_sb_disk. + +This is not a good idea, there are two obvious problems, +- Bucket size is always value power of 2, if store log2(bucket size) in + existing bucket_size of struct cache_sb_disk, it is unnecessary to add + bucket_size_hi. +- Macro csum_set() assumes d[SB_JOURNAL_BUCKETS] is the last member in + struct cache_sb_disk, bucket_size_hi was added after d[] which makes + csum_set calculate an unexpected super block checksum. + +To fix the above problems, this patch introduces a new incompat feature +bit BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE, when this bit is set, it +means bucket_size in struct cache_sb_disk stores the order of power-of-2 +bucket size value. When user specifies a bucket size larger than 32768 +sectors, BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE will be set to +incompat feature set, and bucket_size stores log2(bucket size) more +than store the real bucket size value. + +The obsoleted BCH_FEATURE_INCOMPAT_LARGE_BUCKET won't be used anymore, +it is renamed to BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET and still only +recognized by kernel driver for legacy compatible purpose. The previous +bucket_size_hi is renmaed to obso_bucket_size_hi in struct cache_sb_disk +and not used in bcache-tools anymore. + +For cache device created with BCH_FEATURE_INCOMPAT_LARGE_BUCKET feature, +bcache-tools and kernel driver still recognize the feature string and +display it as "obso_large_bucket". + +With this change, the unnecessary extra space extend of bcache on-disk +super block can be avoided, and csum_set() may generate expected check +sum as well. + +Fixes: ffa470327572 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket") +Signed-off-by: Coly Li +Cc: stable@vger.kernel.org # 5.9+ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bcache/features.c | 2 +- + drivers/md/bcache/features.h | 11 ++++++++--- + drivers/md/bcache/super.c | 22 +++++++++++++++++++--- + include/uapi/linux/bcache.h | 2 +- + 4 files changed, 29 insertions(+), 8 deletions(-) + +--- a/drivers/md/bcache/features.c ++++ b/drivers/md/bcache/features.c +@@ -17,7 +17,7 @@ struct feature { + }; + + static struct feature feature_list[] = { +- {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LARGE_BUCKET, ++ {BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE, + "large_bucket"}, + {0, 0, 0 }, + }; +--- a/drivers/md/bcache/features.h ++++ b/drivers/md/bcache/features.h +@@ -13,11 +13,15 @@ + + /* Feature set definition */ + /* Incompat feature set */ +-#define BCH_FEATURE_INCOMPAT_LARGE_BUCKET 0x0001 /* 32bit bucket size */ ++/* 32bit bucket size, obsoleted */ ++#define BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET 0x0001 ++/* real bucket size is (1 << bucket_size) */ ++#define BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE 0x0002 + + #define BCH_FEATURE_COMPAT_SUPP 0 + #define BCH_FEATURE_RO_COMPAT_SUPP 0 +-#define BCH_FEATURE_INCOMPAT_SUPP BCH_FEATURE_INCOMPAT_LARGE_BUCKET ++#define BCH_FEATURE_INCOMPAT_SUPP (BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET| \ ++ BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE) + + #define BCH_HAS_COMPAT_FEATURE(sb, mask) \ + ((sb)->feature_compat & (mask)) +@@ -77,7 +81,8 @@ static inline void bch_clear_feature_##n + ~BCH##_FEATURE_INCOMPAT_##flagname; \ + } + +-BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET); ++BCH_FEATURE_INCOMPAT_FUNCS(obso_large_bucket, OBSO_LARGE_BUCKET); ++BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LOG_LARGE_BUCKET_SIZE); + + static inline bool bch_has_unknown_compat_features(struct cache_sb *sb) + { +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -64,9 +64,25 @@ static unsigned int get_bucket_size(stru + { + unsigned int bucket_size = le16_to_cpu(s->bucket_size); + +- if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES && +- bch_has_feature_large_bucket(sb)) +- bucket_size |= le16_to_cpu(s->bucket_size_hi) << 16; ++ if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES) { ++ if (bch_has_feature_large_bucket(sb)) { ++ unsigned int max, order; ++ ++ max = sizeof(unsigned int) * BITS_PER_BYTE - 1; ++ order = le16_to_cpu(s->bucket_size); ++ /* ++ * bcache tool will make sure the overflow won't ++ * happen, an error message here is enough. ++ */ ++ if (order > max) ++ pr_err("Bucket size (1 << %u) overflows\n", ++ order); ++ bucket_size = 1 << order; ++ } else if (bch_has_feature_obso_large_bucket(sb)) { ++ bucket_size += ++ le16_to_cpu(s->obso_bucket_size_hi) << 16; ++ } ++ } + + return bucket_size; + } +--- a/include/uapi/linux/bcache.h ++++ b/include/uapi/linux/bcache.h +@@ -213,7 +213,7 @@ struct cache_sb_disk { + __le16 keys; + }; + __le64 d[SB_JOURNAL_BUCKETS]; /* journal buckets */ +- __le16 bucket_size_hi; ++ __le16 obso_bucket_size_hi; /* obsoleted */ + }; + + /* diff --git a/queue-5.10/blk-iocost-fix-null-iocg-deref-from-racing-against-initialization.patch b/queue-5.10/blk-iocost-fix-null-iocg-deref-from-racing-against-initialization.patch new file mode 100644 index 00000000000..c668cdb425b --- /dev/null +++ b/queue-5.10/blk-iocost-fix-null-iocg-deref-from-racing-against-initialization.patch @@ -0,0 +1,84 @@ +From d16baa3f1453c14d680c5fee01cd122a22d0e0ce Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Tue, 5 Jan 2021 12:37:23 -0500 +Subject: blk-iocost: fix NULL iocg deref from racing against initialization + +From: Tejun Heo + +commit d16baa3f1453c14d680c5fee01cd122a22d0e0ce upstream. + +When initializing iocost for a queue, its rqos should be registered before +the blkcg policy is activated to allow policy data initiailization to lookup +the associated ioc. This unfortunately means that the rqos methods can be +called on bios before iocgs are attached to all existing blkgs. + +While the race is theoretically possible on ioc_rqos_throttle(), it mostly +happened in ioc_rqos_merge() due to the difference in how they lookup ioc. +The former determines it from the passed in @rqos and then bails before +dereferencing iocg if the looked up ioc is disabled, which most likely is +the case if initialization is still in progress. The latter looked up ioc by +dereferencing the possibly NULL iocg making it a lot more prone to actually +triggering the bug. + +* Make ioc_rqos_merge() use the same method as ioc_rqos_throttle() to look + up ioc for consistency. + +* Make ioc_rqos_throttle() and ioc_rqos_merge() test for NULL iocg before + dereferencing it. + +* Explain the danger of NULL iocgs in blk_iocost_init(). + +Signed-off-by: Tejun Heo +Reported-by: Jonathan Lemon +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-iocost.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/block/blk-iocost.c ++++ b/block/blk-iocost.c +@@ -2525,8 +2525,8 @@ static void ioc_rqos_throttle(struct rq_ + bool use_debt, ioc_locked; + unsigned long flags; + +- /* bypass IOs if disabled or for root cgroup */ +- if (!ioc->enabled || !iocg->level) ++ /* bypass IOs if disabled, still initializing, or for root cgroup */ ++ if (!ioc->enabled || !iocg || !iocg->level) + return; + + /* calculate the absolute vtime cost */ +@@ -2653,14 +2653,14 @@ static void ioc_rqos_merge(struct rq_qos + struct bio *bio) + { + struct ioc_gq *iocg = blkg_to_iocg(bio->bi_blkg); +- struct ioc *ioc = iocg->ioc; ++ struct ioc *ioc = rqos_to_ioc(rqos); + sector_t bio_end = bio_end_sector(bio); + struct ioc_now now; + u64 vtime, abs_cost, cost; + unsigned long flags; + +- /* bypass if disabled or for root cgroup */ +- if (!ioc->enabled || !iocg->level) ++ /* bypass if disabled, still initializing, or for root cgroup */ ++ if (!ioc->enabled || !iocg || !iocg->level) + return; + + abs_cost = calc_vtime_cost(bio, iocg, true); +@@ -2837,6 +2837,12 @@ static int blk_iocost_init(struct reques + ioc_refresh_params(ioc, true); + spin_unlock_irq(&ioc->lock); + ++ /* ++ * rqos must be added before activation to allow iocg_pd_init() to ++ * lookup the ioc from q. This means that the rqos methods may get ++ * called before policy activation completion, can't assume that the ++ * target bio has an iocg associated and need to test for NULL iocg. ++ */ + rq_qos_add(q, rqos); + ret = blkcg_activate_policy(q, &blkcg_policy_iocost); + if (ret) { diff --git a/queue-5.10/btrfs-qgroup-don-t-try-to-wait-flushing-if-we-re-already-holding-a-transaction.patch b/queue-5.10/btrfs-qgroup-don-t-try-to-wait-flushing-if-we-re-already-holding-a-transaction.patch new file mode 100644 index 00000000000..f6491b25388 --- /dev/null +++ b/queue-5.10/btrfs-qgroup-don-t-try-to-wait-flushing-if-we-re-already-holding-a-transaction.patch @@ -0,0 +1,91 @@ +From ae5e070eaca9dbebde3459dd8f4c2756f8c097d0 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Fri, 4 Dec 2020 09:24:47 +0800 +Subject: btrfs: qgroup: don't try to wait flushing if we're already holding a transaction + +From: Qu Wenruo + +commit ae5e070eaca9dbebde3459dd8f4c2756f8c097d0 upstream. + +There is a chance of racing for qgroup flushing which may lead to +deadlock: + + Thread A | Thread B + (not holding trans handle) | (holding a trans handle) +--------------------------------+-------------------------------- +__btrfs_qgroup_reserve_meta() | __btrfs_qgroup_reserve_meta() +|- try_flush_qgroup() | |- try_flush_qgroup() + |- QGROUP_FLUSHING bit set | | + | | |- test_and_set_bit() + | | |- wait_event() + |- btrfs_join_transaction() | + |- btrfs_commit_transaction()| + + !!! DEAD LOCK !!! + +Since thread A wants to commit transaction, but thread B is holding a +transaction handle, blocking the commit. +At the same time, thread B is waiting for thread A to finish its commit. + +This is just a hot fix, and would lead to more EDQUOT when we're near +the qgroup limit. + +The proper fix would be to make all metadata/data reservations happen +without holding a transaction handle. + +CC: stable@vger.kernel.org # 5.9+ +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/qgroup.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -3565,16 +3565,6 @@ static int try_flush_qgroup(struct btrfs + bool can_commit = true; + + /* +- * We don't want to run flush again and again, so if there is a running +- * one, we won't try to start a new flush, but exit directly. +- */ +- if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) { +- wait_event(root->qgroup_flush_wait, +- !test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)); +- return 0; +- } +- +- /* + * If current process holds a transaction, we shouldn't flush, as we + * assume all space reservation happens before a transaction handle is + * held. +@@ -3588,6 +3578,26 @@ static int try_flush_qgroup(struct btrfs + current->journal_info != BTRFS_SEND_TRANS_STUB) + can_commit = false; + ++ /* ++ * We don't want to run flush again and again, so if there is a running ++ * one, we won't try to start a new flush, but exit directly. ++ */ ++ if (test_and_set_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)) { ++ /* ++ * We are already holding a transaction, thus we can block other ++ * threads from flushing. So exit right now. This increases ++ * the chance of EDQUOT for heavy load and near limit cases. ++ * But we can argue that if we're already near limit, EDQUOT is ++ * unavoidable anyway. ++ */ ++ if (!can_commit) ++ return 0; ++ ++ wait_event(root->qgroup_flush_wait, ++ !test_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state)); ++ return 0; ++ } ++ + ret = btrfs_start_delalloc_snapshot(root); + if (ret < 0) + goto out; diff --git a/queue-5.10/btrfs-send-fix-wrong-file-path-when-there-is-an-inode-with-a-pending-rmdir.patch b/queue-5.10/btrfs-send-fix-wrong-file-path-when-there-is-an-inode-with-a-pending-rmdir.patch new file mode 100644 index 00000000000..a09ead03f92 --- /dev/null +++ b/queue-5.10/btrfs-send-fix-wrong-file-path-when-there-is-an-inode-with-a-pending-rmdir.patch @@ -0,0 +1,290 @@ +From 0b3f407e6728d990ae1630a02c7b952c21c288d3 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Thu, 10 Dec 2020 12:09:02 +0000 +Subject: btrfs: send: fix wrong file path when there is an inode with a pending rmdir + +From: Filipe Manana + +commit 0b3f407e6728d990ae1630a02c7b952c21c288d3 upstream. + +When doing an incremental send, if we have a new inode that happens to +have the same number that an old directory inode had in the base snapshot +and that old directory has a pending rmdir operation, we end up computing +a wrong path for the new inode, causing the receiver to fail. + +Example reproducer: + + $ cat test-send-rmdir.sh + #!/bin/bash + + DEV=/dev/sdi + MNT=/mnt/sdi + + mkfs.btrfs -f $DEV >/dev/null + mount $DEV $MNT + + mkdir $MNT/dir + touch $MNT/dir/file1 + touch $MNT/dir/file2 + touch $MNT/dir/file3 + + # Filesystem looks like: + # + # . (ino 256) + # |----- dir/ (ino 257) + # |----- file1 (ino 258) + # |----- file2 (ino 259) + # |----- file3 (ino 260) + # + + btrfs subvolume snapshot -r $MNT $MNT/snap1 + btrfs send -f /tmp/snap1.send $MNT/snap1 + + # Now remove our directory and all its files. + rm -fr $MNT/dir + + # Unmount the filesystem and mount it again. This is to ensure that + # the next inode that is created ends up with the same inode number + # that our directory "dir" had, 257, which is the first free "objectid" + # available after mounting again the filesystem. + umount $MNT + mount $DEV $MNT + + # Now create a new file (it could be a directory as well). + touch $MNT/newfile + + # Filesystem now looks like: + # + # . (ino 256) + # |----- newfile (ino 257) + # + + btrfs subvolume snapshot -r $MNT $MNT/snap2 + btrfs send -f /tmp/snap2.send -p $MNT/snap1 $MNT/snap2 + + # Now unmount the filesystem, create a new one, mount it and try to apply + # both send streams to recreate both snapshots. + umount $DEV + + mkfs.btrfs -f $DEV >/dev/null + + mount $DEV $MNT + + btrfs receive -f /tmp/snap1.send $MNT + btrfs receive -f /tmp/snap2.send $MNT + + umount $MNT + +When running the test, the receive operation for the incremental stream +fails: + + $ ./test-send-rmdir.sh + Create a readonly snapshot of '/mnt/sdi' in '/mnt/sdi/snap1' + At subvol /mnt/sdi/snap1 + Create a readonly snapshot of '/mnt/sdi' in '/mnt/sdi/snap2' + At subvol /mnt/sdi/snap2 + At subvol snap1 + At snapshot snap2 + ERROR: chown o257-9-0 failed: No such file or directory + +So fix this by tracking directories that have a pending rmdir by inode +number and generation number, instead of only inode number. + +A test case for fstests follows soon. + +Reported-by: Massimo B. +Tested-by: Massimo B. +Link: https://lore.kernel.org/linux-btrfs/6ae34776e85912960a253a8327068a892998e685.camel@gmx.net/ +CC: stable@vger.kernel.org # 4.19+ +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/send.c | 49 +++++++++++++++++++++++++++++++------------------ + 1 file changed, 31 insertions(+), 18 deletions(-) + +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -236,6 +236,7 @@ struct waiting_dir_move { + * after this directory is moved, we can try to rmdir the ino rmdir_ino. + */ + u64 rmdir_ino; ++ u64 rmdir_gen; + bool orphanized; + }; + +@@ -316,7 +317,7 @@ static int is_waiting_for_move(struct se + static struct waiting_dir_move * + get_waiting_dir_move(struct send_ctx *sctx, u64 ino); + +-static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino); ++static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen); + + static int need_send_hole(struct send_ctx *sctx) + { +@@ -2299,7 +2300,7 @@ static int get_cur_path(struct send_ctx + + fs_path_reset(name); + +- if (is_waiting_for_rm(sctx, ino)) { ++ if (is_waiting_for_rm(sctx, ino, gen)) { + ret = gen_unique_name(sctx, ino, gen, name); + if (ret < 0) + goto out; +@@ -2858,8 +2859,8 @@ out: + return ret; + } + +-static struct orphan_dir_info * +-add_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) ++static struct orphan_dir_info *add_orphan_dir_info(struct send_ctx *sctx, ++ u64 dir_ino, u64 dir_gen) + { + struct rb_node **p = &sctx->orphan_dirs.rb_node; + struct rb_node *parent = NULL; +@@ -2868,20 +2869,23 @@ add_orphan_dir_info(struct send_ctx *sct + while (*p) { + parent = *p; + entry = rb_entry(parent, struct orphan_dir_info, node); +- if (dir_ino < entry->ino) { ++ if (dir_ino < entry->ino) + p = &(*p)->rb_left; +- } else if (dir_ino > entry->ino) { ++ else if (dir_ino > entry->ino) + p = &(*p)->rb_right; +- } else { ++ else if (dir_gen < entry->gen) ++ p = &(*p)->rb_left; ++ else if (dir_gen > entry->gen) ++ p = &(*p)->rb_right; ++ else + return entry; +- } + } + + odi = kmalloc(sizeof(*odi), GFP_KERNEL); + if (!odi) + return ERR_PTR(-ENOMEM); + odi->ino = dir_ino; +- odi->gen = 0; ++ odi->gen = dir_gen; + odi->last_dir_index_offset = 0; + + rb_link_node(&odi->node, parent, p); +@@ -2889,8 +2893,8 @@ add_orphan_dir_info(struct send_ctx *sct + return odi; + } + +-static struct orphan_dir_info * +-get_orphan_dir_info(struct send_ctx *sctx, u64 dir_ino) ++static struct orphan_dir_info *get_orphan_dir_info(struct send_ctx *sctx, ++ u64 dir_ino, u64 gen) + { + struct rb_node *n = sctx->orphan_dirs.rb_node; + struct orphan_dir_info *entry; +@@ -2901,15 +2905,19 @@ get_orphan_dir_info(struct send_ctx *sct + n = n->rb_left; + else if (dir_ino > entry->ino) + n = n->rb_right; ++ else if (gen < entry->gen) ++ n = n->rb_left; ++ else if (gen > entry->gen) ++ n = n->rb_right; + else + return entry; + } + return NULL; + } + +-static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino) ++static int is_waiting_for_rm(struct send_ctx *sctx, u64 dir_ino, u64 gen) + { +- struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino); ++ struct orphan_dir_info *odi = get_orphan_dir_info(sctx, dir_ino, gen); + + return odi != NULL; + } +@@ -2954,7 +2962,7 @@ static int can_rmdir(struct send_ctx *sc + key.type = BTRFS_DIR_INDEX_KEY; + key.offset = 0; + +- odi = get_orphan_dir_info(sctx, dir); ++ odi = get_orphan_dir_info(sctx, dir, dir_gen); + if (odi) + key.offset = odi->last_dir_index_offset; + +@@ -2985,7 +2993,7 @@ static int can_rmdir(struct send_ctx *sc + + dm = get_waiting_dir_move(sctx, loc.objectid); + if (dm) { +- odi = add_orphan_dir_info(sctx, dir); ++ odi = add_orphan_dir_info(sctx, dir, dir_gen); + if (IS_ERR(odi)) { + ret = PTR_ERR(odi); + goto out; +@@ -2993,12 +3001,13 @@ static int can_rmdir(struct send_ctx *sc + odi->gen = dir_gen; + odi->last_dir_index_offset = found_key.offset; + dm->rmdir_ino = dir; ++ dm->rmdir_gen = dir_gen; + ret = 0; + goto out; + } + + if (loc.objectid > send_progress) { +- odi = add_orphan_dir_info(sctx, dir); ++ odi = add_orphan_dir_info(sctx, dir, dir_gen); + if (IS_ERR(odi)) { + ret = PTR_ERR(odi); + goto out; +@@ -3038,6 +3047,7 @@ static int add_waiting_dir_move(struct s + return -ENOMEM; + dm->ino = ino; + dm->rmdir_ino = 0; ++ dm->rmdir_gen = 0; + dm->orphanized = orphanized; + + while (*p) { +@@ -3183,7 +3193,7 @@ static int path_loop(struct send_ctx *sc + while (ino != BTRFS_FIRST_FREE_OBJECTID) { + fs_path_reset(name); + +- if (is_waiting_for_rm(sctx, ino)) ++ if (is_waiting_for_rm(sctx, ino, gen)) + break; + if (is_waiting_for_move(sctx, ino)) { + if (*ancestor_ino == 0) +@@ -3223,6 +3233,7 @@ static int apply_dir_move(struct send_ct + u64 parent_ino, parent_gen; + struct waiting_dir_move *dm = NULL; + u64 rmdir_ino = 0; ++ u64 rmdir_gen; + u64 ancestor; + bool is_orphan; + int ret; +@@ -3237,6 +3248,7 @@ static int apply_dir_move(struct send_ct + dm = get_waiting_dir_move(sctx, pm->ino); + ASSERT(dm); + rmdir_ino = dm->rmdir_ino; ++ rmdir_gen = dm->rmdir_gen; + is_orphan = dm->orphanized; + free_waiting_dir_move(sctx, dm); + +@@ -3273,6 +3285,7 @@ static int apply_dir_move(struct send_ct + dm = get_waiting_dir_move(sctx, pm->ino); + ASSERT(dm); + dm->rmdir_ino = rmdir_ino; ++ dm->rmdir_gen = rmdir_gen; + } + goto out; + } +@@ -3291,7 +3304,7 @@ static int apply_dir_move(struct send_ct + struct orphan_dir_info *odi; + u64 gen; + +- odi = get_orphan_dir_info(sctx, rmdir_ino); ++ odi = get_orphan_dir_info(sctx, rmdir_ino, rmdir_gen); + if (!odi) { + /* already deleted */ + goto finish; diff --git a/queue-5.10/dmabuf-fix-use-after-free-of-dmabuf-s-file-f_inode.patch b/queue-5.10/dmabuf-fix-use-after-free-of-dmabuf-s-file-f_inode.patch new file mode 100644 index 00000000000..d9d04224cc8 --- /dev/null +++ b/queue-5.10/dmabuf-fix-use-after-free-of-dmabuf-s-file-f_inode.patch @@ -0,0 +1,108 @@ +From 05cd84691eafcd7959a1e120d5e72c0dd98c5d91 Mon Sep 17 00:00:00 2001 +From: Charan Teja Reddy +Date: Tue, 5 Jan 2021 20:06:39 +0530 +Subject: dmabuf: fix use-after-free of dmabuf's file->f_inode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Charan Teja Reddy + +commit 05cd84691eafcd7959a1e120d5e72c0dd98c5d91 upstream. + +It is observed 'use-after-free' on the dmabuf's file->f_inode with the +race between closing the dmabuf file and reading the dmabuf's debug +info. + +Consider the below scenario where P1 is closing the dma_buf file +and P2 is reading the dma_buf's debug info in the system: + +P1 P2 + dma_buf_debug_show() +dma_buf_put() + __fput() + file->f_op->release() + dput() + .... + dentry_unlink_inode() + iput(dentry->d_inode) + (where the inode is freed) + mutex_lock(&db_list.lock) + read 'dma_buf->file->f_inode' + (the same inode is freed by P1) + mutex_unlock(&db_list.lock) + dentry->d_op->d_release()--> + dma_buf_release() + ..... + mutex_lock(&db_list.lock) + removes the dmabuf from the list + mutex_unlock(&db_list.lock) + +In the above scenario, when dma_buf_put() is called on a dma_buf, it +first frees the dma_buf's file->f_inode(=dentry->d_inode) and then +removes this dma_buf from the system db_list. In between P2 traversing +the db_list tries to access this dma_buf's file->f_inode that was freed +by P1 which is a use-after-free case. + +Since, __fput() calls f_op->release first and then later calls the +d_op->d_release, move the dma_buf's db_list removal from d_release() to +f_op->release(). This ensures that dma_buf's file->f_inode is not +accessed after it is released. + +Cc: # 5.4.x- +Fixes: 4ab59c3c638c ("dma-buf: Move dma_buf_release() from fops to dentry_ops") +Acked-by: Christian König +Signed-off-by: Charan Teja Reddy +Signed-off-by: Sumit Semwal +Signed-off-by: Thomas Zimmermann +Link: https://patchwork.freedesktop.org/patch/msgid/1609857399-31549-1-git-send-email-charante@codeaurora.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma-buf/dma-buf.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -76,10 +76,6 @@ static void dma_buf_release(struct dentr + + dmabuf->ops->release(dmabuf); + +- mutex_lock(&db_list.lock); +- list_del(&dmabuf->list_node); +- mutex_unlock(&db_list.lock); +- + if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) + dma_resv_fini(dmabuf->resv); + +@@ -88,6 +84,22 @@ static void dma_buf_release(struct dentr + kfree(dmabuf); + } + ++static int dma_buf_file_release(struct inode *inode, struct file *file) ++{ ++ struct dma_buf *dmabuf; ++ ++ if (!is_dma_buf_file(file)) ++ return -EINVAL; ++ ++ dmabuf = file->private_data; ++ ++ mutex_lock(&db_list.lock); ++ list_del(&dmabuf->list_node); ++ mutex_unlock(&db_list.lock); ++ ++ return 0; ++} ++ + static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = dmabuffs_dname, + .d_release = dma_buf_release, +@@ -413,6 +425,7 @@ static void dma_buf_show_fdinfo(struct s + } + + static const struct file_operations dma_buf_fops = { ++ .release = dma_buf_file_release, + .mmap = dma_buf_mmap_internal, + .llseek = dma_buf_llseek, + .poll = dma_buf_poll, diff --git a/queue-5.10/drm-i915-clear-the-gpu-reloc-batch.patch b/queue-5.10/drm-i915-clear-the-gpu-reloc-batch.patch new file mode 100644 index 00000000000..fd2a9a7ac20 --- /dev/null +++ b/queue-5.10/drm-i915-clear-the-gpu-reloc-batch.patch @@ -0,0 +1,46 @@ +From 641382e9b44fba81a0778e1914ee35b8471121f9 Mon Sep 17 00:00:00 2001 +From: Matthew Auld +Date: Thu, 24 Dec 2020 15:13:58 +0000 +Subject: drm/i915: clear the gpu reloc batch + +From: Matthew Auld + +commit 641382e9b44fba81a0778e1914ee35b8471121f9 upstream. + +The reloc batch is short lived but can exist in the user visible ppGTT, +and since it's backed by an internal object, which lacks page clearing, +we should take care to clear it upfront. + +Signed-off-by: Matthew Auld +Reviewed-by: Chris Wilson +Signed-off-by: Chris Wilson +Link: https://patchwork.freedesktop.org/patch/msgid/20201224151358.401345-2-matthew.auld@intel.com +Cc: stable@vger.kernel.org +(cherry picked from commit 26ebc511e799f621357982ccc37a7987a56a00f4) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +@@ -1046,7 +1046,7 @@ static void reloc_gpu_flush(struct i915_ + GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); + cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; + +- __i915_gem_object_flush_map(obj, 0, sizeof(u32) * (cache->rq_size + 1)); ++ i915_gem_object_flush_map(obj); + i915_gem_object_unpin_map(obj); + + intel_gt_chipset_flush(cache->rq->engine->gt); +@@ -1296,6 +1296,8 @@ static int __reloc_gpu_alloc(struct i915 + goto err_pool; + } + ++ memset32(cmd, 0, pool->obj->base.size / sizeof(u32)); ++ + batch = i915_vma_instance(pool->obj, vma->vm, NULL); + if (IS_ERR(batch)) { + err = PTR_ERR(batch); diff --git a/queue-5.10/drm-i915-clear-the-shadow-batch.patch b/queue-5.10/drm-i915-clear-the-shadow-batch.patch new file mode 100644 index 00000000000..a8c3239d638 --- /dev/null +++ b/queue-5.10/drm-i915-clear-the-shadow-batch.patch @@ -0,0 +1,105 @@ +From 75353bcd2184010f08a3ed2f0da019bd9d604e1e Mon Sep 17 00:00:00 2001 +From: Matthew Auld +Date: Thu, 24 Dec 2020 15:13:57 +0000 +Subject: drm/i915: clear the shadow batch + +From: Matthew Auld + +commit 75353bcd2184010f08a3ed2f0da019bd9d604e1e upstream. + +The shadow batch is an internal object, which doesn't have any page +clearing, and since the batch_len can be smaller than the object, we +should take care to clear it. + +Testcase: igt/gen9_exec_parse/shadow-peek +Fixes: 4f7af1948abc ("drm/i915: Support ro ppgtt mapped cmdparser shadow buffers") +Signed-off-by: Matthew Auld +Reviewed-by: Chris Wilson +Signed-off-by: Chris Wilson +Link: https://patchwork.freedesktop.org/patch/msgid/20201224151358.401345-1-matthew.auld@intel.com +Cc: stable@vger.kernel.org +(cherry picked from commit eeb52ee6c4a429ec301faf1dc48988744960786e) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_cmd_parser.c | 27 +++++++++------------------ + 1 file changed, 9 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_cmd_parser.c ++++ b/drivers/gpu/drm/i915/i915_cmd_parser.c +@@ -1166,7 +1166,7 @@ static u32 *copy_batch(struct drm_i915_g + } + } + if (IS_ERR(src)) { +- unsigned long x, n; ++ unsigned long x, n, remain; + void *ptr; + + /* +@@ -1177,14 +1177,15 @@ static u32 *copy_batch(struct drm_i915_g + * We don't care about copying too much here as we only + * validate up to the end of the batch. + */ ++ remain = length; + if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) +- length = round_up(length, ++ remain = round_up(remain, + boot_cpu_data.x86_clflush_size); + + ptr = dst; + x = offset_in_page(offset); +- for (n = offset >> PAGE_SHIFT; length; n++) { +- int len = min(length, PAGE_SIZE - x); ++ for (n = offset >> PAGE_SHIFT; remain; n++) { ++ int len = min(remain, PAGE_SIZE - x); + + src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); + if (needs_clflush) +@@ -1193,13 +1194,15 @@ static u32 *copy_batch(struct drm_i915_g + kunmap_atomic(src); + + ptr += len; +- length -= len; ++ remain -= len; + x = 0; + } + } + + i915_gem_object_unpin_pages(src_obj); + ++ memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); ++ + /* dst_obj is returned with vmap pinned */ + return dst; + } +@@ -1392,11 +1395,6 @@ static unsigned long *alloc_whitelist(u3 + + #define LENGTH_BIAS 2 + +-static bool shadow_needs_clflush(struct drm_i915_gem_object *obj) +-{ +- return !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE); +-} +- + /** + * intel_engine_cmd_parser() - parse a batch buffer for privilege violations + * @engine: the engine on which the batch is to execute +@@ -1539,16 +1537,9 @@ int intel_engine_cmd_parser(struct intel + ret = 0; /* allow execution */ + } + } +- +- if (shadow_needs_clflush(shadow->obj)) +- drm_clflush_virt_range(batch_end, 8); + } + +- if (shadow_needs_clflush(shadow->obj)) { +- void *ptr = page_mask_bits(shadow->obj->mm.mapping); +- +- drm_clflush_virt_range(ptr, (void *)(cmd + 1) - ptr); +- } ++ i915_gem_object_flush_map(shadow->obj); + + if (!IS_ERR_OR_NULL(jump_whitelist)) + kfree(jump_whitelist); diff --git a/queue-5.10/hwmon-amd_energy-fix-allocation-of-hwmon_channel_info-config.patch b/queue-5.10/hwmon-amd_energy-fix-allocation-of-hwmon_channel_info-config.patch new file mode 100644 index 00000000000..e9eea8e407b --- /dev/null +++ b/queue-5.10/hwmon-amd_energy-fix-allocation-of-hwmon_channel_info-config.patch @@ -0,0 +1,52 @@ +From 84e261553e6f919bf0b4d65244599ab2b41f1da5 Mon Sep 17 00:00:00 2001 +From: David Arcari +Date: Thu, 7 Jan 2021 09:47:07 -0500 +Subject: hwmon: (amd_energy) fix allocation of hwmon_channel_info config + +From: David Arcari + +commit 84e261553e6f919bf0b4d65244599ab2b41f1da5 upstream. + +hwmon, specifically hwmon_num_channel_attrs, expects the config +array in the hwmon_channel_info structure to be terminated by +a zero entry. amd_energy does not honor this convention. As +result, a KASAN warning is possible. Fix this by adding an +additional entry and setting it to zero. + +Fixes: 8abee9566b7e ("hwmon: Add amd_energy driver to report energy counters") + +Signed-off-by: David Arcari +Cc: Naveen Krishna Chatradhi +Cc: Jean Delvare +Cc: Guenter Roeck +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: David Arcari +Acked-by: Naveen Krishna Chatradhi +Link: https://lore.kernel.org/r/20210107144707.6927-1-darcari@redhat.com +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/amd_energy.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/hwmon/amd_energy.c ++++ b/drivers/hwmon/amd_energy.c +@@ -222,7 +222,7 @@ static int amd_create_sensor(struct devi + */ + cpus = num_present_cpus() / num_siblings; + +- s_config = devm_kcalloc(dev, cpus + sockets, ++ s_config = devm_kcalloc(dev, cpus + sockets + 1, + sizeof(u32), GFP_KERNEL); + if (!s_config) + return -ENOMEM; +@@ -254,6 +254,7 @@ static int amd_create_sensor(struct devi + scnprintf(label_l[i], 10, "Esocket%u", (i - cpus)); + } + ++ s_config[i] = 0; + return 0; + } + diff --git a/queue-5.10/iommu-vt-d-move-intel_iommu-info-from-struct-intel_svm-to-struct-intel_svm_dev.patch b/queue-5.10/iommu-vt-d-move-intel_iommu-info-from-struct-intel_svm-to-struct-intel_svm_dev.patch new file mode 100644 index 00000000000..44c861e5a6b --- /dev/null +++ b/queue-5.10/iommu-vt-d-move-intel_iommu-info-from-struct-intel_svm-to-struct-intel_svm_dev.patch @@ -0,0 +1,111 @@ +From 9ad9f45b3b91162b33abfe175ae75ab65718dbf5 Mon Sep 17 00:00:00 2001 +From: Liu Yi L +Date: Thu, 7 Jan 2021 00:03:55 +0800 +Subject: iommu/vt-d: Move intel_iommu info from struct intel_svm to struct intel_svm_dev + +From: Liu Yi L + +commit 9ad9f45b3b91162b33abfe175ae75ab65718dbf5 upstream. + +'struct intel_svm' is shared by all devices bound to a give process, +but records only a single pointer to a 'struct intel_iommu'. Consequently, +cache invalidations may only be applied to a single DMAR unit, and are +erroneously skipped for the other devices. + +In preparation for fixing this, rework the structures so that the iommu +pointer resides in 'struct intel_svm_dev', allowing 'struct intel_svm' +to track them in its device list. + +Fixes: 1c4f88b7f1f9 ("iommu/vt-d: Shared virtual address in scalable mode") +Cc: Lu Baolu +Cc: Jacob Pan +Cc: Raj Ashok +Cc: David Woodhouse +Reported-by: Guo Kaijie +Reported-by: Xin Zeng +Signed-off-by: Guo Kaijie +Signed-off-by: Xin Zeng +Signed-off-by: Liu Yi L +Tested-by: Guo Kaijie +Cc: stable@vger.kernel.org # v5.0+ +Acked-by: Lu Baolu +Link: https://lore.kernel.org/r/1609949037-25291-2-git-send-email-yi.l.liu@intel.com +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/intel/svm.c | 9 +++++---- + include/linux/intel-iommu.h | 2 +- + 2 files changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/iommu/intel/svm.c ++++ b/drivers/iommu/intel/svm.c +@@ -142,7 +142,7 @@ static void intel_flush_svm_range_dev (s + } + desc.qw2 = 0; + desc.qw3 = 0; +- qi_submit_sync(svm->iommu, &desc, 1, 0); ++ qi_submit_sync(sdev->iommu, &desc, 1, 0); + + if (sdev->dev_iotlb) { + desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) | +@@ -166,7 +166,7 @@ static void intel_flush_svm_range_dev (s + } + desc.qw2 = 0; + desc.qw3 = 0; +- qi_submit_sync(svm->iommu, &desc, 1, 0); ++ qi_submit_sync(sdev->iommu, &desc, 1, 0); + } + } + +@@ -211,7 +211,7 @@ static void intel_mm_release(struct mmu_ + */ + rcu_read_lock(); + list_for_each_entry_rcu(sdev, &svm->devs, list) +- intel_pasid_tear_down_entry(svm->iommu, sdev->dev, ++ intel_pasid_tear_down_entry(sdev->iommu, sdev->dev, + svm->pasid, true); + rcu_read_unlock(); + +@@ -363,6 +363,7 @@ int intel_svm_bind_gpasid(struct iommu_d + } + sdev->dev = dev; + sdev->sid = PCI_DEVID(info->bus, info->devfn); ++ sdev->iommu = iommu; + + /* Only count users if device has aux domains */ + if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)) +@@ -546,6 +547,7 @@ intel_svm_bind_mm(struct device *dev, un + goto out; + } + sdev->dev = dev; ++ sdev->iommu = iommu; + + ret = intel_iommu_enable_pasid(iommu, dev); + if (ret) { +@@ -575,7 +577,6 @@ intel_svm_bind_mm(struct device *dev, un + kfree(sdev); + goto out; + } +- svm->iommu = iommu; + + if (pasid_max > intel_pasid_max_id) + pasid_max = intel_pasid_max_id; +--- a/include/linux/intel-iommu.h ++++ b/include/linux/intel-iommu.h +@@ -758,6 +758,7 @@ struct intel_svm_dev { + struct list_head list; + struct rcu_head rcu; + struct device *dev; ++ struct intel_iommu *iommu; + struct svm_dev_ops *ops; + struct iommu_sva sva; + u32 pasid; +@@ -771,7 +772,6 @@ struct intel_svm { + struct mmu_notifier notifier; + struct mm_struct *mm; + +- struct intel_iommu *iommu; + unsigned int flags; + u32 pasid; + int gpasid; /* In case that guest PASID is different from host PASID */ diff --git a/queue-5.10/kvm-check-tlbs_dirty-directly.patch b/queue-5.10/kvm-check-tlbs_dirty-directly.patch new file mode 100644 index 00000000000..97119301170 --- /dev/null +++ b/queue-5.10/kvm-check-tlbs_dirty-directly.patch @@ -0,0 +1,46 @@ +From 88bf56d04bc3564542049ec4ec168a8b60d0b48c Mon Sep 17 00:00:00 2001 +From: Lai Jiangshan +Date: Thu, 17 Dec 2020 23:41:18 +0800 +Subject: kvm: check tlbs_dirty directly + +From: Lai Jiangshan + +commit 88bf56d04bc3564542049ec4ec168a8b60d0b48c upstream. + +In kvm_mmu_notifier_invalidate_range_start(), tlbs_dirty is used as: + need_tlb_flush |= kvm->tlbs_dirty; +with need_tlb_flush's type being int and tlbs_dirty's type being long. + +It means that tlbs_dirty is always used as int and the higher 32 bits +is useless. We need to check tlbs_dirty in a correct way and this +change checks it directly without propagating it to need_tlb_flush. + +Note: it's _extremely_ unlikely this neglecting of higher 32 bits can +cause problems in practice. It would require encountering tlbs_dirty +on a 4 billion count boundary, and KVM would need to be using shadow +paging or be running a nested guest. + +Cc: stable@vger.kernel.org +Fixes: a4ee1ca4a36e ("KVM: MMU: delay flush all tlbs on sync_page path") +Signed-off-by: Lai Jiangshan +Message-Id: <20201217154118.16497-1-jiangshanlai@gmail.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + virt/kvm/kvm_main.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -482,9 +482,8 @@ static int kvm_mmu_notifier_invalidate_r + kvm->mmu_notifier_count++; + need_tlb_flush = kvm_unmap_hva_range(kvm, range->start, range->end, + range->flags); +- need_tlb_flush |= kvm->tlbs_dirty; + /* we've to flush the tlb before the pages can be freed */ +- if (need_tlb_flush) ++ if (need_tlb_flush || kvm->tlbs_dirty) + kvm_flush_remote_tlbs(kvm); + + spin_unlock(&kvm->mmu_lock); diff --git a/queue-5.10/kvm-x86-mmu-ensure-tdp-mmu-roots-are-freed-after-yield.patch b/queue-5.10/kvm-x86-mmu-ensure-tdp-mmu-roots-are-freed-after-yield.patch new file mode 100644 index 00000000000..f419fa0f3f9 --- /dev/null +++ b/queue-5.10/kvm-x86-mmu-ensure-tdp-mmu-roots-are-freed-after-yield.patch @@ -0,0 +1,230 @@ +From a889ea54b3daa63ee1463dc19ed699407d61458b Mon Sep 17 00:00:00 2001 +From: Ben Gardon +Date: Wed, 6 Jan 2021 16:19:34 -0800 +Subject: KVM: x86/mmu: Ensure TDP MMU roots are freed after yield + +From: Ben Gardon + +commit a889ea54b3daa63ee1463dc19ed699407d61458b upstream. + +Many TDP MMU functions which need to perform some action on all TDP MMU +roots hold a reference on that root so that they can safely drop the MMU +lock in order to yield to other threads. However, when releasing the +reference on the root, there is a bug: the root will not be freed even +if its reference count (root_count) is reduced to 0. + +To simplify acquiring and releasing references on TDP MMU root pages, and +to ensure that these roots are properly freed, move the get/put operations +into another TDP MMU root iterator macro. + +Moving the get/put operations into an iterator macro also helps +simplify control flow when a root does need to be freed. Note that using +the list_for_each_entry_safe macro would not have been appropriate in +this situation because it could keep a pointer to the next root across +an MMU lock release + reacquire, during which time that root could be +freed. + +Reported-by: Maciej S. Szmigiero +Suggested-by: Paolo Bonzini +Fixes: faaf05b00aec ("kvm: x86/mmu: Support zapping SPTEs in the TDP MMU") +Fixes: 063afacd8730 ("kvm: x86/mmu: Support invalidate range MMU notifier for TDP MMU") +Fixes: a6a0b05da9f3 ("kvm: x86/mmu: Support dirty logging for the TDP MMU") +Fixes: 14881998566d ("kvm: x86/mmu: Support disabling dirty logging for the tdp MMU") +Signed-off-by: Ben Gardon +Message-Id: <20210107001935.3732070-1-bgardon@google.com> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/mmu/tdp_mmu.c | 104 ++++++++++++++++++++------------------------- + 1 file changed, 48 insertions(+), 56 deletions(-) + +--- a/arch/x86/kvm/mmu/tdp_mmu.c ++++ b/arch/x86/kvm/mmu/tdp_mmu.c +@@ -42,7 +42,48 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm * + WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); + } + +-#define for_each_tdp_mmu_root(_kvm, _root) \ ++static void tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root) ++{ ++ if (kvm_mmu_put_root(kvm, root)) ++ kvm_tdp_mmu_free_root(kvm, root); ++} ++ ++static inline bool tdp_mmu_next_root_valid(struct kvm *kvm, ++ struct kvm_mmu_page *root) ++{ ++ lockdep_assert_held(&kvm->mmu_lock); ++ ++ if (list_entry_is_head(root, &kvm->arch.tdp_mmu_roots, link)) ++ return false; ++ ++ kvm_mmu_get_root(kvm, root); ++ return true; ++ ++} ++ ++static inline struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, ++ struct kvm_mmu_page *root) ++{ ++ struct kvm_mmu_page *next_root; ++ ++ next_root = list_next_entry(root, link); ++ tdp_mmu_put_root(kvm, root); ++ return next_root; ++} ++ ++/* ++ * Note: this iterator gets and puts references to the roots it iterates over. ++ * This makes it safe to release the MMU lock and yield within the loop, but ++ * if exiting the loop early, the caller must drop the reference to the most ++ * recent root. (Unless keeping a live reference is desirable.) ++ */ ++#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ ++ for (_root = list_first_entry(&_kvm->arch.tdp_mmu_roots, \ ++ typeof(*_root), link); \ ++ tdp_mmu_next_root_valid(_kvm, _root); \ ++ _root = tdp_mmu_next_root(_kvm, _root)) ++ ++#define for_each_tdp_mmu_root(_kvm, _root) \ + list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) + + bool is_tdp_mmu_root(struct kvm *kvm, hpa_t hpa) +@@ -439,18 +480,9 @@ bool kvm_tdp_mmu_zap_gfn_range(struct kv + struct kvm_mmu_page *root; + bool flush = false; + +- for_each_tdp_mmu_root(kvm, root) { +- /* +- * Take a reference on the root so that it cannot be freed if +- * this thread releases the MMU lock and yields in this loop. +- */ +- kvm_mmu_get_root(kvm, root); +- ++ for_each_tdp_mmu_root_yield_safe(kvm, root) + flush |= zap_gfn_range(kvm, root, start, end, true); + +- kvm_mmu_put_root(kvm, root); +- } +- + return flush; + } + +@@ -609,13 +641,7 @@ static int kvm_tdp_mmu_handle_hva_range( + int ret = 0; + int as_id; + +- for_each_tdp_mmu_root(kvm, root) { +- /* +- * Take a reference on the root so that it cannot be freed if +- * this thread releases the MMU lock and yields in this loop. +- */ +- kvm_mmu_get_root(kvm, root); +- ++ for_each_tdp_mmu_root_yield_safe(kvm, root) { + as_id = kvm_mmu_page_as_id(root); + slots = __kvm_memslots(kvm, as_id); + kvm_for_each_memslot(memslot, slots) { +@@ -637,8 +663,6 @@ static int kvm_tdp_mmu_handle_hva_range( + ret |= handler(kvm, memslot, root, gfn_start, + gfn_end, data); + } +- +- kvm_mmu_put_root(kvm, root); + } + + return ret; +@@ -826,21 +850,13 @@ bool kvm_tdp_mmu_wrprot_slot(struct kvm + int root_as_id; + bool spte_set = false; + +- for_each_tdp_mmu_root(kvm, root) { ++ for_each_tdp_mmu_root_yield_safe(kvm, root) { + root_as_id = kvm_mmu_page_as_id(root); + if (root_as_id != slot->as_id) + continue; + +- /* +- * Take a reference on the root so that it cannot be freed if +- * this thread releases the MMU lock and yields in this loop. +- */ +- kvm_mmu_get_root(kvm, root); +- + spte_set |= wrprot_gfn_range(kvm, root, slot->base_gfn, + slot->base_gfn + slot->npages, min_level); +- +- kvm_mmu_put_root(kvm, root); + } + + return spte_set; +@@ -894,21 +910,13 @@ bool kvm_tdp_mmu_clear_dirty_slot(struct + int root_as_id; + bool spte_set = false; + +- for_each_tdp_mmu_root(kvm, root) { ++ for_each_tdp_mmu_root_yield_safe(kvm, root) { + root_as_id = kvm_mmu_page_as_id(root); + if (root_as_id != slot->as_id) + continue; + +- /* +- * Take a reference on the root so that it cannot be freed if +- * this thread releases the MMU lock and yields in this loop. +- */ +- kvm_mmu_get_root(kvm, root); +- + spte_set |= clear_dirty_gfn_range(kvm, root, slot->base_gfn, + slot->base_gfn + slot->npages); +- +- kvm_mmu_put_root(kvm, root); + } + + return spte_set; +@@ -1017,21 +1025,13 @@ bool kvm_tdp_mmu_slot_set_dirty(struct k + int root_as_id; + bool spte_set = false; + +- for_each_tdp_mmu_root(kvm, root) { ++ for_each_tdp_mmu_root_yield_safe(kvm, root) { + root_as_id = kvm_mmu_page_as_id(root); + if (root_as_id != slot->as_id) + continue; + +- /* +- * Take a reference on the root so that it cannot be freed if +- * this thread releases the MMU lock and yields in this loop. +- */ +- kvm_mmu_get_root(kvm, root); +- + spte_set |= set_dirty_gfn_range(kvm, root, slot->base_gfn, + slot->base_gfn + slot->npages); +- +- kvm_mmu_put_root(kvm, root); + } + return spte_set; + } +@@ -1077,21 +1077,13 @@ void kvm_tdp_mmu_zap_collapsible_sptes(s + struct kvm_mmu_page *root; + int root_as_id; + +- for_each_tdp_mmu_root(kvm, root) { ++ for_each_tdp_mmu_root_yield_safe(kvm, root) { + root_as_id = kvm_mmu_page_as_id(root); + if (root_as_id != slot->as_id) + continue; + +- /* +- * Take a reference on the root so that it cannot be freed if +- * this thread releases the MMU lock and yields in this loop. +- */ +- kvm_mmu_get_root(kvm, root); +- + zap_collapsible_spte_range(kvm, root, slot->base_gfn, + slot->base_gfn + slot->npages); +- +- kvm_mmu_put_root(kvm, root); + } + } + diff --git a/queue-5.10/kvm-x86-mmu-get-root-level-from-walkers-when-retrieving-mmio-spte.patch b/queue-5.10/kvm-x86-mmu-get-root-level-from-walkers-when-retrieving-mmio-spte.patch new file mode 100644 index 00000000000..7b340c6bc3d --- /dev/null +++ b/queue-5.10/kvm-x86-mmu-get-root-level-from-walkers-when-retrieving-mmio-spte.patch @@ -0,0 +1,120 @@ +From 39b4d43e6003cee51cd119596d3c33d0449eb44c Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Thu, 17 Dec 2020 16:31:37 -0800 +Subject: KVM: x86/mmu: Get root level from walkers when retrieving MMIO SPTE + +From: Sean Christopherson + +commit 39b4d43e6003cee51cd119596d3c33d0449eb44c upstream. + +Get the so called "root" level from the low level shadow page table +walkers instead of manually attempting to calculate it higher up the +stack, e.g. in get_mmio_spte(). When KVM is using PAE shadow paging, +the starting level of the walk, from the callers perspective, is not +the CR3 root but rather the PDPTR "root". Checking for reserved bits +from the CR3 root causes get_mmio_spte() to consume uninitialized stack +data due to indexing into sptes[] for a level that was not filled by +get_walk(). This can result in false positives and/or negatives +depending on what garbage happens to be on the stack. + +Opportunistically nuke a few extra newlines. + +Fixes: 95fb5b0258b7 ("kvm: x86/mmu: Support MMIO in the TDP MMU") +Reported-by: Richard Herbert +Cc: Ben Gardon +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Message-Id: <20201218003139.2167891-3-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/mmu/mmu.c | 15 ++++++--------- + arch/x86/kvm/mmu/tdp_mmu.c | 5 ++++- + arch/x86/kvm/mmu/tdp_mmu.h | 4 +++- + 3 files changed, 13 insertions(+), 11 deletions(-) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -3485,16 +3485,16 @@ static bool mmio_info_in_cache(struct kv + * Return the level of the lowest level SPTE added to sptes. + * That SPTE may be non-present. + */ +-static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) ++static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level) + { + struct kvm_shadow_walk_iterator iterator; + int leaf = -1; + u64 spte; + +- + walk_shadow_page_lockless_begin(vcpu); + +- for (shadow_walk_init(&iterator, vcpu, addr); ++ for (shadow_walk_init(&iterator, vcpu, addr), ++ *root_level = iterator.level; + shadow_walk_okay(&iterator); + __shadow_walk_next(&iterator, spte)) { + leaf = iterator.level; +@@ -3504,7 +3504,6 @@ static int get_walk(struct kvm_vcpu *vcp + + if (!is_shadow_present_pte(spte)) + break; +- + } + + walk_shadow_page_lockless_end(vcpu); +@@ -3517,9 +3516,7 @@ static bool get_mmio_spte(struct kvm_vcp + { + u64 sptes[PT64_ROOT_MAX_LEVEL]; + struct rsvd_bits_validate *rsvd_check; +- int root = vcpu->arch.mmu->shadow_root_level; +- int leaf; +- int level; ++ int root, leaf, level; + bool reserved = false; + + if (!VALID_PAGE(vcpu->arch.mmu->root_hpa)) { +@@ -3528,9 +3525,9 @@ static bool get_mmio_spte(struct kvm_vcp + } + + if (is_tdp_mmu_root(vcpu->kvm, vcpu->arch.mmu->root_hpa)) +- leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes); ++ leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, &root); + else +- leaf = get_walk(vcpu, addr, sptes); ++ leaf = get_walk(vcpu, addr, sptes, &root); + + if (unlikely(leaf < 0)) { + *sptep = 0ull; +--- a/arch/x86/kvm/mmu/tdp_mmu.c ++++ b/arch/x86/kvm/mmu/tdp_mmu.c +@@ -1148,13 +1148,16 @@ bool kvm_tdp_mmu_write_protect_gfn(struc + * Return the level of the lowest level SPTE added to sptes. + * That SPTE may be non-present. + */ +-int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) ++int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, ++ int *root_level) + { + struct tdp_iter iter; + struct kvm_mmu *mmu = vcpu->arch.mmu; + gfn_t gfn = addr >> PAGE_SHIFT; + int leaf = -1; + ++ *root_level = vcpu->arch.mmu->shadow_root_level; ++ + tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { + leaf = iter.level; + sptes[leaf - 1] = iter.old_spte; +--- a/arch/x86/kvm/mmu/tdp_mmu.h ++++ b/arch/x86/kvm/mmu/tdp_mmu.h +@@ -44,5 +44,7 @@ void kvm_tdp_mmu_zap_collapsible_sptes(s + bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, + struct kvm_memory_slot *slot, gfn_t gfn); + +-int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes); ++int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, ++ int *root_level); ++ + #endif /* __KVM_X86_MMU_TDP_MMU_H */ diff --git a/queue-5.10/kvm-x86-mmu-use-1-to-flag-an-undefined-spte-in-get_mmio_spte.patch b/queue-5.10/kvm-x86-mmu-use-1-to-flag-an-undefined-spte-in-get_mmio_spte.patch new file mode 100644 index 00000000000..54a111d92ae --- /dev/null +++ b/queue-5.10/kvm-x86-mmu-use-1-to-flag-an-undefined-spte-in-get_mmio_spte.patch @@ -0,0 +1,67 @@ +From 2aa078932ff6c66bf10cc5b3144440dbfa7d813d Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Thu, 17 Dec 2020 16:31:36 -0800 +Subject: KVM: x86/mmu: Use -1 to flag an undefined spte in get_mmio_spte() + +From: Sean Christopherson + +commit 2aa078932ff6c66bf10cc5b3144440dbfa7d813d upstream. + +Return -1 from the get_walk() helpers if the shadow walk doesn't fill at +least one spte, which can theoretically happen if the walk hits a +not-present PDPTR. Returning the root level in such a case will cause +get_mmio_spte() to return garbage (uninitialized stack data). In +practice, such a scenario should be impossible as KVM shouldn't get a +reserved-bit page fault with a not-present PDPTR. + +Note, using mmu->root_level in get_walk() is wrong for other reasons, +too, but that's now a moot point. + +Fixes: 95fb5b0258b7 ("kvm: x86/mmu: Support MMIO in the TDP MMU") +Cc: Ben Gardon +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Message-Id: <20201218003139.2167891-2-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/mmu/mmu.c | 7 ++++++- + arch/x86/kvm/mmu/tdp_mmu.c | 2 +- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -3488,7 +3488,7 @@ static bool mmio_info_in_cache(struct kv + static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes) + { + struct kvm_shadow_walk_iterator iterator; +- int leaf = vcpu->arch.mmu->root_level; ++ int leaf = -1; + u64 spte; + + +@@ -3532,6 +3532,11 @@ static bool get_mmio_spte(struct kvm_vcp + else + leaf = get_walk(vcpu, addr, sptes); + ++ if (unlikely(leaf < 0)) { ++ *sptep = 0ull; ++ return reserved; ++ } ++ + rsvd_check = &vcpu->arch.mmu->shadow_zero_check; + + for (level = root; level >= leaf; level--) { +--- a/arch/x86/kvm/mmu/tdp_mmu.c ++++ b/arch/x86/kvm/mmu/tdp_mmu.c +@@ -1152,8 +1152,8 @@ int kvm_tdp_mmu_get_walk(struct kvm_vcpu + { + struct tdp_iter iter; + struct kvm_mmu *mmu = vcpu->arch.mmu; +- int leaf = vcpu->arch.mmu->shadow_root_level; + gfn_t gfn = addr >> PAGE_SHIFT; ++ int leaf = -1; + + tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { + leaf = iter.level; diff --git a/queue-5.10/mm-make-wait_on_page_writeback-wait-for-multiple-pending-writebacks.patch b/queue-5.10/mm-make-wait_on_page_writeback-wait-for-multiple-pending-writebacks.patch new file mode 100644 index 00000000000..10b73875cd2 --- /dev/null +++ b/queue-5.10/mm-make-wait_on_page_writeback-wait-for-multiple-pending-writebacks.patch @@ -0,0 +1,103 @@ +From c2407cf7d22d0c0d94cf20342b3b8f06f1d904e7 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Tue, 5 Jan 2021 11:33:00 -0800 +Subject: mm: make wait_on_page_writeback() wait for multiple pending writebacks + +From: Linus Torvalds + +commit c2407cf7d22d0c0d94cf20342b3b8f06f1d904e7 upstream. + +Ever since commit 2a9127fcf229 ("mm: rewrite wait_on_page_bit_common() +logic") we've had some very occasional reports of BUG_ON(PageWriteback) +in write_cache_pages(), which we thought we already fixed in commit +073861ed77b6 ("mm: fix VM_BUG_ON(PageTail) and BUG_ON(PageWriteback)"). + +But syzbot just reported another one, even with that commit in place. + +And it turns out that there's a simpler way to trigger the BUG_ON() than +the one Hugh found with page re-use. It all boils down to the fact that +the page writeback is ostensibly serialized by the page lock, but that +isn't actually really true. + +Yes, the people _setting_ writeback all do so under the page lock, but +the actual clearing of the bit - and waking up any waiters - happens +without any page lock. + +This gives us this fairly simple race condition: + + CPU1 = end previous writeback + CPU2 = start new writeback under page lock + CPU3 = write_cache_pages() + + CPU1 CPU2 CPU3 + ---- ---- ---- + + end_page_writeback() + test_clear_page_writeback(page) + ... delayed... + + lock_page(); + set_page_writeback() + unlock_page() + + lock_page() + wait_on_page_writeback(); + + wake_up_page(page, PG_writeback); + .. wakes up CPU3 .. + + BUG_ON(PageWriteback(page)); + +where the BUG_ON() happens because we woke up the PG_writeback bit +becasue of the _previous_ writeback, but a new one had already been +started because the clearing of the bit wasn't actually atomic wrt the +actual wakeup or serialized by the page lock. + +The reason this didn't use to happen was that the old logic in waiting +on a page bit would just loop if it ever saw the bit set again. + +The nice proper fix would probably be to get rid of the whole "wait for +writeback to clear, and then set it" logic in the writeback path, and +replace it with an atomic "wait-to-set" (ie the same as we have for page +locking: we set the page lock bit with a single "lock_page()", not with +"wait for lock bit to clear and then set it"). + +However, out current model for writeback is that the waiting for the +writeback bit is done by the generic VFS code (ie write_cache_pages()), +but the actual setting of the writeback bit is done much later by the +filesystem ".writepages()" function. + +IOW, to make the writeback bit have that same kind of "wait-to-set" +behavior as we have for page locking, we'd have to change our roughly +~50 different writeback functions. Painful. + +Instead, just make "wait_on_page_writeback()" loop on the very unlikely +situation that the PG_writeback bit is still set, basically re-instating +the old behavior. This is very non-optimal in case of contention, but +since we only ever set the bit under the page lock, that situation is +controlled. + +Reported-by: syzbot+2fc0712f8f8b8b8fa0ef@syzkaller.appspotmail.com +Fixes: 2a9127fcf229 ("mm: rewrite wait_on_page_bit_common() logic") +Acked-by: Hugh Dickins +Cc: Andrew Morton +Cc: Matthew Wilcox +Cc: stable@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/page-writeback.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -2826,7 +2826,7 @@ EXPORT_SYMBOL(__test_set_page_writeback) + */ + void wait_on_page_writeback(struct page *page) + { +- if (PageWriteback(page)) { ++ while (PageWriteback(page)) { + trace_wait_on_page_writeback(page, page_mapping(page)); + wait_on_page_bit(page, PG_writeback); + } diff --git a/queue-5.10/revert-device-property-keep-secondary-firmware-node-secondary-by-type.patch b/queue-5.10/revert-device-property-keep-secondary-firmware-node-secondary-by-type.patch new file mode 100644 index 00000000000..ed54cdda3fa --- /dev/null +++ b/queue-5.10/revert-device-property-keep-secondary-firmware-node-secondary-by-type.patch @@ -0,0 +1,40 @@ +From 47f4469970d8861bc06d2d4d45ac8200ff07c693 Mon Sep 17 00:00:00 2001 +From: Bard Liao +Date: Tue, 5 Jan 2021 17:11:45 +0800 +Subject: Revert "device property: Keep secondary firmware node secondary by type" + +From: Bard Liao + +commit 47f4469970d8861bc06d2d4d45ac8200ff07c693 upstream. + +While commit d5dcce0c414f ("device property: Keep secondary firmware +node secondary by type") describes everything correct in its commit +message, the change it made does the opposite and original commit +c15e1bdda436 ("device property: Fix the secondary firmware node handling +in set_primary_fwnode()") was fully correct. + +Revert the former one here and improve documentation in the next patch. + +Fixes: d5dcce0c414f ("device property: Keep secondary firmware node secondary by type") +Signed-off-by: Bard Liao +Reviewed-by: Andy Shevchenko +Reviewed-by: Heikki Krogerus +Cc: 5.10+ # 5.10+ +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -4278,7 +4278,7 @@ void set_primary_fwnode(struct device *d + if (fwnode_is_primary(fn)) { + dev->fwnode = fn->secondary; + if (!(parent && fn == parent->fwnode)) +- fn->secondary = ERR_PTR(-ENODEV); ++ fn->secondary = NULL; + } else { + dev->fwnode = NULL; + } diff --git a/queue-5.10/series b/queue-5.10/series index 103a2b6a633..1ceef81f533 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -79,3 +79,56 @@ usb-gadget-enable-super-speed-plus.patch usb-cdc-acm-blacklist-another-ir-droid-device.patch usb-cdc-wdm-fix-use-after-free-in-service_outstanding_interrupt.patch usb-typec-intel_pmc_mux-configure-hpd-first-for-hpd-irq-request.patch +usb-dwc3-meson-g12a-disable-clk-on-error-handling-path-in-probe.patch +usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch +usb-dwc3-gadget-clear-wait-flag-on-dequeue.patch +usb-dwc3-ulpi-use-vstsdone-to-detect-phy-regs-access-completion.patch +usb-dwc3-ulpi-replace-cpu-based-busyloop-with-protocol-based-one.patch +usb-dwc3-ulpi-fix-usb2.0-hs-fs-ls-phy-suspend-regression.patch +usb-chipidea-ci_hdrc_imx-add-missing-put_device-call-in-usbmisc_get_init_data.patch +usb-xhci-fix-u1-u2-handling-for-hardware-with-xhci_intel_host-quirk-set.patch +usb-usbip-vhci_hcd-protect-shift-size.patch +usb-uas-add-pny-usb-portable-ssd-to-unusual_uas.patch +usb-serial-iuu_phoenix-fix-dma-from-stack.patch +usb-serial-option-add-longsung-m5710-module-support.patch +usb-serial-option-add-quectel-em160r-gl.patch +usb-yurex-fix-control-urb-timeout-handling.patch +usb-usblp-fix-dma-to-stack.patch +alsa-usb-audio-fix-ubsan-warnings-for-midi-jacks.patch +usb-gadget-select-config_crc32.patch +usb-gadget-dummy-hcd-fix-shift-out-of-bounds-bug.patch +usb-gadget-f_uac2-reset-wmaxpacketsize.patch +usb-gadget-function-printer-fix-a-memory-leak-for-interface-descriptor.patch +usb-gadget-u_ether-fix-mtu-size-mismatch-with-rx-packet-size.patch +usb-gadget-legacy-fix-return-error-code-in-acm_ms_bind.patch +usb-gadget-fix-spinlock-lockup-on-usb_function_deactivate.patch +usb-gadget-configfs-preserve-function-ordering-after-bind-failure.patch +usb-gadget-configfs-fix-use-after-free-issue-with-udc_name.patch +usb-serial-keyspan_pda-remove-unused-variable.patch +hwmon-amd_energy-fix-allocation-of-hwmon_channel_info-config.patch +mm-make-wait_on_page_writeback-wait-for-multiple-pending-writebacks.patch +x86-mm-fix-leak-of-pmd-ptlock.patch +kvm-x86-mmu-use-1-to-flag-an-undefined-spte-in-get_mmio_spte.patch +kvm-x86-mmu-get-root-level-from-walkers-when-retrieving-mmio-spte.patch +kvm-check-tlbs_dirty-directly.patch +kvm-x86-mmu-ensure-tdp-mmu-roots-are-freed-after-yield.patch +x86-resctrl-use-an-ipi-instead-of-task_work_add-to-update-pqr_assoc-msr.patch +x86-resctrl-don-t-move-a-task-to-the-same-resource-group.patch +blk-iocost-fix-null-iocg-deref-from-racing-against-initialization.patch +alsa-hda-via-fix-runtime-pm-for-clevo-w35xss.patch +alsa-hda-conexant-add-a-new-hda-codec-cx11970.patch +alsa-hda-realtek-fix-speaker-volume-control-on-lenovo-c940.patch +alsa-hda-realtek-add-mute-led-quirk-for-more-hp-laptops.patch +alsa-hda-realtek-enable-mute-and-micmute-led-on-hp-elitebook-850-g7.patch +alsa-hda-realtek-add-two-intel-reference-board-ssid-in-the-alc256.patch +iommu-vt-d-move-intel_iommu-info-from-struct-intel_svm-to-struct-intel_svm_dev.patch +btrfs-qgroup-don-t-try-to-wait-flushing-if-we-re-already-holding-a-transaction.patch +btrfs-send-fix-wrong-file-path-when-there-is-an-inode-with-a-pending-rmdir.patch +revert-device-property-keep-secondary-firmware-node-secondary-by-type.patch +dmabuf-fix-use-after-free-of-dmabuf-s-file-f_inode.patch +arm64-link-with-z-norelro-for-lld-or-aarch64-elf.patch +drm-i915-clear-the-shadow-batch.patch +drm-i915-clear-the-gpu-reloc-batch.patch +bcache-fix-typo-from-suup-to-supp-in-features.h.patch +bcache-check-unsupported-feature-sets-for-bcache-register.patch +bcache-introduce-bch_feature_incompat_log_large_bucket_size-for-large-bucket.patch diff --git a/queue-5.10/usb-chipidea-ci_hdrc_imx-add-missing-put_device-call-in-usbmisc_get_init_data.patch b/queue-5.10/usb-chipidea-ci_hdrc_imx-add-missing-put_device-call-in-usbmisc_get_init_data.patch new file mode 100644 index 00000000000..82fc622158a --- /dev/null +++ b/queue-5.10/usb-chipidea-ci_hdrc_imx-add-missing-put_device-call-in-usbmisc_get_init_data.patch @@ -0,0 +1,40 @@ +From 83a43ff80a566de8718dfc6565545a0080ec1fb5 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Tue, 17 Nov 2020 09:14:30 +0800 +Subject: usb: chipidea: ci_hdrc_imx: add missing put_device() call in usbmisc_get_init_data() + +From: Yu Kuai + +commit 83a43ff80a566de8718dfc6565545a0080ec1fb5 upstream. + +if of_find_device_by_node() succeed, usbmisc_get_init_data() doesn't have +a corresponding put_device(). Thus add put_device() to fix the exception +handling for this function implementation. + +Fixes: ef12da914ed6 ("usb: chipidea: imx: properly check for usbmisc") +Signed-off-by: Yu Kuai +Cc: stable +Link: https://lore.kernel.org/r/20201117011430.642589-1-yukuai3@huawei.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/ci_hdrc_imx.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_ + misc_pdev = of_find_device_by_node(args.np); + of_node_put(args.np); + +- if (!misc_pdev || !platform_get_drvdata(misc_pdev)) ++ if (!misc_pdev) + return ERR_PTR(-EPROBE_DEFER); + ++ if (!platform_get_drvdata(misc_pdev)) { ++ put_device(&misc_pdev->dev); ++ return ERR_PTR(-EPROBE_DEFER); ++ } + data->dev = &misc_pdev->dev; + + /* diff --git a/queue-5.10/usb-dwc3-gadget-clear-wait-flag-on-dequeue.patch b/queue-5.10/usb-dwc3-gadget-clear-wait-flag-on-dequeue.patch new file mode 100644 index 00000000000..2dd29f10dba --- /dev/null +++ b/queue-5.10/usb-dwc3-gadget-clear-wait-flag-on-dequeue.patch @@ -0,0 +1,35 @@ +From a5c7682aaaa10e42928d73de1c9e1e02d2b14c2e Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Mon, 4 Jan 2021 22:42:39 -0800 +Subject: usb: dwc3: gadget: Clear wait flag on dequeue + +From: Thinh Nguyen + +commit a5c7682aaaa10e42928d73de1c9e1e02d2b14c2e upstream. + +If an active transfer is dequeued, then the endpoint is freed to start a +new transfer. Make sure to clear the endpoint's transfer wait flag for +this case. + +Fixes: e0d19563eb6c ("usb: dwc3: gadget: Wait for transfer completion") +Cc: stable@vger.kernel.org +Acked-by: Felipe Balbi +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/b81cd5b5281cfbfdadb002c4bcf5c9be7c017cfd.1609828485.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/gadget.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct + list_for_each_entry_safe(r, t, &dep->started_list, list) + dwc3_gadget_move_cancelled_request(r); + ++ dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; ++ + goto out; + } + } diff --git a/queue-5.10/usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch b/queue-5.10/usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch new file mode 100644 index 00000000000..e2b6ea6aadd --- /dev/null +++ b/queue-5.10/usb-dwc3-gadget-restart-dwc3-gadget-when-enabling-pullup.patch @@ -0,0 +1,70 @@ +From a1383b3537a7bea1c213baa7878ccc4ecf4413b5 Mon Sep 17 00:00:00 2001 +From: Wesley Cheng +Date: Tue, 29 Dec 2020 15:00:37 -0800 +Subject: usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup + +From: Wesley Cheng + +commit a1383b3537a7bea1c213baa7878ccc4ecf4413b5 upstream. + +usb_gadget_deactivate/usb_gadget_activate does not execute the UDC start +operation, which may leave EP0 disabled and event IRQs disabled when +re-activating the function. Move the enabling/disabling of USB EP0 and +device event IRQs to be performed in the pullup routine. + +Fixes: ae7e86108b12 ("usb: dwc3: Stop active transfers before halting the controller") +Tested-by: Michael Tretter +Cc: stable +Reported-by: Michael Tretter +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/1609282837-21666-1-git-send-email-wcheng@codeaurora.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/gadget.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2083,6 +2083,7 @@ static int dwc3_gadget_run_stop(struct d + + static void dwc3_gadget_disable_irq(struct dwc3 *dwc); + static void __dwc3_gadget_stop(struct dwc3 *dwc); ++static int __dwc3_gadget_start(struct dwc3 *dwc); + + static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + { +@@ -2145,6 +2146,8 @@ static int dwc3_gadget_pullup(struct usb + dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % + dwc->ev_buf->length; + } ++ } else { ++ __dwc3_gadget_start(dwc); + } + + ret = dwc3_gadget_run_stop(dwc, is_on, false); +@@ -2319,10 +2322,6 @@ static int dwc3_gadget_start(struct usb_ + } + + dwc->gadget_driver = driver; +- +- if (pm_runtime_active(dwc->dev)) +- __dwc3_gadget_start(dwc); +- + spin_unlock_irqrestore(&dwc->lock, flags); + + return 0; +@@ -2348,13 +2347,6 @@ static int dwc3_gadget_stop(struct usb_g + unsigned long flags; + + spin_lock_irqsave(&dwc->lock, flags); +- +- if (pm_runtime_suspended(dwc->dev)) +- goto out; +- +- __dwc3_gadget_stop(dwc); +- +-out: + dwc->gadget_driver = NULL; + spin_unlock_irqrestore(&dwc->lock, flags); + diff --git a/queue-5.10/usb-dwc3-meson-g12a-disable-clk-on-error-handling-path-in-probe.patch b/queue-5.10/usb-dwc3-meson-g12a-disable-clk-on-error-handling-path-in-probe.patch new file mode 100644 index 00000000000..10c3b9a4fd1 --- /dev/null +++ b/queue-5.10/usb-dwc3-meson-g12a-disable-clk-on-error-handling-path-in-probe.patch @@ -0,0 +1,35 @@ +From a5ada3dfe6a20f41f91448b9034a1ef8da3dc87d Mon Sep 17 00:00:00 2001 +From: Zheng Zengkai +Date: Tue, 15 Dec 2020 10:54:59 +0800 +Subject: usb: dwc3: meson-g12a: disable clk on error handling path in probe + +From: Zheng Zengkai + +commit a5ada3dfe6a20f41f91448b9034a1ef8da3dc87d upstream. + +dwc3_meson_g12a_probe() does not invoke clk_bulk_disable_unprepare() +on one error handling path. This patch fixes that. + +Fixes: 347052e3bf1b ("usb: dwc3: meson-g12a: fix USB2 PHY initialization on G12A and A1 SoCs") +Reported-by: Hulk Robot +Signed-off-by: Zheng Zengkai +Cc: stable +Reviewed-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20201215025459.91794-1-zhengzengkai@huawei.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/dwc3-meson-g12a.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/dwc3-meson-g12a.c ++++ b/drivers/usb/dwc3/dwc3-meson-g12a.c +@@ -754,7 +754,7 @@ static int dwc3_meson_g12a_probe(struct + + ret = priv->drvdata->setup_regmaps(priv, base); + if (ret) +- return ret; ++ goto err_disable_clks; + + if (priv->vbus) { + ret = regulator_enable(priv->vbus); diff --git a/queue-5.10/usb-dwc3-ulpi-fix-usb2.0-hs-fs-ls-phy-suspend-regression.patch b/queue-5.10/usb-dwc3-ulpi-fix-usb2.0-hs-fs-ls-phy-suspend-regression.patch new file mode 100644 index 00000000000..eb3a3a9d832 --- /dev/null +++ b/queue-5.10/usb-dwc3-ulpi-fix-usb2.0-hs-fs-ls-phy-suspend-regression.patch @@ -0,0 +1,91 @@ +From e5f4ca3fce90a37b23a77bfcc86800d484a80514 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Thu, 10 Dec 2020 11:50:08 +0300 +Subject: usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression + +From: Serge Semin + +commit e5f4ca3fce90a37b23a77bfcc86800d484a80514 upstream. + +First of all the commit e0082698b689 ("usb: dwc3: ulpi: conditionally +resume ULPI PHY") introduced the Suspend USB2.0 HS/FS/LS PHY regression, +as by design of the fix any attempt to read/write from/to the PHY control +registers will completely disable the PHY suspension, which consequently +will increase the USB bus power consumption. Secondly the fix won't work +well for the very first attempt of the ULPI PHY control registers IO, +because after disabling the USB2.0 PHY suspension functionality it will +still take some time for the bus to resume from the sleep state if one has +been reached before it. So the very first PHY register read/write +operation will take more time than the busy-loop provides and the IO +timeout error might be returned anyway. + +Here we suggest to fix the denoted problems in the following way. First of +all let's not disable the Suspend USB2.0 HS/FS/LS PHY functionality so to +make the controller and the USB2.0 bus more power efficient. Secondly +instead of that we'll extend the PHY IO op wait procedure with 1 - 1.2 ms +sleep if the PHY suspension is enabled (1ms should be enough as by LPM +specification it is at most how long it takes for the USB2.0 bus to resume +from L1 (Sleep) state). Finally in case if the USB2.0 PHY suspension +functionality has been disabled on the DWC USB3 controller setup procedure +we'll compensate the USB bus resume process latency by extending the +busy-loop attempts counter. + +Fixes: e0082698b689 ("usb: dwc3: ulpi: conditionally resume ULPI PHY") +Acked-by: Heikki Krogerus +Signed-off-by: Serge Semin +Link: https://lore.kernel.org/r/20201210085008.13264-4-Sergey.Semin@baikalelectronics.ru +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/ulpi.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +--- a/drivers/usb/dwc3/ulpi.c ++++ b/drivers/usb/dwc3/ulpi.c +@@ -24,7 +24,7 @@ + static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read) + { + unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY; +- unsigned int count = 1000; ++ unsigned int count = 10000; + u32 reg; + + if (addr >= ULPI_EXT_VENDOR_SPECIFIC) +@@ -33,6 +33,10 @@ static int dwc3_ulpi_busyloop(struct dwc + if (read) + ns += DWC3_ULPI_BASE_DELAY; + ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ if (reg & DWC3_GUSB2PHYCFG_SUSPHY) ++ usleep_range(1000, 1200); ++ + while (count--) { + ndelay(ns); + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); +@@ -50,12 +54,6 @@ static int dwc3_ulpi_read(struct device + u32 reg; + int ret; + +- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); +- if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { +- reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); +- } +- + reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); + dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); + +@@ -73,12 +71,6 @@ static int dwc3_ulpi_write(struct device + struct dwc3 *dwc = dev_get_drvdata(dev); + u32 reg; + +- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); +- if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { +- reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; +- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); +- } +- + reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); + reg |= DWC3_GUSB2PHYACC_WRITE | val; + dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); diff --git a/queue-5.10/usb-dwc3-ulpi-replace-cpu-based-busyloop-with-protocol-based-one.patch b/queue-5.10/usb-dwc3-ulpi-replace-cpu-based-busyloop-with-protocol-based-one.patch new file mode 100644 index 00000000000..08c8534f181 --- /dev/null +++ b/queue-5.10/usb-dwc3-ulpi-replace-cpu-based-busyloop-with-protocol-based-one.patch @@ -0,0 +1,94 @@ +From fca3f138105727c3a22edda32d02f91ce1bf11c9 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Thu, 10 Dec 2020 11:50:07 +0300 +Subject: usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one + +From: Serge Semin + +commit fca3f138105727c3a22edda32d02f91ce1bf11c9 upstream. + +Originally the procedure of the ULPI transaction finish detection has been +developed as a simple busy-loop with just decrementing counter and no +delays. It's wrong since on different systems the loop will take a +different time to complete. So if the system bus and CPU are fast enough +to overtake the ULPI bus and the companion PHY reaction, then we'll get to +take a false timeout error. Fix this by converting the busy-loop procedure +to take the standard bus speed, address value and the registers access +mode into account for the busy-loop delay calculation. + +Here is the way the fix works. It's known that the ULPI bus is clocked +with 60MHz signal. In accordance with [1] the ULPI bus protocol is created +so to spend 5 and 6 clock periods for immediate register write and read +operations respectively, and 6 and 7 clock periods - for the extended +register writes and reads. Based on that we can easily pre-calculate the +time which will be needed for the controller to perform a requested IO +operation. Note we'll still preserve the attempts counter in case if the +DWC USB3 controller has got some internals delays. + +[1] UTMI+ Low Pin Interface (ULPI) Specification, Revision 1.1, + October 20, 2004, pp. 30 - 36. + +Fixes: 88bc9d194ff6 ("usb: dwc3: add ULPI interface support") +Acked-by: Heikki Krogerus +Signed-off-by: Serge Semin +Link: https://lore.kernel.org/r/20201210085008.13264-3-Sergey.Semin@baikalelectronics.ru +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/ulpi.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/usb/dwc3/ulpi.c ++++ b/drivers/usb/dwc3/ulpi.c +@@ -7,6 +7,8 @@ + * Author: Heikki Krogerus + */ + ++#include ++#include + #include + + #include "core.h" +@@ -17,12 +19,22 @@ + DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ + DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) + +-static int dwc3_ulpi_busyloop(struct dwc3 *dwc) ++#define DWC3_ULPI_BASE_DELAY DIV_ROUND_UP(NSEC_PER_SEC, 60000000L) ++ ++static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read) + { ++ unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY; + unsigned int count = 1000; + u32 reg; + ++ if (addr >= ULPI_EXT_VENDOR_SPECIFIC) ++ ns += DWC3_ULPI_BASE_DELAY; ++ ++ if (read) ++ ns += DWC3_ULPI_BASE_DELAY; ++ + while (count--) { ++ ndelay(ns); + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); + if (reg & DWC3_GUSB2PHYACC_DONE) + return 0; +@@ -47,7 +59,7 @@ static int dwc3_ulpi_read(struct device + reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); + dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); + +- ret = dwc3_ulpi_busyloop(dwc); ++ ret = dwc3_ulpi_busyloop(dwc, addr, true); + if (ret) + return ret; + +@@ -71,7 +83,7 @@ static int dwc3_ulpi_write(struct device + reg |= DWC3_GUSB2PHYACC_WRITE | val; + dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); + +- return dwc3_ulpi_busyloop(dwc); ++ return dwc3_ulpi_busyloop(dwc, addr, false); + } + + static const struct ulpi_ops dwc3_ulpi_ops = { diff --git a/queue-5.10/usb-dwc3-ulpi-use-vstsdone-to-detect-phy-regs-access-completion.patch b/queue-5.10/usb-dwc3-ulpi-use-vstsdone-to-detect-phy-regs-access-completion.patch new file mode 100644 index 00000000000..f952715ba04 --- /dev/null +++ b/queue-5.10/usb-dwc3-ulpi-use-vstsdone-to-detect-phy-regs-access-completion.patch @@ -0,0 +1,54 @@ +From ce722da66d3e9384aa2de9d33d584ee154e5e157 Mon Sep 17 00:00:00 2001 +From: Serge Semin +Date: Thu, 10 Dec 2020 11:50:06 +0300 +Subject: usb: dwc3: ulpi: Use VStsDone to detect PHY regs access completion + +From: Serge Semin + +commit ce722da66d3e9384aa2de9d33d584ee154e5e157 upstream. + +In accordance with [1] the DWC_usb3 core sets the GUSB2PHYACCn.VStsDone +bit when the PHY vendor control access is done and clears it when the +application initiates a new transaction. The doc doesn't say anything +about the GUSB2PHYACCn.VStsBsy flag serving for the same purpose. Moreover +we've discovered that the VStsBsy flag can be cleared before the VStsDone +bit. So using the former as a signal of the PHY control registers +completion might be dangerous. Let's have the VStsDone flag utilized +instead then. + +[1] Synopsys DesignWare Cores SuperSpeed USB 3.0 xHCI Host Controller + Databook, 2.70a, December 2013, p.388 + +Fixes: 88bc9d194ff6 ("usb: dwc3: add ULPI interface support") +Acked-by: Heikki Krogerus +Signed-off-by: Serge Semin +Link: https://lore.kernel.org/r/20201210085008.13264-2-Sergey.Semin@baikalelectronics.ru +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/core.h | 1 + + drivers/usb/dwc3/ulpi.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -285,6 +285,7 @@ + + /* Global USB2 PHY Vendor Control Register */ + #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) ++#define DWC3_GUSB2PHYACC_DONE BIT(24) + #define DWC3_GUSB2PHYACC_BUSY BIT(23) + #define DWC3_GUSB2PHYACC_WRITE BIT(22) + #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) +--- a/drivers/usb/dwc3/ulpi.c ++++ b/drivers/usb/dwc3/ulpi.c +@@ -24,7 +24,7 @@ static int dwc3_ulpi_busyloop(struct dwc + + while (count--) { + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); +- if (!(reg & DWC3_GUSB2PHYACC_BUSY)) ++ if (reg & DWC3_GUSB2PHYACC_DONE) + return 0; + cpu_relax(); + } diff --git a/queue-5.10/usb-gadget-configfs-fix-use-after-free-issue-with-udc_name.patch b/queue-5.10/usb-gadget-configfs-fix-use-after-free-issue-with-udc_name.patch new file mode 100644 index 00000000000..5108e87ae81 --- /dev/null +++ b/queue-5.10/usb-gadget-configfs-fix-use-after-free-issue-with-udc_name.patch @@ -0,0 +1,72 @@ +From 64e6bbfff52db4bf6785fab9cffab850b2de6870 Mon Sep 17 00:00:00 2001 +From: Eddie Hung +Date: Tue, 29 Dec 2020 18:53:35 +0800 +Subject: usb: gadget: configfs: Fix use-after-free issue with udc_name + +From: Eddie Hung + +commit 64e6bbfff52db4bf6785fab9cffab850b2de6870 upstream. + +There is a use-after-free issue, if access udc_name +in function gadget_dev_desc_UDC_store after another context +free udc_name in function unregister_gadget. + +Context 1: +gadget_dev_desc_UDC_store()->unregister_gadget()-> +free udc_name->set udc_name to NULL + +Context 2: +gadget_dev_desc_UDC_show()-> access udc_name + +Call trace: +dump_backtrace+0x0/0x340 +show_stack+0x14/0x1c +dump_stack+0xe4/0x134 +print_address_description+0x78/0x478 +__kasan_report+0x270/0x2ec +kasan_report+0x10/0x18 +__asan_report_load1_noabort+0x18/0x20 +string+0xf4/0x138 +vsnprintf+0x428/0x14d0 +sprintf+0xe4/0x12c +gadget_dev_desc_UDC_show+0x54/0x64 +configfs_read_file+0x210/0x3a0 +__vfs_read+0xf0/0x49c +vfs_read+0x130/0x2b4 +SyS_read+0x114/0x208 +el0_svc_naked+0x34/0x38 + +Add mutex_lock to protect this kind of scenario. + +Signed-off-by: Eddie Hung +Signed-off-by: Macpaul Lin +Reviewed-by: Peter Chen +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/1609239215-21819-1-git-send-email-macpaul.lin@mediatek.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/configfs.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -221,9 +221,16 @@ static ssize_t gadget_dev_desc_bcdUSB_st + + static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) + { +- char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name; ++ struct gadget_info *gi = to_gadget_info(item); ++ char *udc_name; ++ int ret; + +- return sprintf(page, "%s\n", udc_name ?: ""); ++ mutex_lock(&gi->lock); ++ udc_name = gi->composite.gadget_driver.udc_name; ++ ret = sprintf(page, "%s\n", udc_name ?: ""); ++ mutex_unlock(&gi->lock); ++ ++ return ret; + } + + static int unregister_gadget(struct gadget_info *gi) diff --git a/queue-5.10/usb-gadget-configfs-preserve-function-ordering-after-bind-failure.patch b/queue-5.10/usb-gadget-configfs-preserve-function-ordering-after-bind-failure.patch new file mode 100644 index 00000000000..a841c535079 --- /dev/null +++ b/queue-5.10/usb-gadget-configfs-preserve-function-ordering-after-bind-failure.patch @@ -0,0 +1,91 @@ +From 6cd0fe91387917be48e91385a572a69dfac2f3f7 Mon Sep 17 00:00:00 2001 +From: Chandana Kishori Chiluveru +Date: Tue, 29 Dec 2020 14:44:43 -0800 +Subject: usb: gadget: configfs: Preserve function ordering after bind failure + +From: Chandana Kishori Chiluveru + +commit 6cd0fe91387917be48e91385a572a69dfac2f3f7 upstream. + +When binding the ConfigFS gadget to a UDC, the functions in each +configuration are added in list order. However, if usb_add_function() +fails, the failed function is put back on its configuration's +func_list and purge_configs_funcs() is called to further clean up. + +purge_configs_funcs() iterates over the configurations and functions +in forward order, calling unbind() on each of the previously added +functions. But after doing so, each function gets moved to the +tail of the configuration's func_list. This results in reshuffling +the original order of the functions within a configuration such +that the failed function now appears first even though it may have +originally appeared in the middle or even end of the list. At this +point if the ConfigFS gadget is attempted to re-bind to the UDC, +the functions will be added in a different order than intended, +with the only recourse being to remove and relink the functions all +over again. + +An example of this as follows: + +ln -s functions/mass_storage.0 configs/c.1 +ln -s functions/ncm.0 configs/c.1 +ln -s functions/ffs.adb configs/c.1 # oops, forgot to start adbd +echo "" > UDC # fails +start adbd +echo "" > UDC # now succeeds, but... + # bind order is + # "ADB", mass_storage, ncm + +[30133.118289] configfs-gadget gadget: adding 'Mass Storage Function'/ffffff810af87200 to config 'c'/ffffff817d6a2520 +[30133.119875] configfs-gadget gadget: adding 'cdc_network'/ffffff80f48d1a00 to config 'c'/ffffff817d6a2520 +[30133.119974] using random self ethernet address +[30133.120002] using random host ethernet address +[30133.139604] usb0: HOST MAC 3e:27:46:ba:3e:26 +[30133.140015] usb0: MAC 6e:28:7e:42:66:6a +[30133.140062] configfs-gadget gadget: adding 'Function FS Gadget'/ffffff80f3868438 to config 'c'/ffffff817d6a2520 +[30133.140081] configfs-gadget gadget: adding 'Function FS Gadget'/ffffff80f3868438 --> -19 +[30133.140098] configfs-gadget gadget: unbind function 'Mass Storage Function'/ffffff810af87200 +[30133.140119] configfs-gadget gadget: unbind function 'cdc_network'/ffffff80f48d1a00 +[30133.173201] configfs-gadget a600000.dwc3: failed to start g1: -19 +[30136.661933] init: starting service 'adbd'... +[30136.700126] read descriptors +[30136.700413] read strings +[30138.574484] configfs-gadget gadget: adding 'Function FS Gadget'/ffffff80f3868438 to config 'c'/ffffff817d6a2520 +[30138.575497] configfs-gadget gadget: adding 'Mass Storage Function'/ffffff810af87200 to config 'c'/ffffff817d6a2520 +[30138.575554] configfs-gadget gadget: adding 'cdc_network'/ffffff80f48d1a00 to config 'c'/ffffff817d6a2520 +[30138.575631] using random self ethernet address +[30138.575660] using random host ethernet address +[30138.595338] usb0: HOST MAC 2e:cf:43:cd:ca:c8 +[30138.597160] usb0: MAC 6a:f0:9f:ee:82:a0 +[30138.791490] configfs-gadget gadget: super-speed config #1: c + +Fix this by reversing the iteration order of the functions in +purge_config_funcs() when unbinding them, and adding them back to +the config's func_list at the head instead of the tail. This +ensures that we unbind and unwind back to the original list order. + +Fixes: 88af8bbe4ef7 ("usb: gadget: the start of the configfs interface") +Signed-off-by: Chandana Kishori Chiluveru +Signed-off-by: Jack Pham +Reviewed-by: Peter Chen +Link: https://lore.kernel.org/r/20201229224443.31623-1-jackp@codeaurora.org +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/configfs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -1248,9 +1248,9 @@ static void purge_configs_funcs(struct g + + cfg = container_of(c, struct config_usb_cfg, c); + +- list_for_each_entry_safe(f, tmp, &c->functions, list) { ++ list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) { + +- list_move_tail(&f->list, &cfg->func_list); ++ list_move(&f->list, &cfg->func_list); + if (f->unbind) { + dev_dbg(&gi->cdev.gadget->dev, + "unbind function '%s'/%p\n", diff --git a/queue-5.10/usb-gadget-dummy-hcd-fix-shift-out-of-bounds-bug.patch b/queue-5.10/usb-gadget-dummy-hcd-fix-shift-out-of-bounds-bug.patch new file mode 100644 index 00000000000..055ba008fc7 --- /dev/null +++ b/queue-5.10/usb-gadget-dummy-hcd-fix-shift-out-of-bounds-bug.patch @@ -0,0 +1,91 @@ +From c318840fb2a42ce25febc95c4c19357acf1ae5ca Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 30 Dec 2020 11:20:44 -0500 +Subject: USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug + +From: Alan Stern + +commit c318840fb2a42ce25febc95c4c19357acf1ae5ca upstream. + +The dummy-hcd driver was written under the assumption that all the +parameters in URBs sent to its root hub would be valid. With URBs +sent from userspace via usbfs, that assumption can be violated. + +In particular, the driver doesn't fully check the port-feature values +stored in the wValue entry of Clear-Port-Feature and Set-Port-Feature +requests. Values that are too large can cause the driver to perform +an invalid left shift of more than 32 bits. Ironically, two of those +left shifts are unnecessary, because they implement Set-Port-Feature +requests that hubs are not required to support, according to section +11.24.2.13 of the USB-2.0 spec. + +This patch adds the appropriate checks for the port feature selector +values and removes the unnecessary feature settings. It also rejects +requests to set the TEST feature or to set or clear the INDICATOR and +C_OVERCURRENT features, as none of these are relevant to dummy-hcd's +root-hub emulation. + +CC: +Reported-and-tested-by: syzbot+5925509f78293baa7331@syzkaller.appspotmail.com +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/20201230162044.GA727759@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/dummy_hcd.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -2114,9 +2114,21 @@ static int dummy_hub_control( + dum_hcd->port_status &= ~USB_PORT_STAT_POWER; + set_link_state(dum_hcd); + break; +- default: ++ case USB_PORT_FEAT_ENABLE: ++ case USB_PORT_FEAT_C_ENABLE: ++ case USB_PORT_FEAT_C_SUSPEND: ++ /* Not allowed for USB-3 */ ++ if (hcd->speed == HCD_USB3) ++ goto error; ++ fallthrough; ++ case USB_PORT_FEAT_C_CONNECTION: ++ case USB_PORT_FEAT_C_RESET: + dum_hcd->port_status &= ~(1 << wValue); + set_link_state(dum_hcd); ++ break; ++ default: ++ /* Disallow INDICATOR and C_OVER_CURRENT */ ++ goto error; + } + break; + case GetHubDescriptor: +@@ -2277,18 +2289,17 @@ static int dummy_hub_control( + */ + dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); + fallthrough; ++ case USB_PORT_FEAT_C_CONNECTION: ++ case USB_PORT_FEAT_C_RESET: ++ case USB_PORT_FEAT_C_ENABLE: ++ case USB_PORT_FEAT_C_SUSPEND: ++ /* Not allowed for USB-3, and ignored for USB-2 */ ++ if (hcd->speed == HCD_USB3) ++ goto error; ++ break; + default: +- if (hcd->speed == HCD_USB3) { +- if ((dum_hcd->port_status & +- USB_SS_PORT_STAT_POWER) != 0) { +- dum_hcd->port_status |= (1 << wValue); +- } +- } else +- if ((dum_hcd->port_status & +- USB_PORT_STAT_POWER) != 0) { +- dum_hcd->port_status |= (1 << wValue); +- } +- set_link_state(dum_hcd); ++ /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */ ++ goto error; + } + break; + case GetPortErrorCount: diff --git a/queue-5.10/usb-gadget-f_uac2-reset-wmaxpacketsize.patch b/queue-5.10/usb-gadget-f_uac2-reset-wmaxpacketsize.patch new file mode 100644 index 00000000000..576d939f9ee --- /dev/null +++ b/queue-5.10/usb-gadget-f_uac2-reset-wmaxpacketsize.patch @@ -0,0 +1,152 @@ +From 9389044f27081d6ec77730c36d5bf9a1288bcda2 Mon Sep 17 00:00:00 2001 +From: Jerome Brunet +Date: Mon, 21 Dec 2020 18:35:28 +0100 +Subject: usb: gadget: f_uac2: reset wMaxPacketSize + +From: Jerome Brunet + +commit 9389044f27081d6ec77730c36d5bf9a1288bcda2 upstream. + +With commit 913e4a90b6f9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth") +wMaxPacketSize is computed dynamically but the value is never reset. + +Because of this, the actual maximum packet size can only decrease each time +the audio gadget is instantiated. + +Reset the endpoint maximum packet size and mark wMaxPacketSize as dynamic +to solve the problem. + +Fixes: 913e4a90b6f9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth") +Signed-off-by: Jerome Brunet +Cc: stable +Link: https://lore.kernel.org/r/20201221173531.215169-2-jbrunet@baylibre.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_uac2.c | 69 +++++++++++++++++++++++++++-------- + 1 file changed, 55 insertions(+), 14 deletions(-) + +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1023), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 1, + }; + +@@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1024), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 4, + }; + +@@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1023), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 1, + }; + +@@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, +- .wMaxPacketSize = cpu_to_le16(1024), ++ /* .wMaxPacketSize = DYNAMIC */ + .bInterval = 4, + }; + +@@ -444,12 +444,28 @@ struct cntrl_range_lay3 { + __le32 dRES; + } __packed; + +-static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, ++static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + struct usb_endpoint_descriptor *ep_desc, +- unsigned int factor, bool is_playback) ++ enum usb_device_speed speed, bool is_playback) + { + int chmask, srate, ssize; +- u16 max_packet_size; ++ u16 max_size_bw, max_size_ep; ++ unsigned int factor; ++ ++ switch (speed) { ++ case USB_SPEED_FULL: ++ max_size_ep = 1023; ++ factor = 1000; ++ break; ++ ++ case USB_SPEED_HIGH: ++ max_size_ep = 1024; ++ factor = 8000; ++ break; ++ ++ default: ++ return -EINVAL; ++ } + + if (is_playback) { + chmask = uac2_opts->p_chmask; +@@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const + ssize = uac2_opts->c_ssize; + } + +- max_packet_size = num_channels(chmask) * ssize * ++ max_size_bw = num_channels(chmask) * ssize * + DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); +- ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, +- le16_to_cpu(ep_desc->wMaxPacketSize))); ++ ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, ++ max_size_ep)); ++ ++ return 0; + } + + /* Use macro to overcome line length limitation */ +@@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg + } + + /* Calculate wMaxPacketSize according to audio bandwidth */ +- set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); +- set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); +- set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); +- set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); ++ ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, ++ true); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ ++ ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL, ++ false); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ ++ ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH, ++ true); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ ++ ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH, ++ false); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } + + if (EPOUT_EN(uac2_opts)) { + agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); diff --git a/queue-5.10/usb-gadget-fix-spinlock-lockup-on-usb_function_deactivate.patch b/queue-5.10/usb-gadget-fix-spinlock-lockup-on-usb_function_deactivate.patch new file mode 100644 index 00000000000..e82e0f3be61 --- /dev/null +++ b/queue-5.10/usb-gadget-fix-spinlock-lockup-on-usb_function_deactivate.patch @@ -0,0 +1,86 @@ +From 5cc35c224a80aa5a5a539510ef049faf0d6ed181 Mon Sep 17 00:00:00 2001 +From: Sriharsha Allenki +Date: Wed, 2 Dec 2020 18:32:20 +0530 +Subject: usb: gadget: Fix spinlock lockup on usb_function_deactivate + +From: Sriharsha Allenki + +commit 5cc35c224a80aa5a5a539510ef049faf0d6ed181 upstream. + +There is a spinlock lockup as part of composite_disconnect +when it tries to acquire cdev->lock as part of usb_gadget_deactivate. +This is because the usb_gadget_deactivate is called from +usb_function_deactivate with the same spinlock held. + +This would result in the below call stack and leads to stall. + +rcu: INFO: rcu_preempt detected stalls on CPUs/tasks: +rcu: 3-...0: (1 GPs behind) idle=162/1/0x4000000000000000 +softirq=10819/10819 fqs=2356 + (detected by 2, t=5252 jiffies, g=20129, q=3770) + Task dump for CPU 3: + task:uvc-gadget_wlhe state:R running task stack: 0 pid: 674 ppid: + 636 flags:0x00000202 + Call trace: + __switch_to+0xc0/0x170 + _raw_spin_lock_irqsave+0x84/0xb0 + composite_disconnect+0x28/0x78 + configfs_composite_disconnect+0x68/0x70 + usb_gadget_disconnect+0x10c/0x128 + usb_gadget_deactivate+0xd4/0x108 + usb_function_deactivate+0x6c/0x80 + uvc_function_disconnect+0x20/0x58 + uvc_v4l2_release+0x30/0x88 + v4l2_release+0xbc/0xf0 + __fput+0x7c/0x230 + ____fput+0x14/0x20 + task_work_run+0x88/0x140 + do_notify_resume+0x240/0x6f0 + work_pending+0x8/0x200 + +Fix this by doing an unlock on cdev->lock before the usb_gadget_deactivate +call from usb_function_deactivate. + +The same lockup can happen in the usb_gadget_activate path. Fix that path +as well. + +Reported-by: Peter Chen +Link: https://lore.kernel.org/linux-usb/20201102094936.GA29581@b29397-desktop/ +Tested-by: Peter Chen +Signed-off-by: Sriharsha Allenki +Cc: stable +Link: https://lore.kernel.org/r/20201202130220.24926-1-sallenki@codeaurora.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/composite.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_f + + spin_lock_irqsave(&cdev->lock, flags); + +- if (cdev->deactivations == 0) ++ if (cdev->deactivations == 0) { ++ spin_unlock_irqrestore(&cdev->lock, flags); + status = usb_gadget_deactivate(cdev->gadget); ++ spin_lock_irqsave(&cdev->lock, flags); ++ } + if (status == 0) + cdev->deactivations++; + +@@ -424,8 +427,11 @@ int usb_function_activate(struct usb_fun + status = -EINVAL; + else { + cdev->deactivations--; +- if (cdev->deactivations == 0) ++ if (cdev->deactivations == 0) { ++ spin_unlock_irqrestore(&cdev->lock, flags); + status = usb_gadget_activate(cdev->gadget); ++ spin_lock_irqsave(&cdev->lock, flags); ++ } + } + + spin_unlock_irqrestore(&cdev->lock, flags); diff --git a/queue-5.10/usb-gadget-function-printer-fix-a-memory-leak-for-interface-descriptor.patch b/queue-5.10/usb-gadget-function-printer-fix-a-memory-leak-for-interface-descriptor.patch new file mode 100644 index 00000000000..14ac7d825e0 --- /dev/null +++ b/queue-5.10/usb-gadget-function-printer-fix-a-memory-leak-for-interface-descriptor.patch @@ -0,0 +1,33 @@ +From 2cc332e4ee4febcbb685e2962ad323fe4b3b750a Mon Sep 17 00:00:00 2001 +From: Zqiang +Date: Thu, 10 Dec 2020 10:01:48 +0800 +Subject: usb: gadget: function: printer: Fix a memory leak for interface descriptor + +From: Zqiang + +commit 2cc332e4ee4febcbb685e2962ad323fe4b3b750a upstream. + +When printer driver is loaded, the printer_func_bind function is called, in +this function, the interface descriptor be allocated memory, if after that, +the error occurred, the interface descriptor memory need to be free. + +Reviewed-by: Peter Chen +Cc: +Signed-off-by: Zqiang +Link: https://lore.kernel.org/r/20201210020148.6691-1-qiang.zhang@windriver.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_printer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -1162,6 +1162,7 @@ fail_tx_reqs: + printer_req_free(dev->in_ep, req); + } + ++ usb_free_all_descriptors(f); + return ret; + + } diff --git a/queue-5.10/usb-gadget-legacy-fix-return-error-code-in-acm_ms_bind.patch b/queue-5.10/usb-gadget-legacy-fix-return-error-code-in-acm_ms_bind.patch new file mode 100644 index 00000000000..cecd90afb6b --- /dev/null +++ b/queue-5.10/usb-gadget-legacy-fix-return-error-code-in-acm_ms_bind.patch @@ -0,0 +1,36 @@ +From c91d3a6bcaa031f551ba29a496a8027b31289464 Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Tue, 17 Nov 2020 17:29:55 +0800 +Subject: USB: gadget: legacy: fix return error code in acm_ms_bind() + +From: Yang Yingliang + +commit c91d3a6bcaa031f551ba29a496a8027b31289464 upstream. + +If usb_otg_descriptor_alloc() failed, it need return ENOMEM. + +Fixes: 578aa8a2b12c ("usb: gadget: acm_ms: allocate and init otg descriptor by otg capabilities") +Reported-by: Hulk Robot +Signed-off-by: Yang Yingliang +Cc: stable +Link: https://lore.kernel.org/r/20201117092955.4102785-1-yangyingliang@huawei.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/legacy/acm_ms.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/acm_ms.c ++++ b/drivers/usb/gadget/legacy/acm_ms.c +@@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_compos + struct usb_descriptor_header *usb_desc; + + usb_desc = usb_otg_descriptor_alloc(gadget); +- if (!usb_desc) ++ if (!usb_desc) { ++ status = -ENOMEM; + goto fail_string_ids; ++ } + usb_otg_descriptor_init(gadget, usb_desc); + otg_desc[0] = usb_desc; + otg_desc[1] = NULL; diff --git a/queue-5.10/usb-gadget-select-config_crc32.patch b/queue-5.10/usb-gadget-select-config_crc32.patch new file mode 100644 index 00000000000..57b9e1988c7 --- /dev/null +++ b/queue-5.10/usb-gadget-select-config_crc32.patch @@ -0,0 +1,44 @@ +From d7889c2020e08caab0d7e36e947f642d91015bd0 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Sun, 3 Jan 2021 22:42:17 +0100 +Subject: usb: gadget: select CONFIG_CRC32 + +From: Arnd Bergmann + +commit d7889c2020e08caab0d7e36e947f642d91015bd0 upstream. + +Without crc32 support, this driver fails to link: + +arm-linux-gnueabi-ld: drivers/usb/gadget/function/f_eem.o: in function `eem_unwrap': +f_eem.c:(.text+0x11cc): undefined reference to `crc32_le' +arm-linux-gnueabi-ld: drivers/usb/gadget/function/f_ncm.o:f_ncm.c:(.text+0x1e40): +more undefined references to `crc32_le' follow + +Fixes: 6d3865f9d41f ("usb: gadget: NCM: Add transmit multi-frame.") +Signed-off-by: Arnd Bergmann +Cc: stable +Link: https://lore.kernel.org/r/20210103214224.1996535-1-arnd@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM + depends on NET + select USB_U_ETHER + select USB_F_NCM ++ select CRC32 + help + NCM is an advanced protocol for Ethernet encapsulation, allows + grouping of several ethernet frames into one USB transfer and +@@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM + depends on NET + select USB_U_ETHER + select USB_F_EEM ++ select CRC32 + help + CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM + and therefore can be supported by more hardware. Technically ECM and diff --git a/queue-5.10/usb-gadget-u_ether-fix-mtu-size-mismatch-with-rx-packet-size.patch b/queue-5.10/usb-gadget-u_ether-fix-mtu-size-mismatch-with-rx-packet-size.patch new file mode 100644 index 00000000000..7a42eeb6126 --- /dev/null +++ b/queue-5.10/usb-gadget-u_ether-fix-mtu-size-mismatch-with-rx-packet-size.patch @@ -0,0 +1,59 @@ +From 0a88fa221ce911c331bf700d2214c5b2f77414d3 Mon Sep 17 00:00:00 2001 +From: Manish Narani +Date: Tue, 17 Nov 2020 12:43:35 +0530 +Subject: usb: gadget: u_ether: Fix MTU size mismatch with RX packet size + +From: Manish Narani + +commit 0a88fa221ce911c331bf700d2214c5b2f77414d3 upstream. + +Fix the MTU size issue with RX packet size as the host sends the packet +with extra bytes containing ethernet header. This causes failure when +user sets the MTU size to the maximum i.e. 15412. In this case the +ethernet packet received will be of length 15412 plus the ethernet header +length. This patch fixes the issue where there is a check that RX packet +length must not be more than max packet length. + +Fixes: bba787a860fa ("usb: gadget: ether: Allow jumbo frames") +Signed-off-by: Manish Narani +Cc: stable +Link: https://lore.kernel.org/r/1605597215-122027-1-git-send-email-manish.narani@xilinx.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/u_ether.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -45,9 +45,10 @@ + #define UETH__VERSION "29-May-2008" + + /* Experiments show that both Linux and Windows hosts allow up to 16k +- * frame sizes. Set the max size to 15k+52 to prevent allocating 32k ++ * frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k + * blocks and still have efficient handling. */ +-#define GETHER_MAX_ETH_FRAME_LEN 15412 ++#define GETHER_MAX_MTU_SIZE 15412 ++#define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN) + + struct eth_dev { + /* lock is held while accessing port_usb +@@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct + + /* MTU range: 14 - 15412 */ + net->min_mtu = ETH_HLEN; +- net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; ++ net->max_mtu = GETHER_MAX_MTU_SIZE; + + dev->gadget = g; + SET_NETDEV_DEV(net, &g->dev); +@@ -848,7 +849,7 @@ struct net_device *gether_setup_name_def + + /* MTU range: 14 - 15412 */ + net->min_mtu = ETH_HLEN; +- net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; ++ net->max_mtu = GETHER_MAX_MTU_SIZE; + + return net; + } diff --git a/queue-5.10/usb-serial-iuu_phoenix-fix-dma-from-stack.patch b/queue-5.10/usb-serial-iuu_phoenix-fix-dma-from-stack.patch new file mode 100644 index 00000000000..817daa7dff2 --- /dev/null +++ b/queue-5.10/usb-serial-iuu_phoenix-fix-dma-from-stack.patch @@ -0,0 +1,76 @@ +From 54d0a3ab80f49f19ee916def62fe067596833403 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 4 Jan 2021 15:50:07 +0100 +Subject: USB: serial: iuu_phoenix: fix DMA from stack + +From: Johan Hovold + +commit 54d0a3ab80f49f19ee916def62fe067596833403 upstream. + +Stack-allocated buffers cannot be used for DMA (on all architectures) so +allocate the flush command buffer using kmalloc(). + +Fixes: 60a8fc017103 ("USB: add iuu_phoenix driver") +Cc: stable # 2.6.25 +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/iuu_phoenix.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/iuu_phoenix.c ++++ b/drivers/usb/serial/iuu_phoenix.c +@@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_ser + struct device *dev = &port->dev; + int i; + int status; +- u8 rxcmd = IUU_UART_RX; ++ u8 *rxcmd; + struct iuu_private *priv = usb_get_serial_port_data(port); + + if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) + return -EIO; + ++ rxcmd = kmalloc(1, GFP_KERNEL); ++ if (!rxcmd) ++ return -ENOMEM; ++ ++ rxcmd[0] = IUU_UART_RX; ++ + for (i = 0; i < 2; i++) { +- status = bulk_immediate(port, &rxcmd, 1); ++ status = bulk_immediate(port, rxcmd, 1); + if (status != IUU_OPERATION_OK) { + dev_dbg(dev, "%s - uart_flush_write error\n", __func__); +- return status; ++ goto out_free; + } + + status = read_immediate(port, &priv->len, 1); + if (status != IUU_OPERATION_OK) { + dev_dbg(dev, "%s - uart_flush_read error\n", __func__); +- return status; ++ goto out_free; + } + + if (priv->len > 0) { +@@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_ser + status = read_immediate(port, priv->buf, priv->len); + if (status != IUU_OPERATION_OK) { + dev_dbg(dev, "%s - uart_flush_read error\n", __func__); +- return status; ++ goto out_free; + } + } + } + dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); + iuu_led(port, 0, 0xF000, 0, 0xFF); ++ ++out_free: ++ kfree(rxcmd); ++ + return status; + } + diff --git a/queue-5.10/usb-serial-keyspan_pda-remove-unused-variable.patch b/queue-5.10/usb-serial-keyspan_pda-remove-unused-variable.patch new file mode 100644 index 00000000000..4513bd122e2 --- /dev/null +++ b/queue-5.10/usb-serial-keyspan_pda-remove-unused-variable.patch @@ -0,0 +1,34 @@ +From 62218024401fac7dd7c7a6e74b566164d515d922 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 8 Jan 2021 15:55:28 +0100 +Subject: USB: serial: keyspan_pda: remove unused variable + +From: Johan Hovold + +Remove an unused variable which was mistakingly left by commit +37faf5061541 ("USB: serial: keyspan_pda: fix write-wakeup +use-after-free") and only removed by a later change. + +This is needed to suppress a W=1 warning about the unused variable in +the stable trees that the build bots triggers. + +Reported-by: kernel test robot +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/keyspan_pda.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/serial/keyspan_pda.c ++++ b/drivers/usb/serial/keyspan_pda.c +@@ -555,10 +555,8 @@ exit: + static void keyspan_pda_write_bulk_callback(struct urb *urb) + { + struct usb_serial_port *port = urb->context; +- struct keyspan_pda_private *priv; + + set_bit(0, &port->write_urbs_free); +- priv = usb_get_serial_port_data(port); + + /* queue up a wakeup at scheduler time */ + usb_serial_port_softint(port); diff --git a/queue-5.10/usb-serial-option-add-longsung-m5710-module-support.patch b/queue-5.10/usb-serial-option-add-longsung-m5710-module-support.patch new file mode 100644 index 00000000000..72d9162f62f --- /dev/null +++ b/queue-5.10/usb-serial-option-add-longsung-m5710-module-support.patch @@ -0,0 +1,57 @@ +From 0e2d6795e8dbe91c2f5473564c6b25d11df3778b Mon Sep 17 00:00:00 2001 +From: Daniel Palmer +Date: Sun, 27 Dec 2020 12:17:16 +0900 +Subject: USB: serial: option: add LongSung M5710 module support + +From: Daniel Palmer + +commit 0e2d6795e8dbe91c2f5473564c6b25d11df3778b upstream. + +Add a device-id entry for the LongSung M5710 module. + +T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=2df3 ProdID=9d03 Rev= 1.00 +S: Manufacturer=Marvell +S: Product=Mobile Composite Device Bus +S: SerialNumber= +C:* #Ifs= 5 Cfg#= 1 Atr=c0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=03 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=e0(wlcon) Sub=01 Prot=03 Driver=rndis_host +E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: Daniel Palmer +https://lore.kernel.org/r/20201227031716.1343300-1-daniel@0x0f.com +[ johan: drop id defines, only bind to vendor class ] +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2057,6 +2057,7 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ + .driver_info = RSVD(6) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ diff --git a/queue-5.10/usb-serial-option-add-quectel-em160r-gl.patch b/queue-5.10/usb-serial-option-add-quectel-em160r-gl.patch new file mode 100644 index 00000000000..97e3d61f23e --- /dev/null +++ b/queue-5.10/usb-serial-option-add-quectel-em160r-gl.patch @@ -0,0 +1,63 @@ +From d6c1ddd938d84a1adef7e19e8efc10e1b4df5034 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Wed, 30 Dec 2020 16:25:34 +0100 +Subject: USB: serial: option: add Quectel EM160R-GL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjørn Mork + +commit d6c1ddd938d84a1adef7e19e8efc10e1b4df5034 upstream. + +New modem using ff/ff/30 for QCDM, ff/00/00 for AT and NMEA, +and ff/ff/ff for RMNET/QMI. + +T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 +D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1 +P: Vendor=2c7c ProdID=0620 Rev= 4.09 +S: Manufacturer=Quectel +S: Product=EM160R-GL +S: SerialNumber=e31cedc1 +C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=896mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=(none) +E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) +E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms + +Cc: stable@vger.kernel.org +Signed-off-by: Bjørn Mork +[ johan: add model comment ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1117,6 +1117,8 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */ ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), diff --git a/queue-5.10/usb-uas-add-pny-usb-portable-ssd-to-unusual_uas.patch b/queue-5.10/usb-uas-add-pny-usb-portable-ssd-to-unusual_uas.patch new file mode 100644 index 00000000000..c6504606b12 --- /dev/null +++ b/queue-5.10/usb-uas-add-pny-usb-portable-ssd-to-unusual_uas.patch @@ -0,0 +1,42 @@ +From 96ebc9c871d8a28fb22aa758dd9188a4732df482 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Mon, 4 Jan 2021 20:07:15 -0800 +Subject: usb: uas: Add PNY USB Portable SSD to unusual_uas + +From: Thinh Nguyen + +commit 96ebc9c871d8a28fb22aa758dd9188a4732df482 upstream. + +Here's another variant PNY Pro Elite USB 3.1 Gen 2 portable SSD that +hangs and doesn't respond to ATA_1x pass-through commands. If it doesn't +support these commands, it should respond properly to the host. Add it +to the unusual uas list to be able to move forward with other +operations. + +Cc: stable@vger.kernel.org +Reviewed-by: Hans de Goede +Acked-by: Oliver Neukum +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/2edc7af892d0913bf06f5b35e49ec463f03d5ed8.1609819418.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_uas.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_uas.h ++++ b/drivers/usb/storage/unusual_uas.h +@@ -91,6 +91,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x99 + US_FL_BROKEN_FUA), + + /* Reported-by: Thinh Nguyen */ ++UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, ++ "PNY", ++ "Pro Elite SSD", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_NO_ATA_1X), ++ ++/* Reported-by: Thinh Nguyen */ + UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, + "PNY", + "Pro Elite SSD", diff --git a/queue-5.10/usb-usbip-vhci_hcd-protect-shift-size.patch b/queue-5.10/usb-usbip-vhci_hcd-protect-shift-size.patch new file mode 100644 index 00000000000..a2a1441cc0b --- /dev/null +++ b/queue-5.10/usb-usbip-vhci_hcd-protect-shift-size.patch @@ -0,0 +1,40 @@ +From 718bf42b119de652ebcc93655a1f33a9c0d04b3c Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 28 Dec 2020 23:13:09 -0800 +Subject: usb: usbip: vhci_hcd: protect shift size + +From: Randy Dunlap + +commit 718bf42b119de652ebcc93655a1f33a9c0d04b3c upstream. + +Fix shift out-of-bounds in vhci_hcd.c: + + UBSAN: shift-out-of-bounds in ../drivers/usb/usbip/vhci_hcd.c:399:41 + shift exponent 768 is too large for 32-bit type 'int' + +Fixes: 03cd00d538a6 ("usbip: vhci-hcd: Set the vhci structure up to work") +Signed-off-by: Randy Dunlap +Reported-by: syzbot+297d20e437b79283bf6d@syzkaller.appspotmail.com +Cc: Yuyang Du +Cc: Shuah Khan +Cc: Greg Kroah-Hartman +Cc: linux-usb@vger.kernel.org +Cc: stable +Link: https://lore.kernel.org/r/20201229071309.18418-1-rdunlap@infradead.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/usbip/vhci_hcd.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -396,6 +396,8 @@ static int vhci_hub_control(struct usb_h + default: + usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", + wValue); ++ if (wValue >= 32) ++ goto error; + vhci_hcd->port_status[rhport] &= ~(1 << wValue); + break; + } diff --git a/queue-5.10/usb-usblp-fix-dma-to-stack.patch b/queue-5.10/usb-usblp-fix-dma-to-stack.patch new file mode 100644 index 00000000000..791cb93fd8f --- /dev/null +++ b/queue-5.10/usb-usblp-fix-dma-to-stack.patch @@ -0,0 +1,58 @@ +From 020a1f453449294926ca548d8d5ca970926e8dfd Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 4 Jan 2021 15:53:02 +0100 +Subject: USB: usblp: fix DMA to stack + +From: Johan Hovold + +commit 020a1f453449294926ca548d8d5ca970926e8dfd upstream. + +Stack-allocated buffers cannot be used for DMA (on all architectures). + +Replace the HP-channel macro with a helper function that allocates a +dedicated transfer buffer so that it can continue to be used with +arguments from the stack. + +Note that the buffer is cleared on allocation as usblp_ctrl_msg() +returns success also on short transfers (the buffer is only used for +debugging). + +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210104145302.2087-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/usblp.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -274,8 +274,25 @@ static int usblp_ctrl_msg(struct usblp * + #define usblp_reset(usblp)\ + usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0) + +-#define usblp_hp_channel_change_request(usblp, channel, buffer) \ +- usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1) ++static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel) ++{ ++ u8 *buf; ++ int ret; ++ ++ buf = kzalloc(1, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, ++ USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, ++ channel, buf, 1); ++ if (ret == 0) ++ *new_channel = buf[0]; ++ ++ kfree(buf); ++ ++ return ret; ++} + + /* + * See the description for usblp_select_alts() below for the usage diff --git a/queue-5.10/usb-xhci-fix-u1-u2-handling-for-hardware-with-xhci_intel_host-quirk-set.patch b/queue-5.10/usb-xhci-fix-u1-u2-handling-for-hardware-with-xhci_intel_host-quirk-set.patch new file mode 100644 index 00000000000..4cb65d8d9cc --- /dev/null +++ b/queue-5.10/usb-xhci-fix-u1-u2-handling-for-hardware-with-xhci_intel_host-quirk-set.patch @@ -0,0 +1,89 @@ +From 5d5323a6f3625f101dbfa94ba3ef7706cce38760 Mon Sep 17 00:00:00 2001 +From: Michael Grzeschik +Date: Tue, 15 Dec 2020 20:31:47 +0100 +Subject: USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST quirk set + +From: Michael Grzeschik + +commit 5d5323a6f3625f101dbfa94ba3ef7706cce38760 upstream. + +The commit 0472bf06c6fd ("xhci: Prevent U1/U2 link pm states if exit +latency is too long") was constraining the xhci code not to allow U1/U2 +sleep states if the latency to wake up from the U-states reached the +service interval of an periodic endpoint. This fix was not taking into +account that in case the quirk XHCI_INTEL_HOST is set, the wakeup time +will be calculated and configured differently. + +It checks for u1_params.mel/u2_params.mel as a limit. But the code could +decide to write another MEL into the hardware. This leads to broken +cases where not enough bandwidth is available for other devices: + +usb 1-2: can't set config #1, error -28 + +This patch is fixing that case by checking for timeout_ns after the +wakeup time was calculated depending on the quirks. + +Fixes: 0472bf06c6fd ("xhci: Prevent U1/U2 link pm states if exit latency is too long") +Signed-off-by: Michael Grzeschik +Cc: stable +Link: https://lore.kernel.org/r/20201215193147.11738-1-m.grzeschik@pengutronix.de +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4646,19 +4646,19 @@ static u16 xhci_calculate_u1_timeout(str + { + unsigned long long timeout_ns; + ++ if (xhci->quirks & XHCI_INTEL_HOST) ++ timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); ++ else ++ timeout_ns = udev->u1_params.sel; ++ + /* Prevent U1 if service interval is shorter than U1 exit latency */ + if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { +- if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { ++ if (xhci_service_interval_to_ns(desc) <= timeout_ns) { + dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); + return USB3_LPM_DISABLED; + } + } + +- if (xhci->quirks & XHCI_INTEL_HOST) +- timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); +- else +- timeout_ns = udev->u1_params.sel; +- + /* The U1 timeout is encoded in 1us intervals. + * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. + */ +@@ -4710,19 +4710,19 @@ static u16 xhci_calculate_u2_timeout(str + { + unsigned long long timeout_ns; + ++ if (xhci->quirks & XHCI_INTEL_HOST) ++ timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); ++ else ++ timeout_ns = udev->u2_params.sel; ++ + /* Prevent U2 if service interval is shorter than U2 exit latency */ + if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { +- if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { ++ if (xhci_service_interval_to_ns(desc) <= timeout_ns) { + dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); + return USB3_LPM_DISABLED; + } + } + +- if (xhci->quirks & XHCI_INTEL_HOST) +- timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); +- else +- timeout_ns = udev->u2_params.sel; +- + /* The U2 timeout is encoded in 256us intervals */ + timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); + /* If the necessary timeout value is bigger than what we can set in the diff --git a/queue-5.10/usb-yurex-fix-control-urb-timeout-handling.patch b/queue-5.10/usb-yurex-fix-control-urb-timeout-handling.patch new file mode 100644 index 00000000000..a7873869f4d --- /dev/null +++ b/queue-5.10/usb-yurex-fix-control-urb-timeout-handling.patch @@ -0,0 +1,38 @@ +From 372c93131998c0622304bed118322d2a04489e63 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 14 Dec 2020 11:30:53 +0100 +Subject: USB: yurex: fix control-URB timeout handling + +From: Johan Hovold + +commit 372c93131998c0622304bed118322d2a04489e63 upstream. + +Make sure to always cancel the control URB in write() so that it can be +reused after a timeout or spurious CMD_ACK. + +Currently any further write requests after a timeout would fail after +triggering a WARN() in usb_submit_urb() when attempting to submit the +already active URB. + +Reported-by: syzbot+e87ebe0f7913f71f2ea5@syzkaller.appspotmail.com +Fixes: 6bc235a2e24a ("USB: add driver for Meywa-Denki & Kayac YUREX") +Cc: stable # 2.6.37 +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/yurex.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -495,6 +495,9 @@ static ssize_t yurex_write(struct file * + timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); + finish_wait(&dev->waitq, &wait); + ++ /* make sure URB is idle after timeout or (spurious) CMD_ACK */ ++ usb_kill_urb(dev->cntl_urb); ++ + mutex_unlock(&dev->io_mutex); + + if (retval < 0) { diff --git a/queue-5.10/x86-mm-fix-leak-of-pmd-ptlock.patch b/queue-5.10/x86-mm-fix-leak-of-pmd-ptlock.patch new file mode 100644 index 00000000000..1e17f214a80 --- /dev/null +++ b/queue-5.10/x86-mm-fix-leak-of-pmd-ptlock.patch @@ -0,0 +1,85 @@ +From d1c5246e08eb64991001d97a3bd119c93edbc79a Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 2 Dec 2020 22:28:12 -0800 +Subject: x86/mm: Fix leak of pmd ptlock + +From: Dan Williams + +commit d1c5246e08eb64991001d97a3bd119c93edbc79a upstream. + +Commit + + 28ee90fe6048 ("x86/mm: implement free pmd/pte page interfaces") + +introduced a new location where a pmd was released, but neglected to +run the pmd page destructor. In fact, this happened previously for a +different pmd release path and was fixed by commit: + + c283610e44ec ("x86, mm: do not leak page->ptl for pmd page tables"). + +This issue was hidden until recently because the failure mode is silent, +but commit: + + b2b29d6d0119 ("mm: account PMD tables like PTE tables") + +turns the failure mode into this signature: + + BUG: Bad page state in process lt-pmem-ns pfn:15943d + page:000000007262ed7b refcount:0 mapcount:-1024 mapping:0000000000000000 index:0x0 pfn:0x15943d + flags: 0xaffff800000000() + raw: 00affff800000000 dead000000000100 0000000000000000 0000000000000000 + raw: 0000000000000000 ffff913a029bcc08 00000000fffffbff 0000000000000000 + page dumped because: nonzero mapcount + [..] + dump_stack+0x8b/0xb0 + bad_page.cold+0x63/0x94 + free_pcp_prepare+0x224/0x270 + free_unref_page+0x18/0xd0 + pud_free_pmd_page+0x146/0x160 + ioremap_pud_range+0xe3/0x350 + ioremap_page_range+0x108/0x160 + __ioremap_caller.constprop.0+0x174/0x2b0 + ? memremap+0x7a/0x110 + memremap+0x7a/0x110 + devm_memremap+0x53/0xa0 + pmem_attach_disk+0x4ed/0x530 [nd_pmem] + ? __devm_release_region+0x52/0x80 + nvdimm_bus_probe+0x85/0x210 [libnvdimm] + +Given this is a repeat occurrence it seemed prudent to look for other +places where this destructor might be missing and whether a better +helper is needed. try_to_free_pmd_page() looks like a candidate, but +testing with setting up and tearing down pmd mappings via the dax unit +tests is thus far not triggering the failure. + +As for a better helper pmd_free() is close, but it is a messy fit +due to requiring an @mm arg. Also, ___pmd_free_tlb() wants to call +paravirt_tlb_remove_table() instead of free_page(), so open-coded +pgtable_pmd_page_dtor() seems the best way forward for now. + +Debugged together with Matthew Wilcox . + +Fixes: 28ee90fe6048 ("x86/mm: implement free pmd/pte page interfaces") +Signed-off-by: Dan Williams +Signed-off-by: Borislav Petkov +Tested-by: Yi Zhang +Acked-by: Peter Zijlstra (Intel) +Cc: +Link: https://lkml.kernel.org/r/160697689204.605323.17629854984697045602.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/pgtable.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -829,6 +829,8 @@ int pud_free_pmd_page(pud_t *pud, unsign + } + + free_page((unsigned long)pmd_sv); ++ ++ pgtable_pmd_page_dtor(virt_to_page(pmd)); + free_page((unsigned long)pmd); + + return 1; diff --git a/queue-5.10/x86-resctrl-don-t-move-a-task-to-the-same-resource-group.patch b/queue-5.10/x86-resctrl-don-t-move-a-task-to-the-same-resource-group.patch new file mode 100644 index 00000000000..7d470d074f1 --- /dev/null +++ b/queue-5.10/x86-resctrl-don-t-move-a-task-to-the-same-resource-group.patch @@ -0,0 +1,49 @@ +From a0195f314a25582b38993bf30db11c300f4f4611 Mon Sep 17 00:00:00 2001 +From: Fenghua Yu +Date: Thu, 17 Dec 2020 14:31:19 -0800 +Subject: x86/resctrl: Don't move a task to the same resource group + +From: Fenghua Yu + +commit a0195f314a25582b38993bf30db11c300f4f4611 upstream. + +Shakeel Butt reported in [1] that a user can request a task to be moved +to a resource group even if the task is already in the group. It just +wastes time to do the move operation which could be costly to send IPI +to a different CPU. + +Add a sanity check to ensure that the move operation only happens when +the task is not already in the resource group. + +[1] https://lore.kernel.org/lkml/CALvZod7E9zzHwenzf7objzGKsdBmVwTgEJ0nPgs0LUFU3SN5Pw@mail.gmail.com/ + +Fixes: e02737d5b826 ("x86/intel_rdt: Add tasks files") +Reported-by: Shakeel Butt +Signed-off-by: Fenghua Yu +Signed-off-by: Reinette Chatre +Signed-off-by: Borislav Petkov +Reviewed-by: Tony Luck +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/962ede65d8e95be793cb61102cca37f7bb018e66.1608243147.git.reinette.chatre@intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/resctrl/rdtgroup.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c ++++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c +@@ -546,6 +546,13 @@ static void update_task_closid_rmid(stru + static int __rdtgroup_move_task(struct task_struct *tsk, + struct rdtgroup *rdtgrp) + { ++ /* If the task is already in rdtgrp, no need to move the task. */ ++ if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && ++ tsk->rmid == rdtgrp->mon.rmid) || ++ (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && ++ tsk->closid == rdtgrp->mon.parent->closid)) ++ return 0; ++ + /* + * Set the task's closid/rmid before the PQR_ASSOC MSR can be + * updated by them. diff --git a/queue-5.10/x86-resctrl-use-an-ipi-instead-of-task_work_add-to-update-pqr_assoc-msr.patch b/queue-5.10/x86-resctrl-use-an-ipi-instead-of-task_work_add-to-update-pqr_assoc-msr.patch new file mode 100644 index 00000000000..0e39793ad73 --- /dev/null +++ b/queue-5.10/x86-resctrl-use-an-ipi-instead-of-task_work_add-to-update-pqr_assoc-msr.patch @@ -0,0 +1,208 @@ +From ae28d1aae48a1258bd09a6f707ebb4231d79a761 Mon Sep 17 00:00:00 2001 +From: Fenghua Yu +Date: Thu, 17 Dec 2020 14:31:18 -0800 +Subject: x86/resctrl: Use an IPI instead of task_work_add() to update PQR_ASSOC MSR + +From: Fenghua Yu + +commit ae28d1aae48a1258bd09a6f707ebb4231d79a761 upstream. + +Currently, when moving a task to a resource group the PQR_ASSOC MSR is +updated with the new closid and rmid in an added task callback. If the +task is running, the work is run as soon as possible. If the task is not +running, the work is executed later in the kernel exit path when the +kernel returns to the task again. + +Updating the PQR_ASSOC MSR as soon as possible on the CPU a moved task +is running is the right thing to do. Queueing work for a task that is +not running is unnecessary (the PQR_ASSOC MSR is already updated when +the task is scheduled in) and causing system resource waste with the way +in which it is implemented: Work to update the PQR_ASSOC register is +queued every time the user writes a task id to the "tasks" file, even if +the task already belongs to the resource group. + +This could result in multiple pending work items associated with a +single task even if they are all identical and even though only a single +update with most recent values is needed. Specifically, even if a task +is moved between different resource groups while it is sleeping then it +is only the last move that is relevant but yet a work item is queued +during each move. + +This unnecessary queueing of work items could result in significant +system resource waste, especially on tasks sleeping for a long time. +For example, as demonstrated by Shakeel Butt in [1] writing the same +task id to the "tasks" file can quickly consume significant memory. The +same problem (wasted system resources) occurs when moving a task between +different resource groups. + +As pointed out by Valentin Schneider in [2] there is an additional issue +with the way in which the queueing of work is done in that the task_struct +update is currently done after the work is queued, resulting in a race with +the register update possibly done before the data needed by the update is +available. + +To solve these issues, update the PQR_ASSOC MSR in a synchronous way +right after the new closid and rmid are ready during the task movement, +only if the task is running. If a moved task is not running nothing +is done since the PQR_ASSOC MSR will be updated next time the task is +scheduled. This is the same way used to update the register when tasks +are moved as part of resource group removal. + +[1] https://lore.kernel.org/lkml/CALvZod7E9zzHwenzf7objzGKsdBmVwTgEJ0nPgs0LUFU3SN5Pw@mail.gmail.com/ +[2] https://lore.kernel.org/lkml/20201123022433.17905-1-valentin.schneider@arm.com + + [ bp: Massage commit message and drop the two update_task_closid_rmid() + variants. ] + +Fixes: e02737d5b826 ("x86/intel_rdt: Add tasks files") +Reported-by: Shakeel Butt +Reported-by: Valentin Schneider +Signed-off-by: Fenghua Yu +Signed-off-by: Reinette Chatre +Signed-off-by: Borislav Petkov +Reviewed-by: Tony Luck +Reviewed-by: James Morse +Reviewed-by: Valentin Schneider +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/17aa2fb38fc12ce7bb710106b3e7c7b45acb9e94.1608243147.git.reinette.chatre@intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/resctrl/rdtgroup.c | 112 ++++++++++++--------------------- + 1 file changed, 43 insertions(+), 69 deletions(-) + +--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c ++++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c +@@ -525,89 +525,63 @@ static void rdtgroup_remove(struct rdtgr + kfree(rdtgrp); + } + +-struct task_move_callback { +- struct callback_head work; +- struct rdtgroup *rdtgrp; +-}; +- +-static void move_myself(struct callback_head *head) ++static void _update_task_closid_rmid(void *task) + { +- struct task_move_callback *callback; +- struct rdtgroup *rdtgrp; +- +- callback = container_of(head, struct task_move_callback, work); +- rdtgrp = callback->rdtgrp; +- + /* +- * If resource group was deleted before this task work callback +- * was invoked, then assign the task to root group and free the +- * resource group. ++ * If the task is still current on this CPU, update PQR_ASSOC MSR. ++ * Otherwise, the MSR is updated when the task is scheduled in. + */ +- if (atomic_dec_and_test(&rdtgrp->waitcount) && +- (rdtgrp->flags & RDT_DELETED)) { +- current->closid = 0; +- current->rmid = 0; +- rdtgroup_remove(rdtgrp); +- } +- +- if (unlikely(current->flags & PF_EXITING)) +- goto out; +- +- preempt_disable(); +- /* update PQR_ASSOC MSR to make resource group go into effect */ +- resctrl_sched_in(); +- preempt_enable(); ++ if (task == current) ++ resctrl_sched_in(); ++} + +-out: +- kfree(callback); ++static void update_task_closid_rmid(struct task_struct *t) ++{ ++ if (IS_ENABLED(CONFIG_SMP) && task_curr(t)) ++ smp_call_function_single(task_cpu(t), _update_task_closid_rmid, t, 1); ++ else ++ _update_task_closid_rmid(t); + } + + static int __rdtgroup_move_task(struct task_struct *tsk, + struct rdtgroup *rdtgrp) + { +- struct task_move_callback *callback; +- int ret; +- +- callback = kzalloc(sizeof(*callback), GFP_KERNEL); +- if (!callback) +- return -ENOMEM; +- callback->work.func = move_myself; +- callback->rdtgrp = rdtgrp; +- + /* +- * Take a refcount, so rdtgrp cannot be freed before the +- * callback has been invoked. ++ * Set the task's closid/rmid before the PQR_ASSOC MSR can be ++ * updated by them. ++ * ++ * For ctrl_mon groups, move both closid and rmid. ++ * For monitor groups, can move the tasks only from ++ * their parent CTRL group. + */ +- atomic_inc(&rdtgrp->waitcount); +- ret = task_work_add(tsk, &callback->work, TWA_RESUME); +- if (ret) { +- /* +- * Task is exiting. Drop the refcount and free the callback. +- * No need to check the refcount as the group cannot be +- * deleted before the write function unlocks rdtgroup_mutex. +- */ +- atomic_dec(&rdtgrp->waitcount); +- kfree(callback); +- rdt_last_cmd_puts("Task exited\n"); +- } else { +- /* +- * For ctrl_mon groups move both closid and rmid. +- * For monitor groups, can move the tasks only from +- * their parent CTRL group. +- */ +- if (rdtgrp->type == RDTCTRL_GROUP) { +- tsk->closid = rdtgrp->closid; ++ ++ if (rdtgrp->type == RDTCTRL_GROUP) { ++ tsk->closid = rdtgrp->closid; ++ tsk->rmid = rdtgrp->mon.rmid; ++ } else if (rdtgrp->type == RDTMON_GROUP) { ++ if (rdtgrp->mon.parent->closid == tsk->closid) { + tsk->rmid = rdtgrp->mon.rmid; +- } else if (rdtgrp->type == RDTMON_GROUP) { +- if (rdtgrp->mon.parent->closid == tsk->closid) { +- tsk->rmid = rdtgrp->mon.rmid; +- } else { +- rdt_last_cmd_puts("Can't move task to different control group\n"); +- ret = -EINVAL; +- } ++ } else { ++ rdt_last_cmd_puts("Can't move task to different control group\n"); ++ return -EINVAL; + } + } +- return ret; ++ ++ /* ++ * Ensure the task's closid and rmid are written before determining if ++ * the task is current that will decide if it will be interrupted. ++ */ ++ barrier(); ++ ++ /* ++ * By now, the task's closid and rmid are set. If the task is current ++ * on a CPU, the PQR_ASSOC MSR needs to be updated to make the resource ++ * group go into effect. If the task is not current, the MSR will be ++ * updated when the task is scheduled in. ++ */ ++ update_task_closid_rmid(tsk); ++ ++ return 0; + } + + static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)