]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Feb 2022 13:46:37 +0000 (14:46 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Feb 2022 13:46:37 +0000 (14:46 +0100)
added patches:
alsa-hda-fix-uaf-of-leds-class-devs-at-unbinding.patch
alsa-hda-realtek-add-missing-fixup-model-entry-for-gigabyte-x570-alc1220-quirks.patch
alsa-hda-realtek-add-quirk-for-asus-gu603.patch
alsa-hda-realtek-fix-race-at-concurrent-coef-updates.patch
alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-xtreme-after-reboot-from-windows.patch
alsa-hda-realtek-fix-silent-output-on-gigabyte-x570s-aorus-master-newer-chipset.patch
alsa-usb-audio-correct-quirk-for-vf0770.patch
asoc-hdmi-codec-fix-oob-memory-accesses.patch
asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw.patch
asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw_sx.patch
asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_xr_sx.patch
ata-libata-core-introduce-ata_horkage_no_log_dir-horkage.patch
audit-improve-audit-queue-handling-when-audit-1-on-cmdline.patch
block-bio-integrity-advance-seed-correctly-for-larger-interval-sizes.patch
btrfs-don-t-start-transaction-for-scrub-if-the-fs-is-mounted-read-only.patch
btrfs-fix-deadlock-between-quota-disable-and-qgroup-rescan-worker.patch
btrfs-fix-use-after-free-after-failure-to-create-a-snapshot.patch
cifs-fix-workstation_name-for-multiuser-mounts.patch
dma-buf-heaps-fix-potential-spectre-v1-gadget.patch
drm-amd-display-force-link_rate-as-link_rate_rbr2-for-2018-15-apple-retina-panels.patch
drm-amd-display-update-watermark-values-for-dcn301.patch
drm-amd-display-watermark-latencies-is-not-enough-on-dcn31.patch
drm-amd-pm-correct-the-mgpufanboost-support-for-beige-goby.patch
drm-amdgpu-fix-a-potential-gpu-hang-on-cyan-skillfish.patch
drm-i915-adlp-fix-typec-phy-ready-status-readout.patch
drm-i915-disable-dsb-usage-for-now.patch
drm-nouveau-fix-off-by-one-in-bios-boundary-checking.patch
fbcon-add-option-to-enable-legacy-hardware-acceleration.patch
ib-hfi1-fix-aip-early-init-panic.patch
ib-hfi1-fix-alloc-failure-with-larger-txqueuelen.patch
ib-hfi1-fix-panic-with-larger-ipoib-send_queue_size.patch
ipc-sem-do-not-sleep-with-a-spin-lock-held.patch
mm-debug_vm_pgtable-remove-pte-entry-from-the-page-table.patch
mm-kmemleak-avoid-scanning-potential-huge-holes.patch
mm-pgtable-define-pte_index-so-that-preprocessor-could-recognize-it.patch
mptcp-fix-msk-traversal-in-mptcp_nl_cmd_set_flags.patch
nvme-fabrics-fix-state-check-in-nvmf_ctlr_matches_baseopts.patch
revert-fbcon-disable-accelerated-scrolling.patch
revert-fbdev-garbage-collect-fbdev-scrolling-acceleration-part-1-from-todo-list.patch
revert-fs-9p-search-open-fids-first.patch
selinux-fix-double-free-of-cond_list-on-error-paths.patch
spi-stm32-qspi-update-spi-registering.patch

43 files changed:
queue-5.16/alsa-hda-fix-uaf-of-leds-class-devs-at-unbinding.patch [new file with mode: 0644]
queue-5.16/alsa-hda-realtek-add-missing-fixup-model-entry-for-gigabyte-x570-alc1220-quirks.patch [new file with mode: 0644]
queue-5.16/alsa-hda-realtek-add-quirk-for-asus-gu603.patch [new file with mode: 0644]
queue-5.16/alsa-hda-realtek-fix-race-at-concurrent-coef-updates.patch [new file with mode: 0644]
queue-5.16/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-xtreme-after-reboot-from-windows.patch [new file with mode: 0644]
queue-5.16/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570s-aorus-master-newer-chipset.patch [new file with mode: 0644]
queue-5.16/alsa-usb-audio-correct-quirk-for-vf0770.patch [new file with mode: 0644]
queue-5.16/asoc-hdmi-codec-fix-oob-memory-accesses.patch [new file with mode: 0644]
queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw.patch [new file with mode: 0644]
queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw_sx.patch [new file with mode: 0644]
queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_xr_sx.patch [new file with mode: 0644]
queue-5.16/ata-libata-core-introduce-ata_horkage_no_log_dir-horkage.patch [new file with mode: 0644]
queue-5.16/audit-improve-audit-queue-handling-when-audit-1-on-cmdline.patch [new file with mode: 0644]
queue-5.16/block-bio-integrity-advance-seed-correctly-for-larger-interval-sizes.patch [new file with mode: 0644]
queue-5.16/btrfs-don-t-start-transaction-for-scrub-if-the-fs-is-mounted-read-only.patch [new file with mode: 0644]
queue-5.16/btrfs-fix-deadlock-between-quota-disable-and-qgroup-rescan-worker.patch [new file with mode: 0644]
queue-5.16/btrfs-fix-use-after-free-after-failure-to-create-a-snapshot.patch [new file with mode: 0644]
queue-5.16/cifs-fix-workstation_name-for-multiuser-mounts.patch [new file with mode: 0644]
queue-5.16/dma-buf-heaps-fix-potential-spectre-v1-gadget.patch [new file with mode: 0644]
queue-5.16/drm-amd-display-force-link_rate-as-link_rate_rbr2-for-2018-15-apple-retina-panels.patch [new file with mode: 0644]
queue-5.16/drm-amd-display-update-watermark-values-for-dcn301.patch [new file with mode: 0644]
queue-5.16/drm-amd-display-watermark-latencies-is-not-enough-on-dcn31.patch [new file with mode: 0644]
queue-5.16/drm-amd-pm-correct-the-mgpufanboost-support-for-beige-goby.patch [new file with mode: 0644]
queue-5.16/drm-amdgpu-fix-a-potential-gpu-hang-on-cyan-skillfish.patch [new file with mode: 0644]
queue-5.16/drm-i915-adlp-fix-typec-phy-ready-status-readout.patch [new file with mode: 0644]
queue-5.16/drm-i915-disable-dsb-usage-for-now.patch [new file with mode: 0644]
queue-5.16/drm-nouveau-fix-off-by-one-in-bios-boundary-checking.patch [new file with mode: 0644]
queue-5.16/fbcon-add-option-to-enable-legacy-hardware-acceleration.patch [new file with mode: 0644]
queue-5.16/ib-hfi1-fix-aip-early-init-panic.patch [new file with mode: 0644]
queue-5.16/ib-hfi1-fix-alloc-failure-with-larger-txqueuelen.patch [new file with mode: 0644]
queue-5.16/ib-hfi1-fix-panic-with-larger-ipoib-send_queue_size.patch [new file with mode: 0644]
queue-5.16/ipc-sem-do-not-sleep-with-a-spin-lock-held.patch [new file with mode: 0644]
queue-5.16/mm-debug_vm_pgtable-remove-pte-entry-from-the-page-table.patch [new file with mode: 0644]
queue-5.16/mm-kmemleak-avoid-scanning-potential-huge-holes.patch [new file with mode: 0644]
queue-5.16/mm-pgtable-define-pte_index-so-that-preprocessor-could-recognize-it.patch [new file with mode: 0644]
queue-5.16/mptcp-fix-msk-traversal-in-mptcp_nl_cmd_set_flags.patch [new file with mode: 0644]
queue-5.16/nvme-fabrics-fix-state-check-in-nvmf_ctlr_matches_baseopts.patch [new file with mode: 0644]
queue-5.16/revert-fbcon-disable-accelerated-scrolling.patch [new file with mode: 0644]
queue-5.16/revert-fbdev-garbage-collect-fbdev-scrolling-acceleration-part-1-from-todo-list.patch [new file with mode: 0644]
queue-5.16/revert-fs-9p-search-open-fids-first.patch [new file with mode: 0644]
queue-5.16/selinux-fix-double-free-of-cond_list-on-error-paths.patch [new file with mode: 0644]
queue-5.16/series [new file with mode: 0644]
queue-5.16/spi-stm32-qspi-update-spi-registering.patch [new file with mode: 0644]

diff --git a/queue-5.16/alsa-hda-fix-uaf-of-leds-class-devs-at-unbinding.patch b/queue-5.16/alsa-hda-fix-uaf-of-leds-class-devs-at-unbinding.patch
new file mode 100644 (file)
index 0000000..fb39895
--- /dev/null
@@ -0,0 +1,86 @@
+From 549f8ffc7b2f7561bea7f90930b6c5104318e87b Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 26 Jan 2022 15:50:11 +0100
+Subject: ALSA: hda: Fix UAF of leds class devs at unbinding
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 549f8ffc7b2f7561bea7f90930b6c5104318e87b upstream.
+
+The LED class devices that are created by HD-audio codec drivers are
+registered via devm_led_classdev_register() and associated with the
+HD-audio codec device.  Unfortunately, it turned out that the devres
+release doesn't work for this case; namely, since the codec resource
+release happens before the devm call chain, it triggers a NULL
+dereference or a UAF for a stale set_brightness_delay callback.
+
+For fixing the bug, this patch changes the LED class device register
+and unregister in a manual manner without devres, keeping the
+instances in hda_gen_spec.
+
+Reported-by: Alexander Sergeyev <sergeev917@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220111195229.a77wrpjclqwrx4bx@localhost.localdomain
+Link: https://lore.kernel.org/r/20220126145011.16728-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/hda_generic.c |   17 +++++++++++++++--
+ sound/pci/hda/hda_generic.h |    3 +++
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -91,6 +91,12 @@ static void snd_hda_gen_spec_free(struct
+       free_kctls(spec);
+       snd_array_free(&spec->paths);
+       snd_array_free(&spec->loopback_list);
++#ifdef CONFIG_SND_HDA_GENERIC_LEDS
++      if (spec->led_cdevs[LED_AUDIO_MUTE])
++              led_classdev_unregister(spec->led_cdevs[LED_AUDIO_MUTE]);
++      if (spec->led_cdevs[LED_AUDIO_MICMUTE])
++              led_classdev_unregister(spec->led_cdevs[LED_AUDIO_MICMUTE]);
++#endif
+ }
+ /*
+@@ -3922,7 +3928,10 @@ static int create_mute_led_cdev(struct h
+                                               enum led_brightness),
+                               bool micmute)
+ {
++      struct hda_gen_spec *spec = codec->spec;
+       struct led_classdev *cdev;
++      int idx = micmute ? LED_AUDIO_MICMUTE : LED_AUDIO_MUTE;
++      int err;
+       cdev = devm_kzalloc(&codec->core.dev, sizeof(*cdev), GFP_KERNEL);
+       if (!cdev)
+@@ -3932,10 +3941,14 @@ static int create_mute_led_cdev(struct h
+       cdev->max_brightness = 1;
+       cdev->default_trigger = micmute ? "audio-micmute" : "audio-mute";
+       cdev->brightness_set_blocking = callback;
+-      cdev->brightness = ledtrig_audio_get(micmute ? LED_AUDIO_MICMUTE : LED_AUDIO_MUTE);
++      cdev->brightness = ledtrig_audio_get(idx);
+       cdev->flags = LED_CORE_SUSPENDRESUME;
+-      return devm_led_classdev_register(&codec->core.dev, cdev);
++      err = led_classdev_register(&codec->core.dev, cdev);
++      if (err < 0)
++              return err;
++      spec->led_cdevs[idx] = cdev;
++      return 0;
+ }
+ /**
+--- a/sound/pci/hda/hda_generic.h
++++ b/sound/pci/hda/hda_generic.h
+@@ -294,6 +294,9 @@ struct hda_gen_spec {
+                                  struct hda_jack_callback *cb);
+       void (*mic_autoswitch_hook)(struct hda_codec *codec,
+                                   struct hda_jack_callback *cb);
++
++      /* leds */
++      struct led_classdev *led_cdevs[NUM_AUDIO_LEDS];
+ };
+ /* values for add_stereo_mix_input flag */
diff --git a/queue-5.16/alsa-hda-realtek-add-missing-fixup-model-entry-for-gigabyte-x570-alc1220-quirks.patch b/queue-5.16/alsa-hda-realtek-add-missing-fixup-model-entry-for-gigabyte-x570-alc1220-quirks.patch
new file mode 100644 (file)
index 0000000..1e34bc3
--- /dev/null
@@ -0,0 +1,32 @@
+From 63394a16086fc2152869d7902621e2525e14bc40 Mon Sep 17 00:00:00 2001
+From: Christian Lachner <gladiac@gmail.com>
+Date: Sat, 29 Jan 2022 12:32:41 +0100
+Subject: ALSA: hda/realtek: Add missing fixup-model entry for Gigabyte X570 ALC1220 quirks
+
+From: Christian Lachner <gladiac@gmail.com>
+
+commit 63394a16086fc2152869d7902621e2525e14bc40 upstream.
+
+The initial commit of the new Gigabyte X570 ALC1220 quirks lacked the
+fixup-model entry in alc882_fixup_models[]. It seemed not to cause any ill
+effects but for completeness sake this commit makes up for that.
+
+Signed-off-by: Christian Lachner <gladiac@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220129113243.93068-2-gladiac@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -2660,6 +2660,7 @@ static const struct hda_model_fixup alc8
+       {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
+       {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
+       {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
++      {.id = ALC1220_FIXUP_GB_X570, .name = "gb-x570"},
+       {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
+       {}
+ };
diff --git a/queue-5.16/alsa-hda-realtek-add-quirk-for-asus-gu603.patch b/queue-5.16/alsa-hda-realtek-add-quirk-for-asus-gu603.patch
new file mode 100644 (file)
index 0000000..71b1c2a
--- /dev/null
@@ -0,0 +1,36 @@
+From 94db9cc8f8fa2d5426ce79ec4ca16028f7084224 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Albert=20Geant=C4=83?= <albertgeanta@gmail.com>
+Date: Mon, 31 Jan 2022 03:05:23 +0200
+Subject: ALSA: hda/realtek: Add quirk for ASUS GU603
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Albert Geantă <albertgeanta@gmail.com>
+
+commit 94db9cc8f8fa2d5426ce79ec4ca16028f7084224 upstream.
+
+The ASUS GU603 (Zephyrus M16 - SSID 1043:16b2) requires a quirk similar to
+other ASUS devices for correctly routing the 4 integrated speakers. This
+fixes it by adding a corresponding quirk entry, which connects the bass
+speakers to the proper DAC.
+
+Signed-off-by: Albert Geantă <albertgeanta@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220131010523.546386-1-albertgeanta@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -8854,6 +8854,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
+       SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+       SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
++      SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
+       SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+       SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
diff --git a/queue-5.16/alsa-hda-realtek-fix-race-at-concurrent-coef-updates.patch b/queue-5.16/alsa-hda-realtek-fix-race-at-concurrent-coef-updates.patch
new file mode 100644 (file)
index 0000000..f3db0a3
--- /dev/null
@@ -0,0 +1,148 @@
+From b837a9f5ab3bdfab9233c9f98a6bef717673a3e5 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 31 Jan 2022 08:57:38 +0100
+Subject: ALSA: hda: realtek: Fix race at concurrent COEF updates
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit b837a9f5ab3bdfab9233c9f98a6bef717673a3e5 upstream.
+
+The COEF access is done with two steps: setting the index then read or
+write the data.  When multiple COEF accesses are performed
+concurrently, the index and data might be paired unexpectedly.
+In most cases, this isn't a big problem as the COEF setup is done at
+the initialization, but some dynamic changes like the mute LED may hit
+such a race.
+
+For avoiding the racy COEF accesses, this patch introduces a new
+mutex coef_mutex to alc_spec, and wrap the COEF accessing functions
+with it.
+
+Reported-by: Alexander Sergeyev <sergeev917@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220111195229.a77wrpjclqwrx4bx@localhost.localdomain
+Link: https://lore.kernel.org/r/20220131075738.24323-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c |   61 ++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 50 insertions(+), 11 deletions(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -97,6 +97,7 @@ struct alc_spec {
+       unsigned int gpio_mic_led_mask;
+       struct alc_coef_led mute_led_coef;
+       struct alc_coef_led mic_led_coef;
++      struct mutex coef_mutex;
+       hda_nid_t headset_mic_pin;
+       hda_nid_t headphone_mic_pin;
+@@ -132,8 +133,8 @@ struct alc_spec {
+  * COEF access helper functions
+  */
+-static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
+-                             unsigned int coef_idx)
++static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
++                               unsigned int coef_idx)
+ {
+       unsigned int val;
+@@ -142,28 +143,61 @@ static int alc_read_coefex_idx(struct hd
+       return val;
+ }
++static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
++                             unsigned int coef_idx)
++{
++      struct alc_spec *spec = codec->spec;
++      unsigned int val;
++
++      mutex_lock(&spec->coef_mutex);
++      val = __alc_read_coefex_idx(codec, nid, coef_idx);
++      mutex_unlock(&spec->coef_mutex);
++      return val;
++}
++
+ #define alc_read_coef_idx(codec, coef_idx) \
+       alc_read_coefex_idx(codec, 0x20, coef_idx)
+-static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
+-                               unsigned int coef_idx, unsigned int coef_val)
++static void __alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
++                                 unsigned int coef_idx, unsigned int coef_val)
+ {
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
+ }
++static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
++                               unsigned int coef_idx, unsigned int coef_val)
++{
++      struct alc_spec *spec = codec->spec;
++
++      mutex_lock(&spec->coef_mutex);
++      __alc_write_coefex_idx(codec, nid, coef_idx, coef_val);
++      mutex_unlock(&spec->coef_mutex);
++}
++
+ #define alc_write_coef_idx(codec, coef_idx, coef_val) \
+       alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
++static void __alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
++                                  unsigned int coef_idx, unsigned int mask,
++                                  unsigned int bits_set)
++{
++      unsigned int val = __alc_read_coefex_idx(codec, nid, coef_idx);
++
++      if (val != -1)
++              __alc_write_coefex_idx(codec, nid, coef_idx,
++                                     (val & ~mask) | bits_set);
++}
++
+ static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
+                                 unsigned int coef_idx, unsigned int mask,
+                                 unsigned int bits_set)
+ {
+-      unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
++      struct alc_spec *spec = codec->spec;
+-      if (val != -1)
+-              alc_write_coefex_idx(codec, nid, coef_idx,
+-                                   (val & ~mask) | bits_set);
++      mutex_lock(&spec->coef_mutex);
++      __alc_update_coefex_idx(codec, nid, coef_idx, mask, bits_set);
++      mutex_unlock(&spec->coef_mutex);
+ }
+ #define alc_update_coef_idx(codec, coef_idx, mask, bits_set)  \
+@@ -196,13 +230,17 @@ struct coef_fw {
+ static void alc_process_coef_fw(struct hda_codec *codec,
+                               const struct coef_fw *fw)
+ {
++      struct alc_spec *spec = codec->spec;
++
++      mutex_lock(&spec->coef_mutex);
+       for (; fw->nid; fw++) {
+               if (fw->mask == (unsigned short)-1)
+-                      alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
++                      __alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
+               else
+-                      alc_update_coefex_idx(codec, fw->nid, fw->idx,
+-                                            fw->mask, fw->val);
++                      __alc_update_coefex_idx(codec, fw->nid, fw->idx,
++                                              fw->mask, fw->val);
+       }
++      mutex_unlock(&spec->coef_mutex);
+ }
+ /*
+@@ -1148,6 +1186,7 @@ static int alc_alloc_spec(struct hda_cod
+       codec->spdif_status_reset = 1;
+       codec->forced_resume = 1;
+       codec->patch_ops = alc_patch_ops;
++      mutex_init(&spec->coef_mutex);
+       err = alc_codec_rename_from_preset(codec);
+       if (err < 0) {
diff --git a/queue-5.16/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-xtreme-after-reboot-from-windows.patch b/queue-5.16/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-xtreme-after-reboot-from-windows.patch
new file mode 100644 (file)
index 0000000..e8695e9
--- /dev/null
@@ -0,0 +1,34 @@
+From ea3541961376f733373839cc90493aafa8a7f733 Mon Sep 17 00:00:00 2001
+From: Christian Lachner <gladiac@gmail.com>
+Date: Sat, 29 Jan 2022 12:32:43 +0100
+Subject: ALSA: hda/realtek: Fix silent output on Gigabyte X570 Aorus Xtreme after reboot from Windows
+
+From: Christian Lachner <gladiac@gmail.com>
+
+commit ea3541961376f733373839cc90493aafa8a7f733 upstream.
+
+This commit switches the Gigabyte X570 Aorus Xtreme from using the
+ALC1220_FIXUP_CLEVO_P950 to the ALC1220_FIXUP_GB_X570 quirk. This fixes
+the no-audio after reboot from windows problem.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205275
+Signed-off-by: Christian Lachner <gladiac@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220129113243.93068-4-gladiac@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2586,7 +2586,7 @@ static const struct snd_pci_quirk alc882
+       SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
+       SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_GB_X570),
+-      SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950),
++      SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_GB_X570),
+       SND_PCI_QUIRK(0x1458, 0xa0d5, "Gigabyte X570S Aorus Master", ALC1220_FIXUP_GB_X570),
+       SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
diff --git a/queue-5.16/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570s-aorus-master-newer-chipset.patch b/queue-5.16/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570s-aorus-master-newer-chipset.patch
new file mode 100644 (file)
index 0000000..4f401aa
--- /dev/null
@@ -0,0 +1,51 @@
+From 41a8601302ecbe704ac970552c33dc942300fc37 Mon Sep 17 00:00:00 2001
+From: Christian Lachner <gladiac@gmail.com>
+Date: Sat, 29 Jan 2022 12:32:42 +0100
+Subject: ALSA: hda/realtek: Fix silent output on Gigabyte X570S Aorus Master (newer chipset)
+
+From: Christian Lachner <gladiac@gmail.com>
+
+commit 41a8601302ecbe704ac970552c33dc942300fc37 upstream.
+
+Newer versions of the X570 Master come with a newer revision of the
+mainboard chipset - the X570S. These boards have the same ALC1220 codec
+but seem to initialize the codec with a different parameter in Coef 0x7
+which causes the output audio to be very low. We therefore write a
+known-good value to Coef 0x7 to fix that. As the value is the exact same
+as on the other X570(non-S) boards the same quirk-function can be shared
+between both generations.
+
+This commit adds the Gigabyte X570S Aorus Master to the list of boards
+using the ALC1220_FIXUP_GB_X570 quirk. This fixes both, the silent output
+and the no-audio after reboot from windows problems.
+
+This work has been tested by the folks over at the level1techs forum here:
+https://forum.level1techs.com/t/has-anybody-gotten-audio-working-in-linux-on-aorus-x570-master/154072
+
+Signed-off-by: Christian Lachner <gladiac@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220129113243.93068-3-gladiac@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -2159,6 +2159,7 @@ static void alc1220_fixup_gb_x570(struct
+ {
+       static const hda_nid_t conn1[] = { 0x0c };
+       static const struct coef_fw gb_x570_coefs[] = {
++              WRITE_COEF(0x07, 0x03c0),
+               WRITE_COEF(0x1a, 0x01c1),
+               WRITE_COEF(0x1b, 0x0202),
+               WRITE_COEF(0x43, 0x3005),
+@@ -2586,6 +2587,7 @@ static const struct snd_pci_quirk alc882
+       SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
+       SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_GB_X570),
+       SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950),
++      SND_PCI_QUIRK(0x1458, 0xa0d5, "Gigabyte X570S Aorus Master", ALC1220_FIXUP_GB_X570),
+       SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1462, 0x1229, "MSI-GP73", ALC1220_FIXUP_CLEVO_P950),
diff --git a/queue-5.16/alsa-usb-audio-correct-quirk-for-vf0770.patch b/queue-5.16/alsa-usb-audio-correct-quirk-for-vf0770.patch
new file mode 100644 (file)
index 0000000..024c52e
--- /dev/null
@@ -0,0 +1,44 @@
+From 4ee02e20893d2f9e951c7888f2284fa608ddaa35 Mon Sep 17 00:00:00 2001
+From: Jonas Hahnfeld <hahnjo@hahnjo.de>
+Date: Mon, 31 Jan 2022 19:35:16 +0100
+Subject: ALSA: usb-audio: Correct quirk for VF0770
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonas Hahnfeld <hahnjo@hahnjo.de>
+
+commit 4ee02e20893d2f9e951c7888f2284fa608ddaa35 upstream.
+
+This device provides both audio and video. The original quirk added in
+commit 48827e1d6af5 ("ALSA: usb-audio: Add quirk for VF0770") used
+USB_DEVICE to match the vendor and product ID. Depending on module order,
+if snd-usb-audio was asked first, it would match the entire device and
+uvcvideo wouldn't get to see it. Change the matching to USB_AUDIO_DEVICE
+to restore uvcvideo matching in all cases.
+
+Fixes: 48827e1d6af5 ("ALSA: usb-audio: Add quirk for VF0770")
+Reported-by: Jukka Heikintalo <heikintalo.jukka@gmail.com>
+Tested-by: Jukka Heikintalo <heikintalo.jukka@gmail.com>
+Reported-by: Paweł Susicki <pawel.susicki@gmail.com>
+Tested-by: Paweł Susicki <pawel.susicki@gmail.com>
+Cc: <stable@vger.kernel.org> # 5.4, 5.10, 5.14, 5.15
+Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
+Link: https://lore.kernel.org/r/20220131183516.61191-1-hahnjo@hahnjo.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/quirks-table.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -84,7 +84,7 @@
+  * combination.
+  */
+ {
+-      USB_DEVICE(0x041e, 0x4095),
++      USB_AUDIO_DEVICE(0x041e, 0x4095),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
diff --git a/queue-5.16/asoc-hdmi-codec-fix-oob-memory-accesses.patch b/queue-5.16/asoc-hdmi-codec-fix-oob-memory-accesses.patch
new file mode 100644 (file)
index 0000000..610dfba
--- /dev/null
@@ -0,0 +1,49 @@
+From 06feec6005c9d9500cd286ec440aabf8b2ddd94d Mon Sep 17 00:00:00 2001
+From: Dmitry Osipenko <digetx@gmail.com>
+Date: Wed, 12 Jan 2022 22:50:39 +0300
+Subject: ASoC: hdmi-codec: Fix OOB memory accesses
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+commit 06feec6005c9d9500cd286ec440aabf8b2ddd94d upstream.
+
+Correct size of iec_status array by changing it to the size of status
+array of the struct snd_aes_iec958. This fixes out-of-bounds slab
+read accesses made by memcpy() of the hdmi-codec driver. This problem
+is reported by KASAN.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Link: https://lore.kernel.org/r/20220112195039.1329-1-digetx@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/uapi/sound/asound.h   |    4 +++-
+ sound/soc/codecs/hdmi-codec.c |    2 +-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/include/uapi/sound/asound.h
++++ b/include/uapi/sound/asound.h
+@@ -56,8 +56,10 @@
+  *                                                                          *
+  ****************************************************************************/
++#define AES_IEC958_STATUS_SIZE                24
++
+ struct snd_aes_iec958 {
+-      unsigned char status[24];       /* AES/IEC958 channel status bits */
++      unsigned char status[AES_IEC958_STATUS_SIZE]; /* AES/IEC958 channel status bits */
+       unsigned char subcode[147];     /* AES/IEC958 subcode bits */
+       unsigned char pad;              /* nothing */
+       unsigned char dig_subframe[4];  /* AES/IEC958 subframe bits */
+--- a/sound/soc/codecs/hdmi-codec.c
++++ b/sound/soc/codecs/hdmi-codec.c
+@@ -277,7 +277,7 @@ struct hdmi_codec_priv {
+       bool busy;
+       struct snd_soc_jack *jack;
+       unsigned int jack_status;
+-      u8 iec_status[5];
++      u8 iec_status[AES_IEC958_STATUS_SIZE];
+ };
+ static const struct snd_soc_dapm_widget hdmi_widgets[] = {
diff --git a/queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw.patch b/queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw.patch
new file mode 100644 (file)
index 0000000..0afbe9a
--- /dev/null
@@ -0,0 +1,54 @@
+From 817f7c9335ec01e0f5e8caffc4f1dcd5e458a4c0 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 24 Jan 2022 15:32:51 +0000
+Subject: ASoC: ops: Reject out of bounds values in snd_soc_put_volsw()
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 817f7c9335ec01e0f5e8caffc4f1dcd5e458a4c0 upstream.
+
+We don't currently validate that the values being set are within the range
+we advertised to userspace as being valid, do so and reject any values
+that are out of range.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20220124153253.3548853-2-broonie@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/soc-ops.c |   18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -316,13 +316,27 @@ int snd_soc_put_volsw(struct snd_kcontro
+       if (sign_bit)
+               mask = BIT(sign_bit + 1) - 1;
+-      val = ((ucontrol->value.integer.value[0] + min) & mask);
++      val = ucontrol->value.integer.value[0];
++      if (mc->platform_max && val > mc->platform_max)
++              return -EINVAL;
++      if (val > max - min)
++              return -EINVAL;
++      if (val < 0)
++              return -EINVAL;
++      val = (val + min) & mask;
+       if (invert)
+               val = max - val;
+       val_mask = mask << shift;
+       val = val << shift;
+       if (snd_soc_volsw_is_stereo(mc)) {
+-              val2 = ((ucontrol->value.integer.value[1] + min) & mask);
++              val2 = ucontrol->value.integer.value[1];
++              if (mc->platform_max && val2 > mc->platform_max)
++                      return -EINVAL;
++              if (val2 > max - min)
++                      return -EINVAL;
++              if (val2 < 0)
++                      return -EINVAL;
++              val2 = (val2 + min) & mask;
+               if (invert)
+                       val2 = max - val2;
+               if (reg == reg2) {
diff --git a/queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw_sx.patch b/queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw_sx.patch
new file mode 100644 (file)
index 0000000..b9598a5
--- /dev/null
@@ -0,0 +1,41 @@
+From 4f1e50d6a9cf9c1b8c859d449b5031cacfa8404e Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 24 Jan 2022 15:32:52 +0000
+Subject: ASoC: ops: Reject out of bounds values in snd_soc_put_volsw_sx()
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 4f1e50d6a9cf9c1b8c859d449b5031cacfa8404e upstream.
+
+We don't currently validate that the values being set are within the range
+we advertised to userspace as being valid, do so and reject any values
+that are out of range.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20220124153253.3548853-3-broonie@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/soc-ops.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -423,8 +423,15 @@ int snd_soc_put_volsw_sx(struct snd_kcon
+       int err = 0;
+       unsigned int val, val_mask;
++      val = ucontrol->value.integer.value[0];
++      if (mc->platform_max && val > mc->platform_max)
++              return -EINVAL;
++      if (val > max - min)
++              return -EINVAL;
++      if (val < 0)
++              return -EINVAL;
+       val_mask = mask << shift;
+-      val = (ucontrol->value.integer.value[0] + min) & mask;
++      val = (val + min) & mask;
+       val = val << shift;
+       err = snd_soc_component_update_bits(component, reg, val_mask, val);
diff --git a/queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_xr_sx.patch b/queue-5.16/asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_xr_sx.patch
new file mode 100644 (file)
index 0000000..d38a3c4
--- /dev/null
@@ -0,0 +1,33 @@
+From 4cf28e9ae6e2e11a044be1bcbcfa1b0d8675fe4d Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 24 Jan 2022 15:32:53 +0000
+Subject: ASoC: ops: Reject out of bounds values in snd_soc_put_xr_sx()
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 4cf28e9ae6e2e11a044be1bcbcfa1b0d8675fe4d upstream.
+
+We don't currently validate that the values being set are within the range
+we advertised to userspace as being valid, do so and reject any values
+that are out of range.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20220124153253.3548853-4-broonie@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/soc-ops.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -879,6 +879,8 @@ int snd_soc_put_xr_sx(struct snd_kcontro
+       long val = ucontrol->value.integer.value[0];
+       unsigned int i;
++      if (val < mc->min || val > mc->max)
++              return -EINVAL;
+       if (invert)
+               val = max - val;
+       val &= mask;
diff --git a/queue-5.16/ata-libata-core-introduce-ata_horkage_no_log_dir-horkage.patch b/queue-5.16/ata-libata-core-introduce-ata_horkage_no_log_dir-horkage.patch
new file mode 100644 (file)
index 0000000..59799b6
--- /dev/null
@@ -0,0 +1,65 @@
+From ac9f0c810684a1b161c18eb4b91ce84cbc13c91d Mon Sep 17 00:00:00 2001
+From: Anton Lundin <glance@acc.umu.se>
+Date: Thu, 3 Feb 2022 10:41:35 +0100
+Subject: ata: libata-core: Introduce ATA_HORKAGE_NO_LOG_DIR horkage
+
+From: Anton Lundin <glance@acc.umu.se>
+
+commit ac9f0c810684a1b161c18eb4b91ce84cbc13c91d upstream.
+
+06f6c4c6c3e8 ("ata: libata: add missing ata_identify_page_supported() calls")
+introduced additional calls to ata_identify_page_supported(), thus also
+adding indirectly accesses to the device log directory log page through
+ata_log_supported(). Reading this log page causes SATADOM-ML 3ME devices
+to lock up.
+
+Introduce the horkage flag ATA_HORKAGE_NO_LOG_DIR to prevent accesses to
+the log directory in ata_log_supported() and add a blacklist entry
+with this flag for "SATADOM-ML 3ME" devices.
+
+Fixes: 636f6e2af4fb ("libata: add horkage for missing Identify Device log")
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Anton Lundin <glance@acc.umu.se>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-core.c |   10 ++++++++++
+ include/linux/libata.h    |    1 +
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -2043,6 +2043,9 @@ static bool ata_log_supported(struct ata
+ {
+       struct ata_port *ap = dev->link->ap;
++      if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR)
++              return false;
++
+       if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1))
+               return false;
+       return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false;
+@@ -4123,6 +4126,13 @@ static const struct ata_blacklist_entry
+       { "WDC WD3000JD-*",             NULL,   ATA_HORKAGE_WD_BROKEN_LPM },
+       { "WDC WD3200JD-*",             NULL,   ATA_HORKAGE_WD_BROKEN_LPM },
++      /*
++       * This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY
++       * log page is accessed. Ensure we never ask for this log page with
++       * these devices.
++       */
++      { "SATADOM-ML 3ME",             NULL,   ATA_HORKAGE_NO_LOG_DIR },
++
+       /* End Marker */
+       { }
+ };
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -428,6 +428,7 @@ enum {
+       ATA_HORKAGE_MAX_TRIM_128M = (1 << 26),  /* Limit max trim size to 128M */
+       ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27),  /* Disable NCQ on ATI chipset */
+       ATA_HORKAGE_NO_ID_DEV_LOG = (1 << 28),  /* Identify device log missing */
++      ATA_HORKAGE_NO_LOG_DIR  = (1 << 29),    /* Do not read log directory */
+        /* DMA mask for user DMA control: User visible values; DO NOT
+           renumber */
diff --git a/queue-5.16/audit-improve-audit-queue-handling-when-audit-1-on-cmdline.patch b/queue-5.16/audit-improve-audit-queue-handling-when-audit-1-on-cmdline.patch
new file mode 100644 (file)
index 0000000..d8c6977
--- /dev/null
@@ -0,0 +1,207 @@
+From f26d04331360d42dbd6b58448bd98e4edbfbe1c5 Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Thu, 13 Jan 2022 18:54:38 -0500
+Subject: audit: improve audit queue handling when "audit=1" on cmdline
+
+From: Paul Moore <paul@paul-moore.com>
+
+commit f26d04331360d42dbd6b58448bd98e4edbfbe1c5 upstream.
+
+When an admin enables audit at early boot via the "audit=1" kernel
+command line the audit queue behavior is slightly different; the
+audit subsystem goes to greater lengths to avoid dropping records,
+which unfortunately can result in problems when the audit daemon is
+forcibly stopped for an extended period of time.
+
+This patch makes a number of changes designed to improve the audit
+queuing behavior so that leaving the audit daemon in a stopped state
+for an extended period does not cause a significant impact to the
+system.
+
+- kauditd_send_queue() is now limited to looping through the
+  passed queue only once per call.  This not only prevents the
+  function from looping indefinitely when records are returned
+  to the current queue, it also allows any recovery handling in
+  kauditd_thread() to take place when kauditd_send_queue()
+  returns.
+
+- Transient netlink send errors seen as -EAGAIN now cause the
+  record to be returned to the retry queue instead of going to
+  the hold queue.  The intention of the hold queue is to store,
+  perhaps for an extended period of time, the events which led
+  up to the audit daemon going offline.  The retry queue remains
+  a temporary queue intended to protect against transient issues
+  between the kernel and the audit daemon.
+
+- The retry queue is now limited by the audit_backlog_limit
+  setting, the same as the other queues.  This allows admins
+  to bound the size of all of the audit queues on the system.
+
+- kauditd_rehold_skb() now returns records to the end of the
+  hold queue to ensure ordering is preserved in the face of
+  recent changes to kauditd_send_queue().
+
+Cc: stable@vger.kernel.org
+Fixes: 5b52330bbfe63 ("audit: fix auditd/kernel connection state tracking")
+Fixes: f4b3ee3c85551 ("audit: improve robustness of the audit queue handling")
+Reported-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Tested-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/audit.c |   62 +++++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 43 insertions(+), 19 deletions(-)
+
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -541,20 +541,22 @@ static void kauditd_printk_skb(struct sk
+ /**
+  * kauditd_rehold_skb - Handle a audit record send failure in the hold queue
+  * @skb: audit record
++ * @error: error code (unused)
+  *
+  * Description:
+  * This should only be used by the kauditd_thread when it fails to flush the
+  * hold queue.
+  */
+-static void kauditd_rehold_skb(struct sk_buff *skb)
++static void kauditd_rehold_skb(struct sk_buff *skb, __always_unused int error)
+ {
+-      /* put the record back in the queue at the same place */
+-      skb_queue_head(&audit_hold_queue, skb);
++      /* put the record back in the queue */
++      skb_queue_tail(&audit_hold_queue, skb);
+ }
+ /**
+  * kauditd_hold_skb - Queue an audit record, waiting for auditd
+  * @skb: audit record
++ * @error: error code
+  *
+  * Description:
+  * Queue the audit record, waiting for an instance of auditd.  When this
+@@ -564,19 +566,31 @@ static void kauditd_rehold_skb(struct sk
+  * and queue it, if we have room.  If we want to hold on to the record, but we
+  * don't have room, record a record lost message.
+  */
+-static void kauditd_hold_skb(struct sk_buff *skb)
++static void kauditd_hold_skb(struct sk_buff *skb, int error)
+ {
+       /* at this point it is uncertain if we will ever send this to auditd so
+        * try to send the message via printk before we go any further */
+       kauditd_printk_skb(skb);
+       /* can we just silently drop the message? */
+-      if (!audit_default) {
+-              kfree_skb(skb);
+-              return;
++      if (!audit_default)
++              goto drop;
++
++      /* the hold queue is only for when the daemon goes away completely,
++       * not -EAGAIN failures; if we are in a -EAGAIN state requeue the
++       * record on the retry queue unless it's full, in which case drop it
++       */
++      if (error == -EAGAIN) {
++              if (!audit_backlog_limit ||
++                  skb_queue_len(&audit_retry_queue) < audit_backlog_limit) {
++                      skb_queue_tail(&audit_retry_queue, skb);
++                      return;
++              }
++              audit_log_lost("kauditd retry queue overflow");
++              goto drop;
+       }
+-      /* if we have room, queue the message */
++      /* if we have room in the hold queue, queue the message */
+       if (!audit_backlog_limit ||
+           skb_queue_len(&audit_hold_queue) < audit_backlog_limit) {
+               skb_queue_tail(&audit_hold_queue, skb);
+@@ -585,24 +599,32 @@ static void kauditd_hold_skb(struct sk_b
+       /* we have no other options - drop the message */
+       audit_log_lost("kauditd hold queue overflow");
++drop:
+       kfree_skb(skb);
+ }
+ /**
+  * kauditd_retry_skb - Queue an audit record, attempt to send again to auditd
+  * @skb: audit record
++ * @error: error code (unused)
+  *
+  * Description:
+  * Not as serious as kauditd_hold_skb() as we still have a connected auditd,
+  * but for some reason we are having problems sending it audit records so
+  * queue the given record and attempt to resend.
+  */
+-static void kauditd_retry_skb(struct sk_buff *skb)
++static void kauditd_retry_skb(struct sk_buff *skb, __always_unused int error)
+ {
+-      /* NOTE: because records should only live in the retry queue for a
+-       * short period of time, before either being sent or moved to the hold
+-       * queue, we don't currently enforce a limit on this queue */
+-      skb_queue_tail(&audit_retry_queue, skb);
++      if (!audit_backlog_limit ||
++          skb_queue_len(&audit_retry_queue) < audit_backlog_limit) {
++              skb_queue_tail(&audit_retry_queue, skb);
++              return;
++      }
++
++      /* we have to drop the record, send it via printk as a last effort */
++      kauditd_printk_skb(skb);
++      audit_log_lost("kauditd retry queue overflow");
++      kfree_skb(skb);
+ }
+ /**
+@@ -640,7 +662,7 @@ static void auditd_reset(const struct au
+       /* flush the retry queue to the hold queue, but don't touch the main
+        * queue since we need to process that normally for multicast */
+       while ((skb = skb_dequeue(&audit_retry_queue)))
+-              kauditd_hold_skb(skb);
++              kauditd_hold_skb(skb, -ECONNREFUSED);
+ }
+ /**
+@@ -714,16 +736,18 @@ static int kauditd_send_queue(struct soc
+                             struct sk_buff_head *queue,
+                             unsigned int retry_limit,
+                             void (*skb_hook)(struct sk_buff *skb),
+-                            void (*err_hook)(struct sk_buff *skb))
++                            void (*err_hook)(struct sk_buff *skb, int error))
+ {
+       int rc = 0;
+-      struct sk_buff *skb;
++      struct sk_buff *skb = NULL;
++      struct sk_buff *skb_tail;
+       unsigned int failed = 0;
+       /* NOTE: kauditd_thread takes care of all our locking, we just use
+        *       the netlink info passed to us (e.g. sk and portid) */
+-      while ((skb = skb_dequeue(queue))) {
++      skb_tail = skb_peek_tail(queue);
++      while ((skb != skb_tail) && (skb = skb_dequeue(queue))) {
+               /* call the skb_hook for each skb we touch */
+               if (skb_hook)
+                       (*skb_hook)(skb);
+@@ -731,7 +755,7 @@ static int kauditd_send_queue(struct soc
+               /* can we send to anyone via unicast? */
+               if (!sk) {
+                       if (err_hook)
+-                              (*err_hook)(skb);
++                              (*err_hook)(skb, -ECONNREFUSED);
+                       continue;
+               }
+@@ -745,7 +769,7 @@ retry:
+                           rc == -ECONNREFUSED || rc == -EPERM) {
+                               sk = NULL;
+                               if (err_hook)
+-                                      (*err_hook)(skb);
++                                      (*err_hook)(skb, rc);
+                               if (rc == -EAGAIN)
+                                       rc = 0;
+                               /* continue to drain the queue */
diff --git a/queue-5.16/block-bio-integrity-advance-seed-correctly-for-larger-interval-sizes.patch b/queue-5.16/block-bio-integrity-advance-seed-correctly-for-larger-interval-sizes.patch
new file mode 100644 (file)
index 0000000..27b13e7
--- /dev/null
@@ -0,0 +1,43 @@
+From b13e0c71856817fca67159b11abac350e41289f5 Mon Sep 17 00:00:00 2001
+From: "Martin K. Petersen" <martin.petersen@oracle.com>
+Date: Thu, 3 Feb 2022 22:42:09 -0500
+Subject: block: bio-integrity: Advance seed correctly for larger interval sizes
+
+From: Martin K. Petersen <martin.petersen@oracle.com>
+
+commit b13e0c71856817fca67159b11abac350e41289f5 upstream.
+
+Commit 309a62fa3a9e ("bio-integrity: bio_integrity_advance must update
+integrity seed") added code to update the integrity seed value when
+advancing a bio. However, it failed to take into account that the
+integrity interval might be larger than the 512-byte block layer
+sector size. This broke bio splitting on PI devices with 4KB logical
+blocks.
+
+The seed value should be advanced by bio_integrity_intervals() and not
+the number of sectors.
+
+Cc: Dmitry Monakhov <dmonakhov@openvz.org>
+Cc: stable@vger.kernel.org
+Fixes: 309a62fa3a9e ("bio-integrity: bio_integrity_advance must update integrity seed")
+Tested-by: Dmitry Ivanov <dmitry.ivanov2@hpe.com>
+Reported-by: Alexey Lyashkov <alexey.lyashkov@hpe.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Link: https://lore.kernel.org/r/20220204034209.4193-1-martin.petersen@oracle.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/bio-integrity.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/block/bio-integrity.c
++++ b/block/bio-integrity.c
+@@ -373,7 +373,7 @@ void bio_integrity_advance(struct bio *b
+       struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
+       unsigned bytes = bio_integrity_bytes(bi, bytes_done >> 9);
+-      bip->bip_iter.bi_sector += bytes_done >> 9;
++      bip->bip_iter.bi_sector += bio_integrity_intervals(bi, bytes_done >> 9);
+       bvec_iter_advance(bip->bip_vec, &bip->bip_iter, bytes);
+ }
diff --git a/queue-5.16/btrfs-don-t-start-transaction-for-scrub-if-the-fs-is-mounted-read-only.patch b/queue-5.16/btrfs-don-t-start-transaction-for-scrub-if-the-fs-is-mounted-read-only.patch
new file mode 100644 (file)
index 0000000..8eb1b07
--- /dev/null
@@ -0,0 +1,84 @@
+From 2d192fc4c1abeb0d04d1c8cd54405ff4a0b0255b Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 16 Dec 2021 19:47:35 +0800
+Subject: btrfs: don't start transaction for scrub if the fs is mounted read-only
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 2d192fc4c1abeb0d04d1c8cd54405ff4a0b0255b upstream.
+
+[BUG]
+The following super simple script would crash btrfs at unmount time, if
+CONFIG_BTRFS_ASSERT() is set.
+
+ mkfs.btrfs -f $dev
+ mount $dev $mnt
+ xfs_io -f -c "pwrite 0 4k" $mnt/file
+ umount $mnt
+ mount -r ro $dev $mnt
+ btrfs scrub start -Br $mnt
+ umount $mnt
+
+This will trigger the following ASSERT() introduced by commit
+0a31daa4b602 ("btrfs: add assertion for empty list of transactions at
+late stage of umount").
+
+That patch is definitely not the cause, it just makes enough noise for
+developers.
+
+[CAUSE]
+We will start transaction for the following call chain during scrub:
+
+  scrub_enumerate_chunks()
+  |- btrfs_inc_block_group_ro()
+     |- btrfs_join_transaction()
+
+However for RO mount, there is no running transaction at all, thus
+btrfs_join_transaction() will start a new transaction.
+
+Furthermore, since it's read-only mount, btrfs_sync_fs() will not call
+btrfs_commit_super() to commit the new but empty transaction.
+
+And leads to the ASSERT().
+
+The bug has been there for a long time. Only the new ASSERT() makes it
+noisy enough to be noticed.
+
+[FIX]
+For read-only scrub on read-only mount, there is no need to start a
+transaction nor to allocate new chunks in btrfs_inc_block_group_ro().
+
+Just do extra read-only mount check in btrfs_inc_block_group_ro(), and
+if it's read-only, skip all chunk allocation and go inc_block_group_ro()
+directly.
+
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/block-group.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2547,6 +2547,19 @@ int btrfs_inc_block_group_ro(struct btrf
+       int ret;
+       bool dirty_bg_running;
++      /*
++       * This can only happen when we are doing read-only scrub on read-only
++       * mount.
++       * In that case we should not start a new transaction on read-only fs.
++       * Thus here we skip all chunk allocations.
++       */
++      if (sb_rdonly(fs_info->sb)) {
++              mutex_lock(&fs_info->ro_block_group_mutex);
++              ret = inc_block_group_ro(cache, 0);
++              mutex_unlock(&fs_info->ro_block_group_mutex);
++              return ret;
++      }
++
+       do {
+               trans = btrfs_join_transaction(fs_info->extent_root);
+               if (IS_ERR(trans))
diff --git a/queue-5.16/btrfs-fix-deadlock-between-quota-disable-and-qgroup-rescan-worker.patch b/queue-5.16/btrfs-fix-deadlock-between-quota-disable-and-qgroup-rescan-worker.patch
new file mode 100644 (file)
index 0000000..1b4becc
--- /dev/null
@@ -0,0 +1,305 @@
+From e804861bd4e69cc5fe1053eedcb024982dde8e48 Mon Sep 17 00:00:00 2001
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Date: Thu, 20 Jan 2022 20:09:16 +0900
+Subject: btrfs: fix deadlock between quota disable and qgroup rescan worker
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+commit e804861bd4e69cc5fe1053eedcb024982dde8e48 upstream.
+
+Quota disable ioctl starts a transaction before waiting for the qgroup
+rescan worker completes. However, this wait can be infinite and results
+in deadlock because of circular dependency among the quota disable
+ioctl, the qgroup rescan worker and the other task with transaction such
+as block group relocation task.
+
+The deadlock happens with the steps following:
+
+1) Task A calls ioctl to disable quota. It starts a transaction and
+   waits for qgroup rescan worker completes.
+2) Task B such as block group relocation task starts a transaction and
+   joins to the transaction that task A started. Then task B commits to
+   the transaction. In this commit, task B waits for a commit by task A.
+3) Task C as the qgroup rescan worker starts its job and starts a
+   transaction. In this transaction start, task C waits for completion
+   of the transaction that task A started and task B committed.
+
+This deadlock was found with fstests test case btrfs/115 and a zoned
+null_blk device. The test case enables and disables quota, and the
+block group reclaim was triggered during the quota disable by chance.
+The deadlock was also observed by running quota enable and disable in
+parallel with 'btrfs balance' command on regular null_blk devices.
+
+An example report of the deadlock:
+
+  [372.469894] INFO: task kworker/u16:6:103 blocked for more than 122 seconds.
+  [372.479944]       Not tainted 5.16.0-rc8 #7
+  [372.485067] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+  [372.493898] task:kworker/u16:6   state:D stack:    0 pid:  103 ppid:     2 flags:0x00004000
+  [372.503285] Workqueue: btrfs-qgroup-rescan btrfs_work_helper [btrfs]
+  [372.510782] Call Trace:
+  [372.514092]  <TASK>
+  [372.521684]  __schedule+0xb56/0x4850
+  [372.530104]  ? io_schedule_timeout+0x190/0x190
+  [372.538842]  ? lockdep_hardirqs_on+0x7e/0x100
+  [372.547092]  ? _raw_spin_unlock_irqrestore+0x3e/0x60
+  [372.555591]  schedule+0xe0/0x270
+  [372.561894]  btrfs_commit_transaction+0x18bb/0x2610 [btrfs]
+  [372.570506]  ? btrfs_apply_pending_changes+0x50/0x50 [btrfs]
+  [372.578875]  ? free_unref_page+0x3f2/0x650
+  [372.585484]  ? finish_wait+0x270/0x270
+  [372.591594]  ? release_extent_buffer+0x224/0x420 [btrfs]
+  [372.599264]  btrfs_qgroup_rescan_worker+0xc13/0x10c0 [btrfs]
+  [372.607157]  ? lock_release+0x3a9/0x6d0
+  [372.613054]  ? btrfs_qgroup_account_extent+0xda0/0xda0 [btrfs]
+  [372.620960]  ? do_raw_spin_lock+0x11e/0x250
+  [372.627137]  ? rwlock_bug.part.0+0x90/0x90
+  [372.633215]  ? lock_is_held_type+0xe4/0x140
+  [372.639404]  btrfs_work_helper+0x1ae/0xa90 [btrfs]
+  [372.646268]  process_one_work+0x7e9/0x1320
+  [372.652321]  ? lock_release+0x6d0/0x6d0
+  [372.658081]  ? pwq_dec_nr_in_flight+0x230/0x230
+  [372.664513]  ? rwlock_bug.part.0+0x90/0x90
+  [372.670529]  worker_thread+0x59e/0xf90
+  [372.676172]  ? process_one_work+0x1320/0x1320
+  [372.682440]  kthread+0x3b9/0x490
+  [372.687550]  ? _raw_spin_unlock_irq+0x24/0x50
+  [372.693811]  ? set_kthread_struct+0x100/0x100
+  [372.700052]  ret_from_fork+0x22/0x30
+  [372.705517]  </TASK>
+  [372.709747] INFO: task btrfs-transacti:2347 blocked for more than 123 seconds.
+  [372.729827]       Not tainted 5.16.0-rc8 #7
+  [372.745907] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+  [372.767106] task:btrfs-transacti state:D stack:    0 pid: 2347 ppid:     2 flags:0x00004000
+  [372.787776] Call Trace:
+  [372.801652]  <TASK>
+  [372.812961]  __schedule+0xb56/0x4850
+  [372.830011]  ? io_schedule_timeout+0x190/0x190
+  [372.852547]  ? lockdep_hardirqs_on+0x7e/0x100
+  [372.871761]  ? _raw_spin_unlock_irqrestore+0x3e/0x60
+  [372.886792]  schedule+0xe0/0x270
+  [372.901685]  wait_current_trans+0x22c/0x310 [btrfs]
+  [372.919743]  ? btrfs_put_transaction+0x3d0/0x3d0 [btrfs]
+  [372.938923]  ? finish_wait+0x270/0x270
+  [372.959085]  ? join_transaction+0xc75/0xe30 [btrfs]
+  [372.977706]  start_transaction+0x938/0x10a0 [btrfs]
+  [372.997168]  transaction_kthread+0x19d/0x3c0 [btrfs]
+  [373.013021]  ? btrfs_cleanup_transaction.isra.0+0xfc0/0xfc0 [btrfs]
+  [373.031678]  kthread+0x3b9/0x490
+  [373.047420]  ? _raw_spin_unlock_irq+0x24/0x50
+  [373.064645]  ? set_kthread_struct+0x100/0x100
+  [373.078571]  ret_from_fork+0x22/0x30
+  [373.091197]  </TASK>
+  [373.105611] INFO: task btrfs:3145 blocked for more than 123 seconds.
+  [373.114147]       Not tainted 5.16.0-rc8 #7
+  [373.120401] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+  [373.130393] task:btrfs           state:D stack:    0 pid: 3145 ppid:  3141 flags:0x00004000
+  [373.140998] Call Trace:
+  [373.145501]  <TASK>
+  [373.149654]  __schedule+0xb56/0x4850
+  [373.155306]  ? io_schedule_timeout+0x190/0x190
+  [373.161965]  ? lockdep_hardirqs_on+0x7e/0x100
+  [373.168469]  ? _raw_spin_unlock_irqrestore+0x3e/0x60
+  [373.175468]  schedule+0xe0/0x270
+  [373.180814]  wait_for_commit+0x104/0x150 [btrfs]
+  [373.187643]  ? test_and_set_bit+0x20/0x20 [btrfs]
+  [373.194772]  ? kmem_cache_free+0x124/0x550
+  [373.201191]  ? btrfs_put_transaction+0x69/0x3d0 [btrfs]
+  [373.208738]  ? finish_wait+0x270/0x270
+  [373.214704]  ? __btrfs_end_transaction+0x347/0x7b0 [btrfs]
+  [373.222342]  btrfs_commit_transaction+0x44d/0x2610 [btrfs]
+  [373.230233]  ? join_transaction+0x255/0xe30 [btrfs]
+  [373.237334]  ? btrfs_record_root_in_trans+0x4d/0x170 [btrfs]
+  [373.245251]  ? btrfs_apply_pending_changes+0x50/0x50 [btrfs]
+  [373.253296]  relocate_block_group+0x105/0xc20 [btrfs]
+  [373.260533]  ? mutex_lock_io_nested+0x1270/0x1270
+  [373.267516]  ? btrfs_wait_nocow_writers+0x85/0x180 [btrfs]
+  [373.275155]  ? merge_reloc_roots+0x710/0x710 [btrfs]
+  [373.283602]  ? btrfs_wait_ordered_extents+0xd30/0xd30 [btrfs]
+  [373.291934]  ? kmem_cache_free+0x124/0x550
+  [373.298180]  btrfs_relocate_block_group+0x35c/0x930 [btrfs]
+  [373.306047]  btrfs_relocate_chunk+0x85/0x210 [btrfs]
+  [373.313229]  btrfs_balance+0x12f4/0x2d20 [btrfs]
+  [373.320227]  ? lock_release+0x3a9/0x6d0
+  [373.326206]  ? btrfs_relocate_chunk+0x210/0x210 [btrfs]
+  [373.333591]  ? lock_is_held_type+0xe4/0x140
+  [373.340031]  ? rcu_read_lock_sched_held+0x3f/0x70
+  [373.346910]  btrfs_ioctl_balance+0x548/0x700 [btrfs]
+  [373.354207]  btrfs_ioctl+0x7f2/0x71b0 [btrfs]
+  [373.360774]  ? lockdep_hardirqs_on_prepare+0x410/0x410
+  [373.367957]  ? lockdep_hardirqs_on_prepare+0x410/0x410
+  [373.375327]  ? btrfs_ioctl_get_supported_features+0x20/0x20 [btrfs]
+  [373.383841]  ? find_held_lock+0x2c/0x110
+  [373.389993]  ? lock_release+0x3a9/0x6d0
+  [373.395828]  ? mntput_no_expire+0xf7/0xad0
+  [373.402083]  ? lock_is_held_type+0xe4/0x140
+  [373.408249]  ? vfs_fileattr_set+0x9f0/0x9f0
+  [373.414486]  ? selinux_file_ioctl+0x349/0x4e0
+  [373.420938]  ? trace_raw_output_lock+0xb4/0xe0
+  [373.427442]  ? selinux_inode_getsecctx+0x80/0x80
+  [373.434224]  ? lockdep_hardirqs_on+0x7e/0x100
+  [373.440660]  ? force_qs_rnp+0x2a0/0x6b0
+  [373.446534]  ? lock_is_held_type+0x9b/0x140
+  [373.452763]  ? __blkcg_punt_bio_submit+0x1b0/0x1b0
+  [373.459732]  ? security_file_ioctl+0x50/0x90
+  [373.466089]  __x64_sys_ioctl+0x127/0x190
+  [373.472022]  do_syscall_64+0x3b/0x90
+  [373.477513]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+  [373.484823] RIP: 0033:0x7f8f4af7e2bb
+  [373.490493] RSP: 002b:00007ffcbf936178 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+  [373.500197] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f8f4af7e2bb
+  [373.509451] RDX: 00007ffcbf936220 RSI: 00000000c4009420 RDI: 0000000000000003
+  [373.518659] RBP: 00007ffcbf93774a R08: 0000000000000013 R09: 00007f8f4b02d4e0
+  [373.527872] R10: 00007f8f4ae87740 R11: 0000000000000246 R12: 0000000000000001
+  [373.537222] R13: 00007ffcbf936220 R14: 0000000000000000 R15: 0000000000000002
+  [373.546506]  </TASK>
+  [373.550878] INFO: task btrfs:3146 blocked for more than 123 seconds.
+  [373.559383]       Not tainted 5.16.0-rc8 #7
+  [373.565748] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+  [373.575748] task:btrfs           state:D stack:    0 pid: 3146 ppid:  2168 flags:0x00000000
+  [373.586314] Call Trace:
+  [373.590846]  <TASK>
+  [373.595121]  __schedule+0xb56/0x4850
+  [373.600901]  ? __lock_acquire+0x23db/0x5030
+  [373.607176]  ? io_schedule_timeout+0x190/0x190
+  [373.613954]  schedule+0xe0/0x270
+  [373.619157]  schedule_timeout+0x168/0x220
+  [373.625170]  ? usleep_range_state+0x150/0x150
+  [373.631653]  ? mark_held_locks+0x9e/0xe0
+  [373.637767]  ? do_raw_spin_lock+0x11e/0x250
+  [373.643993]  ? lockdep_hardirqs_on_prepare+0x17b/0x410
+  [373.651267]  ? _raw_spin_unlock_irq+0x24/0x50
+  [373.657677]  ? lockdep_hardirqs_on+0x7e/0x100
+  [373.664103]  wait_for_completion+0x163/0x250
+  [373.670437]  ? bit_wait_timeout+0x160/0x160
+  [373.676585]  btrfs_quota_disable+0x176/0x9a0 [btrfs]
+  [373.683979]  ? btrfs_quota_enable+0x12f0/0x12f0 [btrfs]
+  [373.691340]  ? down_write+0xd0/0x130
+  [373.696880]  ? down_write_killable+0x150/0x150
+  [373.703352]  btrfs_ioctl+0x3945/0x71b0 [btrfs]
+  [373.710061]  ? find_held_lock+0x2c/0x110
+  [373.716192]  ? lock_release+0x3a9/0x6d0
+  [373.722047]  ? __handle_mm_fault+0x23cd/0x3050
+  [373.728486]  ? btrfs_ioctl_get_supported_features+0x20/0x20 [btrfs]
+  [373.737032]  ? set_pte+0x6a/0x90
+  [373.742271]  ? do_raw_spin_unlock+0x55/0x1f0
+  [373.748506]  ? lock_is_held_type+0xe4/0x140
+  [373.754792]  ? vfs_fileattr_set+0x9f0/0x9f0
+  [373.761083]  ? selinux_file_ioctl+0x349/0x4e0
+  [373.767521]  ? selinux_inode_getsecctx+0x80/0x80
+  [373.774247]  ? __up_read+0x182/0x6e0
+  [373.780026]  ? count_memcg_events.constprop.0+0x46/0x60
+  [373.787281]  ? up_write+0x460/0x460
+  [373.792932]  ? security_file_ioctl+0x50/0x90
+  [373.799232]  __x64_sys_ioctl+0x127/0x190
+  [373.805237]  do_syscall_64+0x3b/0x90
+  [373.810947]  entry_SYSCALL_64_after_hwframe+0x44/0xae
+  [373.818102] RIP: 0033:0x7f1383ea02bb
+  [373.823847] RSP: 002b:00007fffeb4d71f8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
+  [373.833641] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1383ea02bb
+  [373.842961] RDX: 00007fffeb4d7210 RSI: 00000000c0109428 RDI: 0000000000000003
+  [373.852179] RBP: 0000000000000003 R08: 0000000000000003 R09: 0000000000000078
+  [373.861408] R10: 00007f1383daec78 R11: 0000000000000202 R12: 00007fffeb4d874a
+  [373.870647] R13: 0000000000493099 R14: 0000000000000001 R15: 0000000000000000
+  [373.879838]  </TASK>
+  [373.884018]
+               Showing all locks held in the system:
+  [373.894250] 3 locks held by kworker/4:1/58:
+  [373.900356] 1 lock held by khungtaskd/63:
+  [373.906333]  #0: ffffffff8945ff60 (rcu_read_lock){....}-{1:2}, at: debug_show_all_locks+0x53/0x260
+  [373.917307] 3 locks held by kworker/u16:6/103:
+  [373.923938]  #0: ffff888127b4f138 ((wq_completion)btrfs-qgroup-rescan){+.+.}-{0:0}, at: process_one_work+0x712/0x1320
+  [373.936555]  #1: ffff88810b817dd8 ((work_completion)(&work->normal_work)){+.+.}-{0:0}, at: process_one_work+0x73f/0x1320
+  [373.951109]  #2: ffff888102dd4650 (sb_internal#2){.+.+}-{0:0}, at: btrfs_qgroup_rescan_worker+0x1f6/0x10c0 [btrfs]
+  [373.964027] 2 locks held by less/1803:
+  [373.969982]  #0: ffff88813ed56098 (&tty->ldisc_sem){++++}-{0:0}, at: tty_ldisc_ref_wait+0x24/0x80
+  [373.981295]  #1: ffffc90000b3b2e8 (&ldata->atomic_read_lock){+.+.}-{3:3}, at: n_tty_read+0x9e2/0x1060
+  [373.992969] 1 lock held by btrfs-transacti/2347:
+  [373.999893]  #0: ffff88813d4887a8 (&fs_info->transaction_kthread_mutex){+.+.}-{3:3}, at: transaction_kthread+0xe3/0x3c0 [btrfs]
+  [374.015872] 3 locks held by btrfs/3145:
+  [374.022298]  #0: ffff888102dd4460 (sb_writers#18){.+.+}-{0:0}, at: btrfs_ioctl_balance+0xc3/0x700 [btrfs]
+  [374.034456]  #1: ffff88813d48a0a0 (&fs_info->reclaim_bgs_lock){+.+.}-{3:3}, at: btrfs_balance+0xfe5/0x2d20 [btrfs]
+  [374.047646]  #2: ffff88813d488838 (&fs_info->cleaner_mutex){+.+.}-{3:3}, at: btrfs_relocate_block_group+0x354/0x930 [btrfs]
+  [374.063295] 4 locks held by btrfs/3146:
+  [374.069647]  #0: ffff888102dd4460 (sb_writers#18){.+.+}-{0:0}, at: btrfs_ioctl+0x38b1/0x71b0 [btrfs]
+  [374.081601]  #1: ffff88813d488bb8 (&fs_info->subvol_sem){+.+.}-{3:3}, at: btrfs_ioctl+0x38fd/0x71b0 [btrfs]
+  [374.094283]  #2: ffff888102dd4650 (sb_internal#2){.+.+}-{0:0}, at: btrfs_quota_disable+0xc8/0x9a0 [btrfs]
+  [374.106885]  #3: ffff88813d489800 (&fs_info->qgroup_ioctl_lock){+.+.}-{3:3}, at: btrfs_quota_disable+0xd5/0x9a0 [btrfs]
+
+  [374.126780] =============================================
+
+To avoid the deadlock, wait for the qgroup rescan worker to complete
+before starting the transaction for the quota disable ioctl. Clear
+BTRFS_FS_QUOTA_ENABLE flag before the wait and the transaction to
+request the worker to complete. On transaction start failure, set the
+BTRFS_FS_QUOTA_ENABLE flag again. These BTRFS_FS_QUOTA_ENABLE flag
+changes can be done safely since the function btrfs_quota_disable is not
+called concurrently because of fs_info->subvol_sem.
+
+Also check the BTRFS_FS_QUOTA_ENABLE flag in qgroup_rescan_init to avoid
+another qgroup rescan worker to start after the previous qgroup worker
+completed.
+
+CC: stable@vger.kernel.org # 5.4+
+Suggested-by: Nikolay Borisov <nborisov@suse.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/qgroup.c |   21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1185,9 +1185,24 @@ int btrfs_quota_disable(struct btrfs_fs_
+       struct btrfs_trans_handle *trans = NULL;
+       int ret = 0;
++      /*
++       * We need to have subvol_sem write locked, to prevent races between
++       * concurrent tasks trying to disable quotas, because we will unlock
++       * and relock qgroup_ioctl_lock across BTRFS_FS_QUOTA_ENABLED changes.
++       */
++      lockdep_assert_held_write(&fs_info->subvol_sem);
++
+       mutex_lock(&fs_info->qgroup_ioctl_lock);
+       if (!fs_info->quota_root)
+               goto out;
++
++      /*
++       * Request qgroup rescan worker to complete and wait for it. This wait
++       * must be done before transaction start for quota disable since it may
++       * deadlock with transaction by the qgroup rescan worker.
++       */
++      clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
++      btrfs_qgroup_wait_for_completion(fs_info, false);
+       mutex_unlock(&fs_info->qgroup_ioctl_lock);
+       /*
+@@ -1205,14 +1220,13 @@ int btrfs_quota_disable(struct btrfs_fs_
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               trans = NULL;
++              set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
+               goto out;
+       }
+       if (!fs_info->quota_root)
+               goto out;
+-      clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
+-      btrfs_qgroup_wait_for_completion(fs_info, false);
+       spin_lock(&fs_info->qgroup_lock);
+       quota_root = fs_info->quota_root;
+       fs_info->quota_root = NULL;
+@@ -3380,6 +3394,9 @@ qgroup_rescan_init(struct btrfs_fs_info
+                       btrfs_warn(fs_info,
+                       "qgroup rescan init failed, qgroup is not enabled");
+                       ret = -EINVAL;
++              } else if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
++                      /* Quota disable is in progress */
++                      ret = -EBUSY;
+               }
+               if (ret) {
diff --git a/queue-5.16/btrfs-fix-use-after-free-after-failure-to-create-a-snapshot.patch b/queue-5.16/btrfs-fix-use-after-free-after-failure-to-create-a-snapshot.patch
new file mode 100644 (file)
index 0000000..27adaa5
--- /dev/null
@@ -0,0 +1,125 @@
+From 28b21c558a3753171097193b6f6602a94169093a Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Fri, 21 Jan 2022 15:44:39 +0000
+Subject: btrfs: fix use-after-free after failure to create a snapshot
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 28b21c558a3753171097193b6f6602a94169093a upstream.
+
+At ioctl.c:create_snapshot(), we allocate a pending snapshot structure and
+then attach it to the transaction's list of pending snapshots. After that
+we call btrfs_commit_transaction(), and if that returns an error we jump
+to 'fail' label, where we kfree() the pending snapshot structure. This can
+result in a later use-after-free of the pending snapshot:
+
+1) We allocated the pending snapshot and added it to the transaction's
+   list of pending snapshots;
+
+2) We call btrfs_commit_transaction(), and it fails either at the first
+   call to btrfs_run_delayed_refs() or btrfs_start_dirty_block_groups().
+   In both cases, we don't abort the transaction and we release our
+   transaction handle. We jump to the 'fail' label and free the pending
+   snapshot structure. We return with the pending snapshot still in the
+   transaction's list;
+
+3) Another task commits the transaction. This time there's no error at
+   all, and then during the transaction commit it accesses a pointer
+   to the pending snapshot structure that the snapshot creation task
+   has already freed, resulting in a user-after-free.
+
+This issue could actually be detected by smatch, which produced the
+following warning:
+
+  fs/btrfs/ioctl.c:843 create_snapshot() warn: '&pending_snapshot->list' not removed from list
+
+So fix this by not having the snapshot creation ioctl directly add the
+pending snapshot to the transaction's list. Instead add the pending
+snapshot to the transaction handle, and then at btrfs_commit_transaction()
+we add the snapshot to the list only when we can guarantee that any error
+returned after that point will result in a transaction abort, in which
+case the ioctl code can safely free the pending snapshot and no one can
+access it anymore.
+
+CC: stable@vger.kernel.org # 5.10+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/ioctl.c       |    5 +----
+ fs/btrfs/transaction.c |   24 ++++++++++++++++++++++++
+ fs/btrfs/transaction.h |    2 ++
+ 3 files changed, 27 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -779,10 +779,7 @@ static int create_snapshot(struct btrfs_
+               goto fail;
+       }
+-      spin_lock(&fs_info->trans_lock);
+-      list_add(&pending_snapshot->list,
+-               &trans->transaction->pending_snapshots);
+-      spin_unlock(&fs_info->trans_lock);
++      trans->pending_snapshot = pending_snapshot;
+       ret = btrfs_commit_transaction(trans);
+       if (ret)
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -2032,6 +2032,27 @@ static inline void btrfs_wait_delalloc_f
+               btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1);
+ }
++/*
++ * Add a pending snapshot associated with the given transaction handle to the
++ * respective handle. This must be called after the transaction commit started
++ * and while holding fs_info->trans_lock.
++ * This serves to guarantee a caller of btrfs_commit_transaction() that it can
++ * safely free the pending snapshot pointer in case btrfs_commit_transaction()
++ * returns an error.
++ */
++static void add_pending_snapshot(struct btrfs_trans_handle *trans)
++{
++      struct btrfs_transaction *cur_trans = trans->transaction;
++
++      if (!trans->pending_snapshot)
++              return;
++
++      lockdep_assert_held(&trans->fs_info->trans_lock);
++      ASSERT(cur_trans->state >= TRANS_STATE_COMMIT_START);
++
++      list_add(&trans->pending_snapshot->list, &cur_trans->pending_snapshots);
++}
++
+ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+ {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
+@@ -2105,6 +2126,8 @@ int btrfs_commit_transaction(struct btrf
+       if (cur_trans->state >= TRANS_STATE_COMMIT_START) {
+               enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED;
++              add_pending_snapshot(trans);
++
+               spin_unlock(&fs_info->trans_lock);
+               refcount_inc(&cur_trans->use_count);
+@@ -2195,6 +2218,7 @@ int btrfs_commit_transaction(struct btrf
+        * COMMIT_DOING so make sure to wait for num_writers to == 1 again.
+        */
+       spin_lock(&fs_info->trans_lock);
++      add_pending_snapshot(trans);
+       cur_trans->state = TRANS_STATE_COMMIT_DOING;
+       spin_unlock(&fs_info->trans_lock);
+       wait_event(cur_trans->writer_wait,
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -123,6 +123,8 @@ struct btrfs_trans_handle {
+       struct btrfs_transaction *transaction;
+       struct btrfs_block_rsv *block_rsv;
+       struct btrfs_block_rsv *orig_rsv;
++      /* Set by a task that wants to create a snapshot. */
++      struct btrfs_pending_snapshot *pending_snapshot;
+       refcount_t use_count;
+       unsigned int type;
+       /*
diff --git a/queue-5.16/cifs-fix-workstation_name-for-multiuser-mounts.patch b/queue-5.16/cifs-fix-workstation_name-for-multiuser-mounts.patch
new file mode 100644 (file)
index 0000000..d288e5d
--- /dev/null
@@ -0,0 +1,61 @@
+From d3b331fb51f326d5b5326010bf2b5841bb86cdc6 Mon Sep 17 00:00:00 2001
+From: Ryan Bair <ryandbair@gmail.com>
+Date: Wed, 22 Dec 2021 11:04:05 -0500
+Subject: cifs: fix workstation_name for multiuser mounts
+
+From: Ryan Bair <ryandbair@gmail.com>
+
+commit d3b331fb51f326d5b5326010bf2b5841bb86cdc6 upstream.
+
+Set workstation_name from the master_tcon for multiuser mounts.
+
+Just in case, protect size_of_ntlmssp_blob against a NULL workstation_name.
+
+Fixes: 49bd49f983b5 ("cifs: send workstation name during ntlmssp session setup")
+Cc: stable@vger.kernel.org # 5.16
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Ryan Bair <ryandbair@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/connect.c |   13 +++++++++++++
+ fs/cifs/sess.c    |    6 +++++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1945,6 +1945,19 @@ cifs_set_cifscreds(struct smb3_fs_contex
+               }
+       }
++      ctx->workstation_name = kstrdup(ses->workstation_name, GFP_KERNEL);
++      if (!ctx->workstation_name) {
++              cifs_dbg(FYI, "Unable to allocate memory for workstation_name\n");
++              rc = -ENOMEM;
++              kfree(ctx->username);
++              ctx->username = NULL;
++              kfree_sensitive(ctx->password);
++              ctx->password = NULL;
++              kfree(ctx->domainname);
++              ctx->domainname = NULL;
++              goto out_key_put;
++      }
++
+ out_key_put:
+       up_read(&key->sem);
+       key_put(key);
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -675,7 +675,11 @@ static int size_of_ntlmssp_blob(struct c
+       else
+               sz += sizeof(__le16);
+-      sz += sizeof(__le16) * strnlen(ses->workstation_name, CIFS_MAX_WORKSTATION_LEN);
++      if (ses->workstation_name)
++              sz += sizeof(__le16) * strnlen(ses->workstation_name,
++                      CIFS_MAX_WORKSTATION_LEN);
++      else
++              sz += sizeof(__le16);
+       return sz;
+ }
diff --git a/queue-5.16/dma-buf-heaps-fix-potential-spectre-v1-gadget.patch b/queue-5.16/dma-buf-heaps-fix-potential-spectre-v1-gadget.patch
new file mode 100644 (file)
index 0000000..5f37e53
--- /dev/null
@@ -0,0 +1,44 @@
+From 92c4cfaee6872038563c5b6f2e8e613f9d84d47d Mon Sep 17 00:00:00 2001
+From: Jordy Zomer <jordy@pwning.systems>
+Date: Sat, 29 Jan 2022 16:06:04 +0100
+Subject: dma-buf: heaps: Fix potential spectre v1 gadget
+
+From: Jordy Zomer <jordy@pwning.systems>
+
+commit 92c4cfaee6872038563c5b6f2e8e613f9d84d47d upstream.
+
+It appears like nr could be a Spectre v1 gadget as it's supplied by a
+user and used as an array index. Prevent the contents
+of kernel memory from being leaked to userspace via speculative
+execution by using array_index_nospec.
+
+Signed-off-by: Jordy Zomer <jordy@pwning.systems>
+Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
+Cc: <stable@vger.kernel.org> # v5.6+
+Acked-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+ [sumits: added fixes and cc: stable tags]
+Link: https://patchwork.freedesktop.org/patch/msgid/20220129150604.3461652-1-jordy@pwning.systems
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma-buf/dma-heap.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/dma-buf/dma-heap.c
++++ b/drivers/dma-buf/dma-heap.c
+@@ -14,6 +14,7 @@
+ #include <linux/xarray.h>
+ #include <linux/list.h>
+ #include <linux/slab.h>
++#include <linux/nospec.h>
+ #include <linux/uaccess.h>
+ #include <linux/syscalls.h>
+ #include <linux/dma-heap.h>
+@@ -135,6 +136,7 @@ static long dma_heap_ioctl(struct file *
+       if (nr >= ARRAY_SIZE(dma_heap_ioctl_cmds))
+               return -EINVAL;
++      nr = array_index_nospec(nr, ARRAY_SIZE(dma_heap_ioctl_cmds));
+       /* Get the kernel ioctl cmd that matches */
+       kcmd = dma_heap_ioctl_cmds[nr];
diff --git a/queue-5.16/drm-amd-display-force-link_rate-as-link_rate_rbr2-for-2018-15-apple-retina-panels.patch b/queue-5.16/drm-amd-display-force-link_rate-as-link_rate_rbr2-for-2018-15-apple-retina-panels.patch
new file mode 100644 (file)
index 0000000..61d6d9a
--- /dev/null
@@ -0,0 +1,64 @@
+From 30fbce374745a9c6af93c775a5ac49a97f822fda Mon Sep 17 00:00:00 2001
+From: Aun-Ali Zaidi <admin@kodeit.net>
+Date: Sat, 29 Jan 2022 05:49:55 +0000
+Subject: drm/amd/display: Force link_rate as LINK_RATE_RBR2 for 2018 15" Apple Retina panels
+
+From: Aun-Ali Zaidi <admin@kodeit.net>
+
+commit 30fbce374745a9c6af93c775a5ac49a97f822fda upstream.
+
+The eDP link rate reported by the DP_MAX_LINK_RATE dpcd register (0xa) is
+contradictory to the highest rate supported reported by
+EDID (0xc = LINK_RATE_RBR2). The effects of this compounded with commit
+'4a8ca46bae8a ("drm/amd/display: Default max bpc to 16 for eDP")' results
+in no display modes being found and a dark panel.
+
+For now, simply force the maximum supported link rate for the eDP attached
+2018 15" Apple Retina panels.
+
+Additionally, we must also check the firmware revision since the device ID
+reported by the DPCD is identical to that of the more capable 16,1,
+incorrectly quirking it. We also use said firmware check to quirk the
+refreshed 15,1 models with Vega graphics as they use a slightly newer
+firmware version.
+
+Tested-by: Aun-Ali Zaidi <admin@kodeit.net>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Aun-Ali Zaidi <admin@kodeit.net>
+Signed-off-by: Aditya Garg <gargaditya08@live.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c |   20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+@@ -4730,6 +4730,26 @@ static bool retrieve_link_cap(struct dc_
+               dp_hw_fw_revision.ieee_fw_rev,
+               sizeof(dp_hw_fw_revision.ieee_fw_rev));
++      /* Quirk for Apple MBP 2018 15" Retina panels: wrong DP_MAX_LINK_RATE */
++      {
++              uint8_t str_mbp_2018[] = { 101, 68, 21, 103, 98, 97 };
++              uint8_t fwrev_mbp_2018[] = { 7, 4 };
++              uint8_t fwrev_mbp_2018_vega[] = { 8, 4 };
++
++              /* We also check for the firmware revision as 16,1 models have an
++               * identical device id and are incorrectly quirked otherwise.
++               */
++              if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
++                  !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2018,
++                           sizeof(str_mbp_2018)) &&
++                  (!memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018,
++                           sizeof(fwrev_mbp_2018)) ||
++                  !memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018_vega,
++                           sizeof(fwrev_mbp_2018_vega)))) {
++                      link->reported_link_cap.link_rate = LINK_RATE_RBR2;
++              }
++      }
++
+       memset(&link->dpcd_caps.dsc_caps, '\0',
+                       sizeof(link->dpcd_caps.dsc_caps));
+       memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
diff --git a/queue-5.16/drm-amd-display-update-watermark-values-for-dcn301.patch b/queue-5.16/drm-amd-display-update-watermark-values-for-dcn301.patch
new file mode 100644 (file)
index 0000000..00c722a
--- /dev/null
@@ -0,0 +1,68 @@
+From 2d8ae25d233767171942a9fba5fd8f4a620996be Mon Sep 17 00:00:00 2001
+From: Agustin Gutierrez <agustin.gutierrez@amd.com>
+Date: Fri, 28 Jan 2022 17:51:53 -0500
+Subject: drm/amd/display: Update watermark values for DCN301
+
+From: Agustin Gutierrez <agustin.gutierrez@amd.com>
+
+commit 2d8ae25d233767171942a9fba5fd8f4a620996be upstream.
+
+[Why]
+There is underflow / visual corruption DCN301, for high
+bandwidth MST DSC configurations such as 2x1440p144 or 2x4k60.
+
+[How]
+Use up-to-date watermark values for DCN301.
+
+Reviewed-by: Zhan Liu <zhan.liu@amd.com>
+Signed-off-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c |   16 ++++++-------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
+@@ -582,32 +582,32 @@ static struct wm_table lpddr5_wm_table =
+                       .wm_inst = WM_A,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.65333,
+-                      .sr_exit_time_us = 7.95,
+-                      .sr_enter_plus_exit_time_us = 9,
++                      .sr_exit_time_us = 13.5,
++                      .sr_enter_plus_exit_time_us = 16.5,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_B,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.65333,
+-                      .sr_exit_time_us = 9.82,
+-                      .sr_enter_plus_exit_time_us = 11.196,
++                      .sr_exit_time_us = 13.5,
++                      .sr_enter_plus_exit_time_us = 16.5,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_C,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.65333,
+-                      .sr_exit_time_us = 9.89,
+-                      .sr_enter_plus_exit_time_us = 11.24,
++                      .sr_exit_time_us = 13.5,
++                      .sr_enter_plus_exit_time_us = 16.5,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_D,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.65333,
+-                      .sr_exit_time_us = 9.748,
+-                      .sr_enter_plus_exit_time_us = 11.102,
++                      .sr_exit_time_us = 13.5,
++                      .sr_enter_plus_exit_time_us = 16.5,
+                       .valid = true,
+               },
+       }
diff --git a/queue-5.16/drm-amd-display-watermark-latencies-is-not-enough-on-dcn31.patch b/queue-5.16/drm-amd-display-watermark-latencies-is-not-enough-on-dcn31.patch
new file mode 100644 (file)
index 0000000..8c0c084
--- /dev/null
@@ -0,0 +1,87 @@
+From f5fa54f45ab41cbb1f99b1208f49554132ffb207 Mon Sep 17 00:00:00 2001
+From: Paul Hsieh <paul.hsieh@amd.com>
+Date: Fri, 28 Jan 2022 22:03:57 +0800
+Subject: drm/amd/display: watermark latencies is not enough on DCN31
+
+From: Paul Hsieh <paul.hsieh@amd.com>
+
+commit f5fa54f45ab41cbb1f99b1208f49554132ffb207 upstream.
+
+[Why]
+The original latencies were causing underflow in some modes.
+Resolution: 2880x1620@60p when HDR enable
+
+[How]
+1. Replace with the up-to-date watermark values based on new measurments
+2. Correct the ddr_wm_table name to DDR5 on DCN31
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Stylon Wang <stylon.wang@amd.com>
+Signed-off-by: Paul Hsieh <paul.hsieh@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c |   20 +++++------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+@@ -329,38 +329,38 @@ static struct clk_bw_params dcn31_bw_par
+ };
+-static struct wm_table ddr4_wm_table = {
++static struct wm_table ddr5_wm_table = {
+       .entries = {
+               {
+                       .wm_inst = WM_A,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+-                      .sr_exit_time_us = 6.09,
+-                      .sr_enter_plus_exit_time_us = 7.14,
++                      .sr_exit_time_us = 9,
++                      .sr_enter_plus_exit_time_us = 11,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_B,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+-                      .sr_exit_time_us = 10.12,
+-                      .sr_enter_plus_exit_time_us = 11.48,
++                      .sr_exit_time_us = 9,
++                      .sr_enter_plus_exit_time_us = 11,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_C,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+-                      .sr_exit_time_us = 10.12,
+-                      .sr_enter_plus_exit_time_us = 11.48,
++                      .sr_exit_time_us = 9,
++                      .sr_enter_plus_exit_time_us = 11,
+                       .valid = true,
+               },
+               {
+                       .wm_inst = WM_D,
+                       .wm_type = WM_TYPE_PSTATE_CHG,
+                       .pstate_latency_us = 11.72,
+-                      .sr_exit_time_us = 10.12,
+-                      .sr_enter_plus_exit_time_us = 11.48,
++                      .sr_exit_time_us = 9,
++                      .sr_enter_plus_exit_time_us = 11,
+                       .valid = true,
+               },
+       }
+@@ -688,7 +688,7 @@ void dcn31_clk_mgr_construct(
+               if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType) {
+                       dcn31_bw_params.wm_table = lpddr5_wm_table;
+               } else {
+-                      dcn31_bw_params.wm_table = ddr4_wm_table;
++                      dcn31_bw_params.wm_table = ddr5_wm_table;
+               }
+               /* Saved clocks configured at boot for debug purposes */
+                dcn31_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info);
diff --git a/queue-5.16/drm-amd-pm-correct-the-mgpufanboost-support-for-beige-goby.patch b/queue-5.16/drm-amd-pm-correct-the-mgpufanboost-support-for-beige-goby.patch
new file mode 100644 (file)
index 0000000..64d0aaf
--- /dev/null
@@ -0,0 +1,42 @@
+From 3ec5586b4699cfb75cdfa09425e11d121db40773 Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Mon, 24 Jan 2022 13:40:35 +0800
+Subject: drm/amd/pm: correct the MGpuFanBoost support for Beige Goby
+
+From: Evan Quan <evan.quan@amd.com>
+
+commit 3ec5586b4699cfb75cdfa09425e11d121db40773 upstream.
+
+The existing way cannot handle Beige Goby well as a different
+PPTable data structure(PPTable_beige_goby_t instead of PPTable_t)
+is used there.
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -3681,14 +3681,14 @@ static ssize_t sienna_cichlid_get_gpu_me
+ static int sienna_cichlid_enable_mgpu_fan_boost(struct smu_context *smu)
+ {
+-      struct smu_table_context *table_context = &smu->smu_table;
+-      PPTable_t *smc_pptable = table_context->driver_pptable;
++      uint16_t *mgpu_fan_boost_limit_rpm;
++      GET_PPTABLE_MEMBER(MGpuFanBoostLimitRpm, &mgpu_fan_boost_limit_rpm);
+       /*
+        * Skip the MGpuFanBoost setting for those ASICs
+        * which do not support it
+        */
+-      if (!smc_pptable->MGpuFanBoostLimitRpm)
++      if (*mgpu_fan_boost_limit_rpm == 0)
+               return 0;
+       return smu_cmn_send_smc_msg_with_param(smu,
diff --git a/queue-5.16/drm-amdgpu-fix-a-potential-gpu-hang-on-cyan-skillfish.patch b/queue-5.16/drm-amdgpu-fix-a-potential-gpu-hang-on-cyan-skillfish.patch
new file mode 100644 (file)
index 0000000..bf77c4c
--- /dev/null
@@ -0,0 +1,36 @@
+From bca52455a3c07922ee976714b00563a13a29ab15 Mon Sep 17 00:00:00 2001
+From: Lang Yu <Lang.Yu@amd.com>
+Date: Fri, 28 Jan 2022 18:24:53 +0800
+Subject: drm/amdgpu: fix a potential GPU hang on cyan skillfish
+
+From: Lang Yu <Lang.Yu@amd.com>
+
+commit bca52455a3c07922ee976714b00563a13a29ab15 upstream.
+
+We observed a GPU hang when querying GMC CG state(i.e.,
+cat amdgpu_pm_info) on cyan skillfish. Acctually, cyan
+skillfish doesn't support any CG features.
+
+Just prevent it from accessing GMC CG registers.
+
+Signed-off-by: Lang Yu <Lang.Yu@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+@@ -1147,6 +1147,9 @@ static void gmc_v10_0_get_clockgating_st
+ {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
++      if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 3))
++              return;
++
+       adev->mmhub.funcs->get_clockgating(adev, flags);
+       if (adev->ip_versions[ATHUB_HWIP][0] >= IP_VERSION(2, 1, 0))
diff --git a/queue-5.16/drm-i915-adlp-fix-typec-phy-ready-status-readout.patch b/queue-5.16/drm-i915-adlp-fix-typec-phy-ready-status-readout.patch
new file mode 100644 (file)
index 0000000..0c24b78
--- /dev/null
@@ -0,0 +1,48 @@
+From 3c6f13ad723e7206f03bb2752b01d18202b7fc9d Mon Sep 17 00:00:00 2001
+From: Imre Deak <imre.deak@intel.com>
+Date: Wed, 26 Jan 2022 12:43:56 +0200
+Subject: drm/i915/adlp: Fix TypeC PHY-ready status readout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Imre Deak <imre.deak@intel.com>
+
+commit 3c6f13ad723e7206f03bb2752b01d18202b7fc9d upstream.
+
+The TCSS_DDI_STATUS register is indexed by tc_port not by the FIA port
+index, fix this up. This only caused an issue on TC#3/4 ports in legacy
+mode, as in all other cases the two indices either match (on TC#1/2) or
+the TCSS_DDI_STATUS_READY flag is set regardless of something being
+connected or not (on TC#1/2/3/4 in dp-alt and tbt-alt modes).
+
+Reported-and-tested-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
+Fixes: 55ce306c2aa1 ("drm/i915/adl_p: Implement TC sequences")
+Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4698
+Cc: José Roberto de Souza <jose.souza@intel.com>
+Cc: <stable@vger.kernel.org> # v5.14+
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220126104356.2022975-1-imre.deak@intel.com
+(cherry picked from commit 516b33460c5bee78b2055637b0547bdb0e6af754)
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/display/intel_tc.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_tc.c
++++ b/drivers/gpu/drm/i915/display/intel_tc.c
+@@ -345,10 +345,11 @@ static bool icl_tc_phy_status_complete(s
+ static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port)
+ {
+       struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
++      enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
+       struct intel_uncore *uncore = &i915->uncore;
+       u32 val;
+-      val = intel_uncore_read(uncore, TCSS_DDI_STATUS(dig_port->tc_phy_fia_idx));
++      val = intel_uncore_read(uncore, TCSS_DDI_STATUS(tc_port));
+       if (val == 0xffffffff) {
+               drm_dbg_kms(&i915->drm,
+                           "Port %s: PHY in TCCOLD, assuming not complete\n",
diff --git a/queue-5.16/drm-i915-disable-dsb-usage-for-now.patch b/queue-5.16/drm-i915-disable-dsb-usage-for-now.patch
new file mode 100644 (file)
index 0000000..7797569
--- /dev/null
@@ -0,0 +1,57 @@
+From 99510e1afb4863a225207146bd988064c5fd0629 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 14 Oct 2021 21:18:56 +0300
+Subject: drm/i915: Disable DSB usage for now
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 99510e1afb4863a225207146bd988064c5fd0629 upstream.
+
+Turns out the DSB has trouble correctly loading the gamma LUT.
+From a cursory look maybe like some entries do not load
+properly, or they get loaded with some gibberish. Unfortunately
+our current kms_color/etc. tests do not seem to catch this.
+
+I had a brief look at the generated DSB batch and it looked
+correct. Tried a few quick tricks like writing the index
+register twice/etc. but didn't see any improvement.
+Also tried switching to the 10bit gamma mode in case
+there is yet another issue with the multi-segment mode, but
+even the 10bit mode was showing issues.
+
+Switching to mmio fixes all of it. I suppose one theory is that
+maybe the DSB bangs on the LUT too quickly and it can't keep up
+and instead some data either gets dropped or corrupted. To confirm
+that someone should try to slow down the DSB's progress a bit.
+Another thought was that maybe the LUT has crappy dual porting
+and you get contention if you try to load it during active
+scanout. But why then would the mmio path work, unless it's
+just sufficiently slow?
+
+Whatever the case, this is currently busted so let's disable
+it until we get to the root of the problem.
+
+Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3916
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211014181856.17581-2-ville.syrjala@linux.intel.com
+Reviewed-by: Uma Shankar <uma.shankar@intel.com>
+Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/i915_pci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_pci.c
++++ b/drivers/gpu/drm/i915/i915_pci.c
+@@ -866,7 +866,7 @@ static const struct intel_device_info js
+       TGL_CURSOR_OFFSETS, \
+       .has_global_mocs = 1, \
+       .has_pxp = 1, \
+-      .display.has_dsb = 1
++      .display.has_dsb = 0 /* FIXME: LUT load is broken with DSB */
+ static const struct intel_device_info tgl_info = {
+       GEN12_FEATURES,
diff --git a/queue-5.16/drm-nouveau-fix-off-by-one-in-bios-boundary-checking.patch b/queue-5.16/drm-nouveau-fix-off-by-one-in-bios-boundary-checking.patch
new file mode 100644 (file)
index 0000000..7c0f037
--- /dev/null
@@ -0,0 +1,42 @@
+From 1b777d4d9e383d2744fc9b3a09af6ec1893c8b1a Mon Sep 17 00:00:00 2001
+From: Nick Lopez <github@glowingmonkey.org>
+Date: Sat, 22 Jan 2022 01:19:06 -0700
+Subject: drm/nouveau: fix off by one in BIOS boundary checking
+
+From: Nick Lopez <github@glowingmonkey.org>
+
+commit 1b777d4d9e383d2744fc9b3a09af6ec1893c8b1a upstream.
+
+Bounds checking when parsing init scripts embedded in the BIOS reject
+access to the last byte. This causes driver initialization to fail on
+Apple eMac's with GeForce 2 MX GPUs, leaving the system with no working
+console.
+
+This is probably only seen on OpenFirmware machines like PowerPC Macs
+because the BIOS image provided by OF is only the used parts of the ROM,
+not a power-of-two blocks read from PCI directly so PCs always have
+empty bytes at the end that are never accessed.
+
+Signed-off-by: Nick Lopez <github@glowingmonkey.org>
+Fixes: 4d4e9907ff572 ("drm/nouveau/bios: guard against out-of-bounds accesses to image")
+Cc: <stable@vger.kernel.org> # v4.10+
+Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
+Reviewed-by: Karol Herbst <kherbst@redhat.com>
+Signed-off-by: Karol Herbst <kherbst@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220122081906.2633061-1-github@glowingmonkey.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
+@@ -38,7 +38,7 @@ nvbios_addr(struct nvkm_bios *bios, u32
+               *addr += bios->imaged_addr;
+       }
+-      if (unlikely(*addr + size >= bios->size)) {
++      if (unlikely(*addr + size > bios->size)) {
+               nvkm_error(&bios->subdev, "OOB %d %08x %08x\n", size, p, *addr);
+               return false;
+       }
diff --git a/queue-5.16/fbcon-add-option-to-enable-legacy-hardware-acceleration.patch b/queue-5.16/fbcon-add-option-to-enable-legacy-hardware-acceleration.patch
new file mode 100644 (file)
index 0000000..8a1a2bc
--- /dev/null
@@ -0,0 +1,373 @@
+From a3f781a9d6114c1d1e01defb7aa234dec45d2a5f Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Wed, 2 Feb 2022 14:55:31 +0100
+Subject: fbcon: Add option to enable legacy hardware acceleration
+
+From: Helge Deller <deller@gmx.de>
+
+commit a3f781a9d6114c1d1e01defb7aa234dec45d2a5f upstream.
+
+Add a config option CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION to
+enable bitblt and fillrect hardware acceleration in the framebuffer
+console. If disabled, such acceleration will not be used, even if it is
+supported by the graphics hardware driver.
+
+If you plan to use DRM as your main graphics output system, you should
+disable this option since it will prevent compiling in code which isn't
+used later on when DRM takes over.
+
+For all other configurations, e.g. if none of your graphic cards support
+DRM (yet), DRM isn't available for your architecture, or you can't be
+sure that the graphic card in the target system will support DRM, you
+most likely want to enable this option.
+
+In the non-accelerated case (e.g. when DRM is used), the inlined
+fb_scrollmode() function is hardcoded to return SCROLL_REDRAW and as such the
+compiler is able to optimize much unneccesary code away.
+
+In this v3 patch version I additionally changed the GETVYRES() and GETVXRES()
+macros to take a pointer to the fbcon_display struct. This fixes the build when
+console rotation is enabled and helps the compiler again to optimize out code.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-4-deller@gmx.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/console/Kconfig           |   20 ++++++++++++++++
+ drivers/video/fbdev/core/fbcon.c        |   39 ++++++++++++++++++++++----------
+ drivers/video/fbdev/core/fbcon.h        |   15 +++++++++++-
+ drivers/video/fbdev/core/fbcon_ccw.c    |   10 ++++----
+ drivers/video/fbdev/core/fbcon_cw.c     |   10 ++++----
+ drivers/video/fbdev/core/fbcon_rotate.h |    4 +--
+ drivers/video/fbdev/core/fbcon_ud.c     |   20 ++++++++--------
+ 7 files changed, 84 insertions(+), 34 deletions(-)
+
+--- a/drivers/video/console/Kconfig
++++ b/drivers/video/console/Kconfig
+@@ -78,6 +78,26 @@ config FRAMEBUFFER_CONSOLE
+       help
+         Low-level framebuffer-based console driver.
++config FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
++      bool "Enable legacy fbcon hardware acceleration code"
++      depends on FRAMEBUFFER_CONSOLE
++      default y if PARISC
++      default n
++      help
++        This option enables the fbcon (framebuffer text-based) hardware
++        acceleration for graphics drivers which were written for the fbdev
++        graphics interface.
++
++        On modern machines, on mainstream machines (like x86-64) or when
++        using a modern Linux distribution those fbdev drivers usually aren't used.
++        So enabling this option wouldn't have any effect, which is why you want
++        to disable this option on such newer machines.
++
++        If you compile this kernel for older machines which still require the
++        fbdev drivers, you may want to say Y.
++
++        If unsure, select n.
++
+ config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
+        bool "Map the console to the primary display device"
+        depends on FRAMEBUFFER_CONSOLE
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -1136,11 +1136,13 @@ static void fbcon_init(struct vc_data *v
+       ops->graphics = 0;
++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
+       if ((cap & FBINFO_HWACCEL_COPYAREA) &&
+           !(cap & FBINFO_HWACCEL_DISABLED))
+               p->scrollmode = SCROLL_MOVE;
+       else /* default to something safe */
+               p->scrollmode = SCROLL_REDRAW;
++#endif
+       /*
+        *  ++guenther: console.c:vc_allocate() relies on initializing
+@@ -1705,7 +1707,7 @@ static bool fbcon_scroll(struct vc_data
+                       count = vc->vc_rows;
+               if (logo_shown >= 0)
+                       goto redraw_up;
+-              switch (p->scrollmode) {
++              switch (fb_scrollmode(p)) {
+               case SCROLL_MOVE:
+                       fbcon_redraw_blit(vc, info, p, t, b - t - count,
+                                    count);
+@@ -1795,7 +1797,7 @@ static bool fbcon_scroll(struct vc_data
+                       count = vc->vc_rows;
+               if (logo_shown >= 0)
+                       goto redraw_down;
+-              switch (p->scrollmode) {
++              switch (fb_scrollmode(p)) {
+               case SCROLL_MOVE:
+                       fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
+                                    -count);
+@@ -1946,12 +1948,12 @@ static void fbcon_bmove_rec(struct vc_da
+                  height, width);
+ }
+-static void updatescrollmode(struct fbcon_display *p,
++static void updatescrollmode_accel(struct fbcon_display *p,
+                                       struct fb_info *info,
+                                       struct vc_data *vc)
+ {
++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
+       struct fbcon_ops *ops = info->fbcon_par;
+-      int fh = vc->vc_font.height;
+       int cap = info->flags;
+       u16 t = 0;
+       int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
+@@ -1972,12 +1974,6 @@ static void updatescrollmode(struct fbco
+       int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
+               !(cap & FBINFO_HWACCEL_DISABLED);
+-      p->vrows = vyres/fh;
+-      if (yres > (fh * (vc->vc_rows + 1)))
+-              p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
+-      if ((yres % fh) && (vyres % fh < yres % fh))
+-              p->vrows--;
+-
+       if (good_wrap || good_pan) {
+               if (reading_fast || fast_copyarea)
+                       p->scrollmode = good_wrap ?
+@@ -1991,6 +1987,27 @@ static void updatescrollmode(struct fbco
+               else
+                       p->scrollmode = SCROLL_REDRAW;
+       }
++#endif
++}
++
++static void updatescrollmode(struct fbcon_display *p,
++                                      struct fb_info *info,
++                                      struct vc_data *vc)
++{
++      struct fbcon_ops *ops = info->fbcon_par;
++      int fh = vc->vc_font.height;
++      int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
++      int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
++                                 info->var.xres_virtual);
++
++      p->vrows = vyres/fh;
++      if (yres > (fh * (vc->vc_rows + 1)))
++              p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
++      if ((yres % fh) && (vyres % fh < yres % fh))
++              p->vrows--;
++
++      /* update scrollmode in case hardware acceleration is used */
++      updatescrollmode_accel(p, info, vc);
+ }
+ #define PITCH(w) (((w) + 7) >> 3)
+@@ -2148,7 +2165,7 @@ static int fbcon_switch(struct vc_data *
+       updatescrollmode(p, info, vc);
+-      switch (p->scrollmode) {
++      switch (fb_scrollmode(p)) {
+       case SCROLL_WRAP_MOVE:
+               scrollback_phys_max = p->vrows - vc->vc_rows;
+               break;
+--- a/drivers/video/fbdev/core/fbcon.h
++++ b/drivers/video/fbdev/core/fbcon.h
+@@ -29,7 +29,9 @@ struct fbcon_display {
+     /* Filled in by the low-level console driver */
+     const u_char *fontdata;
+     int userfont;                   /* != 0 if fontdata kmalloc()ed */
+-    u_short scrollmode;             /* Scroll Method */
++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
++    u_short scrollmode;             /* Scroll Method, use fb_scrollmode() */
++#endif
+     u_short inverse;                /* != 0 text black on white as default */
+     short yscroll;                  /* Hardware scrolling */
+     int vrows;                      /* number of virtual rows */
+@@ -208,6 +210,17 @@ static inline int attr_col_ec(int shift,
+ #define SCROLL_REDRAW    0x004
+ #define SCROLL_PAN_REDRAW  0x005
++static inline u_short fb_scrollmode(struct fbcon_display *fb)
++{
++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
++      return fb->scrollmode;
++#else
++      /* hardcoded to SCROLL_REDRAW if acceleration was disabled. */
++      return SCROLL_REDRAW;
++#endif
++}
++
++
+ #ifdef CONFIG_FB_TILEBLITTING
+ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
+ #endif
+--- a/drivers/video/fbdev/core/fbcon_ccw.c
++++ b/drivers/video/fbdev/core/fbcon_ccw.c
+@@ -65,7 +65,7 @@ static void ccw_bmove(struct vc_data *vc
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_copyarea area;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
+       area.sx = sy * vc->vc_font.height;
+       area.sy = vyres - ((sx + width) * vc->vc_font.width);
+@@ -83,7 +83,7 @@ static void ccw_clear(struct vc_data *vc
+       struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_fillrect region;
+       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
+       region.color = attr_bgcol_ec(bgshift,vc,info);
+       region.dx = sy * vc->vc_font.height;
+@@ -140,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc
+       u32 cnt, pitch, size;
+       u32 attribute = get_attribute(info, scr_readw(s));
+       u8 *dst, *buf = NULL;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -229,7 +229,7 @@ static void ccw_cursor(struct vc_data *v
+       int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
+       int err = 1, dx, dy;
+       char *src;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -387,7 +387,7 @@ static int ccw_update_start(struct fb_in
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       u32 yoffset;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
+       int err;
+       yoffset = (vyres - info->var.yres) - ops->var.xoffset;
+--- a/drivers/video/fbdev/core/fbcon_cw.c
++++ b/drivers/video/fbdev/core/fbcon_cw.c
+@@ -50,7 +50,7 @@ static void cw_bmove(struct vc_data *vc,
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_copyarea area;
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       area.sx = vxres - ((sy + height) * vc->vc_font.height);
+       area.sy = sx * vc->vc_font.width;
+@@ -68,7 +68,7 @@ static void cw_clear(struct vc_data *vc,
+       struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_fillrect region;
+       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       region.color = attr_bgcol_ec(bgshift,vc,info);
+       region.dx = vxres - ((sy + height) * vc->vc_font.height);
+@@ -125,7 +125,7 @@ static void cw_putcs(struct vc_data *vc,
+       u32 cnt, pitch, size;
+       u32 attribute = get_attribute(info, scr_readw(s));
+       u8 *dst, *buf = NULL;
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -212,7 +212,7 @@ static void cw_cursor(struct vc_data *vc
+       int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
+       int err = 1, dx, dy;
+       char *src;
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -369,7 +369,7 @@ static void cw_cursor(struct vc_data *vc
+ static int cw_update_start(struct fb_info *info)
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       u32 xoffset;
+       int err;
+--- a/drivers/video/fbdev/core/fbcon_rotate.h
++++ b/drivers/video/fbdev/core/fbcon_rotate.h
+@@ -12,11 +12,11 @@
+ #define _FBCON_ROTATE_H
+ #define GETVYRES(s,i) ({                           \
+-        (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
++        (fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE) ? \
+         (i)->var.yres : (i)->var.yres_virtual; })
+ #define GETVXRES(s,i) ({                           \
+-        (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
++        (fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
+         (i)->var.xres : (i)->var.xres_virtual; })
+--- a/drivers/video/fbdev/core/fbcon_ud.c
++++ b/drivers/video/fbdev/core/fbcon_ud.c
+@@ -50,8 +50,8 @@ static void ud_bmove(struct vc_data *vc,
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_copyarea area;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       area.sy = vyres - ((sy + height) * vc->vc_font.height);
+       area.sx = vxres - ((sx + width) * vc->vc_font.width);
+@@ -69,8 +69,8 @@ static void ud_clear(struct vc_data *vc,
+       struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_fillrect region;
+       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       region.color = attr_bgcol_ec(bgshift,vc,info);
+       region.dy = vyres - ((sy + height) * vc->vc_font.height);
+@@ -162,8 +162,8 @@ static void ud_putcs(struct vc_data *vc,
+       u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
+       u32 attribute = get_attribute(info, scr_readw(s));
+       u8 *dst, *buf = NULL;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -259,8 +259,8 @@ static void ud_cursor(struct vc_data *vc
+       int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
+       int err = 1, dx, dy;
+       char *src;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -410,8 +410,8 @@ static int ud_update_start(struct fb_inf
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       int xoffset, yoffset;
+-      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+-      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++      u32 vyres = GETVYRES(ops->p, info);
++      u32 vxres = GETVXRES(ops->p, info);
+       int err;
+       xoffset = vxres - info->var.xres - ops->var.xoffset;
diff --git a/queue-5.16/ib-hfi1-fix-aip-early-init-panic.patch b/queue-5.16/ib-hfi1-fix-aip-early-init-panic.patch
new file mode 100644 (file)
index 0000000..a15ecbe
--- /dev/null
@@ -0,0 +1,123 @@
+From 5f8f55b92edd621f056bdf09e572092849fabd83 Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Date: Sat, 15 Jan 2022 18:02:35 -0500
+Subject: IB/hfi1: Fix AIP early init panic
+
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+
+commit 5f8f55b92edd621f056bdf09e572092849fabd83 upstream.
+
+An early failure in hfi1_ipoib_setup_rn() can lead to the following panic:
+
+  BUG: unable to handle kernel NULL pointer dereference at 00000000000001b0
+  PGD 0 P4D 0
+  Oops: 0002 [#1] SMP NOPTI
+  Workqueue: events work_for_cpu_fn
+  RIP: 0010:try_to_grab_pending+0x2b/0x140
+  Code: 1f 44 00 00 41 55 41 54 55 48 89 d5 53 48 89 fb 9c 58 0f 1f 44 00 00 48 89 c2 fa 66 0f 1f 44 00 00 48 89 55 00 40 84 f6 75 77 <f0> 48 0f ba 2b 00 72 09 31 c0 5b 5d 41 5c 41 5d c3 48 89 df e8 6c
+  RSP: 0018:ffffb6b3cf7cfa48 EFLAGS: 00010046
+  RAX: 0000000000000246 RBX: 00000000000001b0 RCX: 0000000000000000
+  RDX: 0000000000000246 RSI: 0000000000000000 RDI: 00000000000001b0
+  RBP: ffffb6b3cf7cfa70 R08: 0000000000000f09 R09: 0000000000000001
+  R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
+  R13: ffffb6b3cf7cfa90 R14: ffffffff9b2fbfc0 R15: ffff8a4fdf244690
+  FS:  0000000000000000(0000) GS:ffff8a527f400000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00000000000001b0 CR3: 00000017e2410003 CR4: 00000000007706f0
+  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+  PKRU: 55555554
+  Call Trace:
+   __cancel_work_timer+0x42/0x190
+   ? dev_printk_emit+0x4e/0x70
+   iowait_cancel_work+0x15/0x30 [hfi1]
+   hfi1_ipoib_txreq_deinit+0x5a/0x220 [hfi1]
+   ? dev_err+0x6c/0x90
+   hfi1_ipoib_netdev_dtor+0x15/0x30 [hfi1]
+   hfi1_ipoib_setup_rn+0x10e/0x150 [hfi1]
+   rdma_init_netdev+0x5a/0x80 [ib_core]
+   ? hfi1_ipoib_free_rdma_netdev+0x20/0x20 [hfi1]
+   ipoib_intf_init+0x6c/0x350 [ib_ipoib]
+   ipoib_intf_alloc+0x5c/0xc0 [ib_ipoib]
+   ipoib_add_one+0xbe/0x300 [ib_ipoib]
+   add_client_context+0x12c/0x1a0 [ib_core]
+   enable_device_and_get+0xdc/0x1d0 [ib_core]
+   ib_register_device+0x572/0x6b0 [ib_core]
+   rvt_register_device+0x11b/0x220 [rdmavt]
+   hfi1_register_ib_device+0x6b4/0x770 [hfi1]
+   do_init_one.isra.20+0x3e3/0x680 [hfi1]
+   local_pci_probe+0x41/0x90
+   work_for_cpu_fn+0x16/0x20
+   process_one_work+0x1a7/0x360
+   ? create_worker+0x1a0/0x1a0
+   worker_thread+0x1cf/0x390
+   ? create_worker+0x1a0/0x1a0
+   kthread+0x116/0x130
+   ? kthread_flush_work_fn+0x10/0x10
+   ret_from_fork+0x1f/0x40
+
+The panic happens in hfi1_ipoib_txreq_deinit() because there is a NULL
+deref when hfi1_ipoib_netdev_dtor() is called in this error case.
+
+hfi1_ipoib_txreq_init() and hfi1_ipoib_rxq_init() are self unwinding so
+fix by adjusting the error paths accordingly.
+
+Other changes:
+- hfi1_ipoib_free_rdma_netdev() is deleted including the free_netdev()
+  since the netdev core code deletes calls free_netdev()
+- The switch to the accelerated entrances is moved to the success path.
+
+Cc: stable@vger.kernel.org
+Fixes: d99dc602e2a5 ("IB/hfi1: Add functions to transmit datagram ipoib packets")
+Link: https://lore.kernel.org/r/1642287756-182313-4-git-send-email-mike.marciniszyn@cornelisnetworks.com
+Reviewed-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/hfi1/ipoib_main.c |   13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+--- a/drivers/infiniband/hw/hfi1/ipoib_main.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_main.c
+@@ -168,12 +168,6 @@ static void hfi1_ipoib_netdev_dtor(struc
+       free_percpu(dev->tstats);
+ }
+-static void hfi1_ipoib_free_rdma_netdev(struct net_device *dev)
+-{
+-      hfi1_ipoib_netdev_dtor(dev);
+-      free_netdev(dev);
+-}
+-
+ static void hfi1_ipoib_set_id(struct net_device *dev, int id)
+ {
+       struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev);
+@@ -211,24 +205,23 @@ static int hfi1_ipoib_setup_rn(struct ib
+       priv->port_num = port_num;
+       priv->netdev_ops = netdev->netdev_ops;
+-      netdev->netdev_ops = &hfi1_ipoib_netdev_ops;
+-
+       ib_query_pkey(device, port_num, priv->pkey_index, &priv->pkey);
+       rc = hfi1_ipoib_txreq_init(priv);
+       if (rc) {
+               dd_dev_err(dd, "IPoIB netdev TX init - failed(%d)\n", rc);
+-              hfi1_ipoib_free_rdma_netdev(netdev);
+               return rc;
+       }
+       rc = hfi1_ipoib_rxq_init(netdev);
+       if (rc) {
+               dd_dev_err(dd, "IPoIB netdev RX init - failed(%d)\n", rc);
+-              hfi1_ipoib_free_rdma_netdev(netdev);
++              hfi1_ipoib_txreq_deinit(priv);
+               return rc;
+       }
++      netdev->netdev_ops = &hfi1_ipoib_netdev_ops;
++
+       netdev->priv_destructor = hfi1_ipoib_netdev_dtor;
+       netdev->needs_free_netdev = true;
diff --git a/queue-5.16/ib-hfi1-fix-alloc-failure-with-larger-txqueuelen.patch b/queue-5.16/ib-hfi1-fix-alloc-failure-with-larger-txqueuelen.patch
new file mode 100644 (file)
index 0000000..b4d4199
--- /dev/null
@@ -0,0 +1,186 @@
+From b1151b74ff68cc83c2a8e1a618efe7d056e4f237 Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Date: Sat, 15 Jan 2022 18:02:34 -0500
+Subject: IB/hfi1: Fix alloc failure with larger txqueuelen
+
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+
+commit b1151b74ff68cc83c2a8e1a618efe7d056e4f237 upstream.
+
+The following allocation with large txqueuelen will result in the
+following warning:
+
+  Call Trace:
+   __alloc_pages_nodemask+0x283/0x2c0
+   kmalloc_large_node+0x3c/0xa0
+   __kmalloc_node+0x22a/0x2f0
+   hfi1_ipoib_txreq_init+0x19f/0x330 [hfi1]
+   hfi1_ipoib_setup_rn+0xd3/0x1a0 [hfi1]
+   rdma_init_netdev+0x5a/0x80 [ib_core]
+   ipoib_intf_init+0x6c/0x350 [ib_ipoib]
+   ipoib_intf_alloc+0x5c/0xc0 [ib_ipoib]
+   ipoib_add_one+0xbe/0x300 [ib_ipoib]
+   add_client_context+0x12c/0x1a0 [ib_core]
+   ib_register_client+0x147/0x190 [ib_core]
+   ipoib_init_module+0xdd/0x132 [ib_ipoib]
+   do_one_initcall+0x46/0x1c3
+   do_init_module+0x5a/0x220
+   load_module+0x14c5/0x17f0
+   __do_sys_init_module+0x13b/0x180
+   do_syscall_64+0x5b/0x1a0
+   entry_SYSCALL_64_after_hwframe+0x65/0xca
+
+For ipoib, the txqueuelen is modified with the module parameter
+send_queue_size.
+
+Fix by changing to use kv versions of the same allocator to handle the
+large allocations.  The allocation embeds a hdr struct that is dma mapped.
+Change that struct to a pointer to a kzalloced struct.
+
+Cc: stable@vger.kernel.org
+Fixes: d99dc602e2a5 ("IB/hfi1: Add functions to transmit datagram ipoib packets")
+Link: https://lore.kernel.org/r/1642287756-182313-3-git-send-email-mike.marciniszyn@cornelisnetworks.com
+Reviewed-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/hfi1/ipoib.h    |    2 -
+ drivers/infiniband/hw/hfi1/ipoib_tx.c |   36 +++++++++++++++++++++++-----------
+ 2 files changed, 26 insertions(+), 12 deletions(-)
+
+--- a/drivers/infiniband/hw/hfi1/ipoib.h
++++ b/drivers/infiniband/hw/hfi1/ipoib.h
+@@ -55,7 +55,7 @@ union hfi1_ipoib_flow {
+  */
+ struct ipoib_txreq {
+       struct sdma_txreq           txreq;
+-      struct hfi1_sdma_header     sdma_hdr;
++      struct hfi1_sdma_header     *sdma_hdr;
+       int                         sdma_status;
+       int                         complete;
+       struct hfi1_ipoib_dev_priv *priv;
+--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+@@ -122,7 +122,7 @@ static void hfi1_ipoib_free_tx(struct ip
+               dd_dev_warn(priv->dd,
+                           "%s: Status = 0x%x pbc 0x%llx txq = %d sde = %d\n",
+                           __func__, tx->sdma_status,
+-                          le64_to_cpu(tx->sdma_hdr.pbc), tx->txq->q_idx,
++                          le64_to_cpu(tx->sdma_hdr->pbc), tx->txq->q_idx,
+                           tx->txq->sde->this_idx);
+       }
+@@ -231,7 +231,7 @@ static int hfi1_ipoib_build_tx_desc(stru
+ {
+       struct hfi1_devdata *dd = txp->dd;
+       struct sdma_txreq *txreq = &tx->txreq;
+-      struct hfi1_sdma_header *sdma_hdr = &tx->sdma_hdr;
++      struct hfi1_sdma_header *sdma_hdr = tx->sdma_hdr;
+       u16 pkt_bytes =
+               sizeof(sdma_hdr->pbc) + (txp->hdr_dwords << 2) + tx->skb->len;
+       int ret;
+@@ -256,7 +256,7 @@ static void hfi1_ipoib_build_ib_tx_heade
+                                          struct ipoib_txparms *txp)
+ {
+       struct hfi1_ipoib_dev_priv *priv = tx->txq->priv;
+-      struct hfi1_sdma_header *sdma_hdr = &tx->sdma_hdr;
++      struct hfi1_sdma_header *sdma_hdr = tx->sdma_hdr;
+       struct sk_buff *skb = tx->skb;
+       struct hfi1_pportdata *ppd = ppd_from_ibp(txp->ibp);
+       struct rdma_ah_attr *ah_attr = txp->ah_attr;
+@@ -483,7 +483,7 @@ static int hfi1_ipoib_send_dma_single(st
+       if (likely(!ret)) {
+ tx_ok:
+               trace_sdma_output_ibhdr(txq->priv->dd,
+-                                      &tx->sdma_hdr.hdr,
++                                      &tx->sdma_hdr->hdr,
+                                       ib_is_sc5(txp->flow.sc5));
+               hfi1_ipoib_check_queue_depth(txq);
+               return NETDEV_TX_OK;
+@@ -547,7 +547,7 @@ static int hfi1_ipoib_send_dma_list(stru
+       hfi1_ipoib_check_queue_depth(txq);
+       trace_sdma_output_ibhdr(txq->priv->dd,
+-                              &tx->sdma_hdr.hdr,
++                              &tx->sdma_hdr->hdr,
+                               ib_is_sc5(txp->flow.sc5));
+       if (!netdev_xmit_more())
+@@ -683,7 +683,8 @@ int hfi1_ipoib_txreq_init(struct hfi1_ip
+ {
+       struct net_device *dev = priv->netdev;
+       u32 tx_ring_size, tx_item_size;
+-      int i;
++      struct hfi1_ipoib_circ_buf *tx_ring;
++      int i, j;
+       /*
+        * Ring holds 1 less than tx_ring_size
+@@ -701,7 +702,9 @@ int hfi1_ipoib_txreq_init(struct hfi1_ip
+       for (i = 0; i < dev->num_tx_queues; i++) {
+               struct hfi1_ipoib_txq *txq = &priv->txqs[i];
++              struct ipoib_txreq *tx;
++              tx_ring = &txq->tx_ring;
+               iowait_init(&txq->wait,
+                           0,
+                           hfi1_ipoib_flush_txq,
+@@ -725,14 +728,19 @@ int hfi1_ipoib_txreq_init(struct hfi1_ip
+                                            priv->dd->node);
+               txq->tx_ring.items =
+-                      kcalloc_node(tx_ring_size, tx_item_size,
+-                                   GFP_KERNEL, priv->dd->node);
++                      kvzalloc_node(array_size(tx_ring_size, tx_item_size),
++                                    GFP_KERNEL, priv->dd->node);
+               if (!txq->tx_ring.items)
+                       goto free_txqs;
+               txq->tx_ring.max_items = tx_ring_size;
+               txq->tx_ring.shift = ilog2(tx_item_size);
+               txq->tx_ring.avail = hfi1_ipoib_ring_hwat(txq);
++              tx_ring = &txq->tx_ring;
++              for (j = 0; j < tx_ring_size; j++)
++                      hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr =
++                              kzalloc_node(sizeof(*tx->sdma_hdr),
++                                           GFP_KERNEL, priv->dd->node);
+               netif_tx_napi_add(dev, &txq->napi,
+                                 hfi1_ipoib_poll_tx_ring,
+@@ -746,7 +754,10 @@ free_txqs:
+               struct hfi1_ipoib_txq *txq = &priv->txqs[i];
+               netif_napi_del(&txq->napi);
+-              kfree(txq->tx_ring.items);
++              tx_ring = &txq->tx_ring;
++              for (j = 0; j < tx_ring_size; j++)
++                      kfree(hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr);
++              kvfree(tx_ring->items);
+       }
+       kfree(priv->txqs);
+@@ -780,17 +791,20 @@ static void hfi1_ipoib_drain_tx_list(str
+ void hfi1_ipoib_txreq_deinit(struct hfi1_ipoib_dev_priv *priv)
+ {
+-      int i;
++      int i, j;
+       for (i = 0; i < priv->netdev->num_tx_queues; i++) {
+               struct hfi1_ipoib_txq *txq = &priv->txqs[i];
++              struct hfi1_ipoib_circ_buf *tx_ring = &txq->tx_ring;
+               iowait_cancel_work(&txq->wait);
+               iowait_sdma_drain(&txq->wait);
+               hfi1_ipoib_drain_tx_list(txq);
+               netif_napi_del(&txq->napi);
+               hfi1_ipoib_drain_tx_ring(txq);
+-              kfree(txq->tx_ring.items);
++              for (j = 0; j < tx_ring->max_items; j++)
++                      kfree(hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr);
++              kvfree(tx_ring->items);
+       }
+       kfree(priv->txqs);
diff --git a/queue-5.16/ib-hfi1-fix-panic-with-larger-ipoib-send_queue_size.patch b/queue-5.16/ib-hfi1-fix-panic-with-larger-ipoib-send_queue_size.patch
new file mode 100644 (file)
index 0000000..4a5cacf
--- /dev/null
@@ -0,0 +1,77 @@
+From 8c83d39cc730378bbac64d67a551897b203a606e Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Date: Sat, 15 Jan 2022 18:02:33 -0500
+Subject: IB/hfi1: Fix panic with larger ipoib send_queue_size
+
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+
+commit 8c83d39cc730378bbac64d67a551897b203a606e upstream.
+
+When the ipoib send_queue_size is increased from the default the following
+panic happens:
+
+  RIP: 0010:hfi1_ipoib_drain_tx_ring+0x45/0xf0 [hfi1]
+  Code: 31 e4 eb 0f 8b 85 c8 02 00 00 41 83 c4 01 44 39 e0 76 60 8b 8d cc 02 00 00 44 89 e3 be 01 00 00 00 d3 e3 48 03 9d c0 02 00 00 <c7> 83 18 01 00 00 00 00 00 00 48 8b bb 30 01 00 00 e8 25 af a7 e0
+  RSP: 0018:ffffc9000798f4a0 EFLAGS: 00010286
+  RAX: 0000000000008000 RBX: ffffc9000aa0f000 RCX: 000000000000000f
+  RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
+  RBP: ffff88810ff08000 R08: ffff88889476d900 R09: 0000000000000101
+  R10: 0000000000000000 R11: ffffc90006590ff8 R12: 0000000000000200
+  R13: ffffc9000798fba8 R14: 0000000000000000 R15: 0000000000000001
+  FS:  00007fd0f79cc3c0(0000) GS:ffff88885fb00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: ffffc9000aa0f118 CR3: 0000000889c84001 CR4: 00000000001706e0
+  Call Trace:
+   <TASK>
+   hfi1_ipoib_napi_tx_disable+0x45/0x60 [hfi1]
+   hfi1_ipoib_dev_stop+0x18/0x80 [hfi1]
+   ipoib_ib_dev_stop+0x1d/0x40 [ib_ipoib]
+   ipoib_stop+0x48/0xc0 [ib_ipoib]
+   __dev_close_many+0x9e/0x110
+   __dev_change_flags+0xd9/0x210
+   dev_change_flags+0x21/0x60
+   do_setlink+0x31c/0x10f0
+   ? __nla_validate_parse+0x12d/0x1a0
+   ? __nla_parse+0x21/0x30
+   ? inet6_validate_link_af+0x5e/0xf0
+   ? cpumask_next+0x1f/0x20
+   ? __snmp6_fill_stats64.isra.53+0xbb/0x140
+   ? __nla_validate_parse+0x47/0x1a0
+   __rtnl_newlink+0x530/0x910
+   ? pskb_expand_head+0x73/0x300
+   ? __kmalloc_node_track_caller+0x109/0x280
+   ? __nla_put+0xc/0x20
+   ? cpumask_next_and+0x20/0x30
+   ? update_sd_lb_stats.constprop.144+0xd3/0x820
+   ? _raw_spin_unlock_irqrestore+0x25/0x37
+   ? __wake_up_common_lock+0x87/0xc0
+   ? kmem_cache_alloc_trace+0x3d/0x3d0
+   rtnl_newlink+0x43/0x60
+
+The issue happens when the shift that should have been a function of the
+txq item size mistakenly used the ring size.
+
+Fix by using the item size.
+
+Cc: stable@vger.kernel.org
+Fixes: d47dfc2b00e6 ("IB/hfi1: Remove cache and embed txreq in ring")
+Link: https://lore.kernel.org/r/1642287756-182313-2-git-send-email-mike.marciniszyn@cornelisnetworks.com
+Reviewed-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/hfi1/ipoib_tx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c
++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c
+@@ -731,7 +731,7 @@ int hfi1_ipoib_txreq_init(struct hfi1_ip
+                       goto free_txqs;
+               txq->tx_ring.max_items = tx_ring_size;
+-              txq->tx_ring.shift = ilog2(tx_ring_size);
++              txq->tx_ring.shift = ilog2(tx_item_size);
+               txq->tx_ring.avail = hfi1_ipoib_ring_hwat(txq);
+               netif_tx_napi_add(dev, &txq->napi,
diff --git a/queue-5.16/ipc-sem-do-not-sleep-with-a-spin-lock-held.patch b/queue-5.16/ipc-sem-do-not-sleep-with-a-spin-lock-held.patch
new file mode 100644 (file)
index 0000000..ba1ad35
--- /dev/null
@@ -0,0 +1,52 @@
+From 520ba724061cef59763e2b6f5b26e8387c2e5822 Mon Sep 17 00:00:00 2001
+From: Minghao Chi <chi.minghao@zte.com.cn>
+Date: Thu, 3 Feb 2022 20:49:33 -0800
+Subject: ipc/sem: do not sleep with a spin lock held
+
+From: Minghao Chi <chi.minghao@zte.com.cn>
+
+commit 520ba724061cef59763e2b6f5b26e8387c2e5822 upstream.
+
+We can't call kvfree() with a spin lock held, so defer it.
+
+Link: https://lkml.kernel.org/r/20211223031207.556189-1-chi.minghao@zte.com.cn
+Fixes: fc37a3b8b438 ("[PATCH] ipc sem: use kvmalloc for sem_undo allocation")
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Minghao Chi <chi.minghao@zte.com.cn>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Reviewed-by: Manfred Spraul <manfred@colorfullife.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Yang Guang <cgel.zte@gmail.com>
+Cc: Davidlohr Bueso <dbueso@suse.de>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Bhaskar Chowdhury <unixbhaskar@gmail.com>
+Cc: Vasily Averin <vvs@virtuozzo.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ ipc/sem.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -1964,6 +1964,7 @@ static struct sem_undo *find_alloc_undo(
+        */
+       un = lookup_undo(ulp, semid);
+       if (un) {
++              spin_unlock(&ulp->lock);
+               kvfree(new);
+               goto success;
+       }
+@@ -1976,9 +1977,8 @@ static struct sem_undo *find_alloc_undo(
+       ipc_assert_locked_object(&sma->sem_perm);
+       list_add(&new->list_id, &sma->list_id);
+       un = new;
+-
+-success:
+       spin_unlock(&ulp->lock);
++success:
+       sem_unlock(sma, -1);
+ out:
+       return un;
diff --git a/queue-5.16/mm-debug_vm_pgtable-remove-pte-entry-from-the-page-table.patch b/queue-5.16/mm-debug_vm_pgtable-remove-pte-entry-from-the-page-table.patch
new file mode 100644 (file)
index 0000000..b78db40
--- /dev/null
@@ -0,0 +1,75 @@
+From fb5222aae64fe25e5f3ebefde8214dcf3ba33ca5 Mon Sep 17 00:00:00 2001
+From: Pasha Tatashin <pasha.tatashin@soleen.com>
+Date: Thu, 3 Feb 2022 20:49:10 -0800
+Subject: mm/debug_vm_pgtable: remove pte entry from the page table
+
+From: Pasha Tatashin <pasha.tatashin@soleen.com>
+
+commit fb5222aae64fe25e5f3ebefde8214dcf3ba33ca5 upstream.
+
+Patch series "page table check fixes and cleanups", v5.
+
+This patch (of 4):
+
+The pte entry that is used in pte_advanced_tests() is never removed from
+the page table at the end of the test.
+
+The issue is detected by page_table_check, to repro compile kernel with
+the following configs:
+
+CONFIG_DEBUG_VM_PGTABLE=y
+CONFIG_PAGE_TABLE_CHECK=y
+CONFIG_PAGE_TABLE_CHECK_ENFORCED=y
+
+During the boot the following BUG is printed:
+
+  debug_vm_pgtable: [debug_vm_pgtable         ]: Validating architecture page table helpers
+  ------------[ cut here ]------------
+  kernel BUG at mm/page_table_check.c:162!
+  invalid opcode: 0000 [#1] PREEMPT SMP PTI
+  CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.16.0-11413-g2c271fe77d52 #3
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
+  ...
+
+The entry should be properly removed from the page table before the page
+is released to the free list.
+
+Link: https://lkml.kernel.org/r/20220131203249.2832273-1-pasha.tatashin@soleen.com
+Link: https://lkml.kernel.org/r/20220131203249.2832273-2-pasha.tatashin@soleen.com
+Fixes: a5c3b9ffb0f4 ("mm/debug_vm_pgtable: add tests validating advanced arch page table helpers")
+Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
+Reviewed-by: Zi Yan <ziy@nvidia.com>
+Tested-by: Zi Yan <ziy@nvidia.com>
+Acked-by: David Rientjes <rientjes@google.com>
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: Paul Turner <pjt@google.com>
+Cc: Wei Xu <weixugc@google.com>
+Cc: Greg Thelen <gthelen@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Cc: Jiri Slaby <jirislaby@kernel.org>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: <stable@vger.kernel.org>   [5.9+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/debug_vm_pgtable.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/debug_vm_pgtable.c
++++ b/mm/debug_vm_pgtable.c
+@@ -171,6 +171,8 @@ static void __init pte_advanced_tests(st
+       ptep_test_and_clear_young(args->vma, args->vaddr, args->ptep);
+       pte = ptep_get(args->ptep);
+       WARN_ON(pte_young(pte));
++
++      ptep_get_and_clear_full(args->mm, args->vaddr, args->ptep, 1);
+ }
+ static void __init pte_savedwrite_tests(struct pgtable_debug_args *args)
diff --git a/queue-5.16/mm-kmemleak-avoid-scanning-potential-huge-holes.patch b/queue-5.16/mm-kmemleak-avoid-scanning-potential-huge-holes.patch
new file mode 100644 (file)
index 0000000..06a5f3d
--- /dev/null
@@ -0,0 +1,121 @@
+From c10a0f877fe007021d70f9cada240f42adc2b5db Mon Sep 17 00:00:00 2001
+From: Lang Yu <lang.yu@amd.com>
+Date: Thu, 3 Feb 2022 20:49:37 -0800
+Subject: mm/kmemleak: avoid scanning potential huge holes
+
+From: Lang Yu <lang.yu@amd.com>
+
+commit c10a0f877fe007021d70f9cada240f42adc2b5db upstream.
+
+When using devm_request_free_mem_region() and devm_memremap_pages() to
+add ZONE_DEVICE memory, if requested free mem region's end pfn were
+huge(e.g., 0x400000000), the node_end_pfn() will be also huge (see
+move_pfn_range_to_zone()).  Thus it creates a huge hole between
+node_start_pfn() and node_end_pfn().
+
+We found on some AMD APUs, amdkfd requested such a free mem region and
+created a huge hole.  In such a case, following code snippet was just
+doing busy test_bit() looping on the huge hole.
+
+  for (pfn = start_pfn; pfn < end_pfn; pfn++) {
+       struct page *page = pfn_to_online_page(pfn);
+               if (!page)
+                       continue;
+       ...
+  }
+
+So we got a soft lockup:
+
+  watchdog: BUG: soft lockup - CPU#6 stuck for 26s! [bash:1221]
+  CPU: 6 PID: 1221 Comm: bash Not tainted 5.15.0-custom #1
+  RIP: 0010:pfn_to_online_page+0x5/0xd0
+  Call Trace:
+    ? kmemleak_scan+0x16a/0x440
+    kmemleak_write+0x306/0x3a0
+    ? common_file_perm+0x72/0x170
+    full_proxy_write+0x5c/0x90
+    vfs_write+0xb9/0x260
+    ksys_write+0x67/0xe0
+    __x64_sys_write+0x1a/0x20
+    do_syscall_64+0x3b/0xc0
+    entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+I did some tests with the patch.
+
+(1) amdgpu module unloaded
+
+before the patch:
+
+  real    0m0.976s
+  user    0m0.000s
+  sys     0m0.968s
+
+after the patch:
+
+  real    0m0.981s
+  user    0m0.000s
+  sys     0m0.973s
+
+(2) amdgpu module loaded
+
+before the patch:
+
+  real    0m35.365s
+  user    0m0.000s
+  sys     0m35.354s
+
+after the patch:
+
+  real    0m1.049s
+  user    0m0.000s
+  sys     0m1.042s
+
+Link: https://lkml.kernel.org/r/20211108140029.721144-1-lang.yu@amd.com
+Signed-off-by: Lang Yu <lang.yu@amd.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/kmemleak.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/mm/kmemleak.c
++++ b/mm/kmemleak.c
+@@ -1403,7 +1403,8 @@ static void kmemleak_scan(void)
+ {
+       unsigned long flags;
+       struct kmemleak_object *object;
+-      int i;
++      struct zone *zone;
++      int __maybe_unused i;
+       int new_leaks = 0;
+       jiffies_last_scan = jiffies;
+@@ -1443,9 +1444,9 @@ static void kmemleak_scan(void)
+        * Struct page scanning for each node.
+        */
+       get_online_mems();
+-      for_each_online_node(i) {
+-              unsigned long start_pfn = node_start_pfn(i);
+-              unsigned long end_pfn = node_end_pfn(i);
++      for_each_populated_zone(zone) {
++              unsigned long start_pfn = zone->zone_start_pfn;
++              unsigned long end_pfn = zone_end_pfn(zone);
+               unsigned long pfn;
+               for (pfn = start_pfn; pfn < end_pfn; pfn++) {
+@@ -1454,8 +1455,8 @@ static void kmemleak_scan(void)
+                       if (!page)
+                               continue;
+-                      /* only scan pages belonging to this node */
+-                      if (page_to_nid(page) != i)
++                      /* only scan pages belonging to this zone */
++                      if (page_zone(page) != zone)
+                               continue;
+                       /* only scan if page is in use */
+                       if (page_count(page) == 0)
diff --git a/queue-5.16/mm-pgtable-define-pte_index-so-that-preprocessor-could-recognize-it.patch b/queue-5.16/mm-pgtable-define-pte_index-so-that-preprocessor-could-recognize-it.patch
new file mode 100644 (file)
index 0000000..7bf4c34
--- /dev/null
@@ -0,0 +1,39 @@
+From 314c459a6fe0957b5885fbc65c53d51444092880 Mon Sep 17 00:00:00 2001
+From: Mike Rapoport <rppt@linux.ibm.com>
+Date: Thu, 3 Feb 2022 20:49:29 -0800
+Subject: mm/pgtable: define pte_index so that preprocessor could recognize it
+
+From: Mike Rapoport <rppt@linux.ibm.com>
+
+commit 314c459a6fe0957b5885fbc65c53d51444092880 upstream.
+
+Since commit 974b9b2c68f3 ("mm: consolidate pte_index() and
+pte_offset_*() definitions") pte_index is a static inline and there is
+no define for it that can be recognized by the preprocessor.  As a
+result, vm_insert_pages() uses slower loop over vm_insert_page() instead
+of insert_pages() that amortizes the cost of spinlock operations when
+inserting multiple pages.
+
+Link: https://lkml.kernel.org/r/20220111145457.20748-1-rppt@kernel.org
+Fixes: 974b9b2c68f3 ("mm: consolidate pte_index() and pte_offset_*() definitions")
+Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
+Reported-by: Christian Dietrich <stettberger@dokucode.de>
+Reviewed-by: Khalid Aziz <khalid.aziz@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/pgtable.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -62,6 +62,7 @@ static inline unsigned long pte_index(un
+ {
+       return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ }
++#define pte_index pte_index
+ #ifndef pmd_index
+ static inline unsigned long pmd_index(unsigned long address)
diff --git a/queue-5.16/mptcp-fix-msk-traversal-in-mptcp_nl_cmd_set_flags.patch b/queue-5.16/mptcp-fix-msk-traversal-in-mptcp_nl_cmd_set_flags.patch
new file mode 100644 (file)
index 0000000..1e1a4c5
--- /dev/null
@@ -0,0 +1,84 @@
+From 8e9eacad7ec7a9cbf262649ebf1fa6e6f6cc7d82 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 20 Jan 2022 16:35:27 -0800
+Subject: mptcp: fix msk traversal in mptcp_nl_cmd_set_flags()
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 8e9eacad7ec7a9cbf262649ebf1fa6e6f6cc7d82 upstream.
+
+The MPTCP endpoint list is under RCU protection, guarded by the
+pernet spinlock. mptcp_nl_cmd_set_flags() traverses the list
+without acquiring the spin-lock nor under the RCU critical section.
+
+This change addresses the issue performing the lookup and the endpoint
+update under the pernet spinlock.
+
+[The upstream commit had to handle a lookup_by_id variable that is only
+ present in 5.17. This version of the patch removes that variable, so
+ the __lookup_addr() function only handles the lookup as it is
+ implemented in 5.15 and 5.16. It also removes one 'const' keyword to
+ prevent a warning due to differing const-ness in the 5.17 version of
+ addresses_equal().]
+
+Fixes: 0f9f696a502e ("mptcp: add set_flags command in PM netlink")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |   34 +++++++++++++++++++++++++---------
+ 1 file changed, 25 insertions(+), 9 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -459,6 +459,18 @@ static unsigned int fill_remote_addresse
+       return i;
+ }
++static struct mptcp_pm_addr_entry *
++__lookup_addr(struct pm_nl_pernet *pernet, struct mptcp_addr_info *info)
++{
++      struct mptcp_pm_addr_entry *entry;
++
++      list_for_each_entry(entry, &pernet->local_addr_list, list) {
++              if (addresses_equal(&entry->addr, info, true))
++                      return entry;
++      }
++      return NULL;
++}
++
+ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
+ {
+       struct sock *sk = (struct sock *)msk;
+@@ -1725,17 +1737,21 @@ static int mptcp_nl_cmd_set_flags(struct
+       if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+               bkup = 1;
+-      list_for_each_entry(entry, &pernet->local_addr_list, list) {
+-              if (addresses_equal(&entry->addr, &addr.addr, true)) {
+-                      mptcp_nl_addr_backup(net, &entry->addr, bkup);
+-
+-                      if (bkup)
+-                              entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
+-                      else
+-                              entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
+-              }
++      spin_lock_bh(&pernet->lock);
++      entry = __lookup_addr(pernet, &addr.addr);
++      if (!entry) {
++              spin_unlock_bh(&pernet->lock);
++              return -EINVAL;
+       }
++      if (bkup)
++              entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
++      else
++              entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
++      addr = *entry;
++      spin_unlock_bh(&pernet->lock);
++
++      mptcp_nl_addr_backup(net, &addr.addr, bkup);
+       return 0;
+ }
diff --git a/queue-5.16/nvme-fabrics-fix-state-check-in-nvmf_ctlr_matches_baseopts.patch b/queue-5.16/nvme-fabrics-fix-state-check-in-nvmf_ctlr_matches_baseopts.patch
new file mode 100644 (file)
index 0000000..a0e311e
--- /dev/null
@@ -0,0 +1,46 @@
+From 6a51abdeb259a56d95f13cc67e3a0838bcda0377 Mon Sep 17 00:00:00 2001
+From: Uday Shankar <ushankar@purestorage.com>
+Date: Thu, 20 Jan 2022 12:17:37 -0800
+Subject: nvme-fabrics: fix state check in nvmf_ctlr_matches_baseopts()
+
+From: Uday Shankar <ushankar@purestorage.com>
+
+commit 6a51abdeb259a56d95f13cc67e3a0838bcda0377 upstream.
+
+Controller deletion/reset, immediately followed by or concurrent with
+a reconnect, is hard failing the connect attempt resulting in a
+complete loss of connectivity to the controller.
+
+In the connect request, fabrics looks for an existing controller with
+the same address components and aborts the connect if a controller
+already exists and the duplicate connect option isn't set. The match
+routine filters out controllers that are dead or dying, so they don't
+interfere with the new connect request.
+
+When NVME_CTRL_DELETING_NOIO was added, it missed updating the state
+filters in the nvmf_ctlr_matches_baseopts() routine. Thus, when in this
+new state, it's seen as a live controller and fails the connect request.
+
+Correct by adding the DELETING_NIO state to the match checks.
+
+Fixes: ecca390e8056 ("nvme: fix deadlock in disconnect during scan_work and/or ana_work")
+Cc: <stable@vger.kernel.org> # v5.7+
+Signed-off-by: Uday Shankar <ushankar@purestorage.com>
+Reviewed-by: James Smart <jsmart2021@gmail.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/host/fabrics.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvme/host/fabrics.h
++++ b/drivers/nvme/host/fabrics.h
+@@ -170,6 +170,7 @@ nvmf_ctlr_matches_baseopts(struct nvme_c
+                       struct nvmf_ctrl_options *opts)
+ {
+       if (ctrl->state == NVME_CTRL_DELETING ||
++          ctrl->state == NVME_CTRL_DELETING_NOIO ||
+           ctrl->state == NVME_CTRL_DEAD ||
+           strcmp(opts->subsysnqn, ctrl->opts->subsysnqn) ||
+           strcmp(opts->host->nqn, ctrl->opts->host->nqn) ||
diff --git a/queue-5.16/revert-fbcon-disable-accelerated-scrolling.patch b/queue-5.16/revert-fbcon-disable-accelerated-scrolling.patch
new file mode 100644 (file)
index 0000000..cc38e1d
--- /dev/null
@@ -0,0 +1,195 @@
+From 87ab9f6b7417349aa197a6c7098d4fdd4beebb74 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Wed, 2 Feb 2022 14:55:30 +0100
+Subject: Revert "fbcon: Disable accelerated scrolling"
+
+From: Helge Deller <deller@gmx.de>
+
+commit 87ab9f6b7417349aa197a6c7098d4fdd4beebb74 upstream.
+
+This reverts commit 39aead8373b3c20bb5965c024dfb51a94e526151.
+
+Revert the first (of 2) commits which disabled scrolling acceleration in
+fbcon/fbdev.  It introduced a regression for fbdev-supported graphic cards
+because of the performance penalty by doing screen scrolling by software
+instead of using the existing graphic card 2D hardware acceleration.
+
+Console scrolling acceleration was disabled by dropping code which
+checked at runtime the driver hardware capabilities for the
+BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
+enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
+screen contents.  After dropping those checks scrollmode was hard-wired
+to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
+character at the new screen position when scrolling.
+
+This change effectively disabled all hardware-based scrolling acceleration for
+ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
+fillrect) in the drivers isn't used any longer.
+
+The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
+and gma500) used hardware acceleration in the past and thus code for checking
+and using scrolling acceleration is obsolete.
+
+This statement is NOT TRUE, because beside the DRM drivers there are around 35
+other fbdev drivers which depend on fbdev/fbcon and still provide hardware
+acceleration for fbdev/fbcon.
+
+The original commit message also states that syzbot found lots of bugs in fbcon
+and thus it's "often the solution to just delete code and remove features".
+This is true, and the bugs - which actually affected all users of fbcon,
+including DRM - were fixed, or code was dropped like e.g. the support for
+software scrollback in vgacon (commit 973c096f6a85).
+
+So to further analyze which bugs were found by syzbot, I've looked through all
+patches in drivers/video which were tagged with syzbot or syzkaller back to
+year 2005. The vast majority fixed the reported issues on a higher level, e.g.
+when screen is to be resized, or when font size is to be changed. The few ones
+which touched driver code fixed a real driver bug, e.g. by adding a check.
+
+But NONE of those patches touched code of either the SCROLL_MOVE or the
+SCROLL_REDRAW case.
+
+That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
+just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
+was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
+could go away. That argument completely missed the fact that SCROLL_MOVE is
+still heavily used by fbdev (non-DRM) drivers.
+
+Some people mention that using memcpy() instead of the hardware acceleration is
+pretty much the same speed. But that's not true, at least not for older graphic
+cards and machines where we see speed decreases by factor 10 and more and thus
+this change leads to console responsiveness way worse than before.
+
+That's why the original commit is to be reverted. By reverting we
+reintroduce hardware-based scrolling acceleration and fix the
+performance regression for fbdev drivers.
+
+There isn't any impact on DRM when reverting those patches.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Acked-by: Sven Schnelle <svens@stackframe.org>
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-3-deller@gmx.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/gpu/todo.rst       |   21 ------------------
+ drivers/video/fbdev/core/fbcon.c |   45 ++++++++++++++++++++++++++++++++-------
+ 2 files changed, 37 insertions(+), 29 deletions(-)
+
+--- a/Documentation/gpu/todo.rst
++++ b/Documentation/gpu/todo.rst
+@@ -311,27 +311,6 @@ Contact: Daniel Vetter, Noralf Tronnes
+ Level: Advanced
+-Garbage collect fbdev scrolling acceleration
+---------------------------------------------
+-
+-Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode =
+-SCROLL_REDRAW. There's a ton of code this will allow us to remove:
+-
+-- lots of code in fbcon.c
+-
+-- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called
+-  directly instead of the function table (with a switch on p->rotate)
+-
+-- fb_copyarea is unused after this, and can be deleted from all drivers
+-
+-Note that not all acceleration code can be deleted, since clearing and cursor
+-support is still accelerated, which might be good candidates for further
+-deletion projects.
+-
+-Contact: Daniel Vetter
+-
+-Level: Intermediate
+-
+ idr_init_base()
+ ---------------
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -1025,7 +1025,7 @@ static void fbcon_init(struct vc_data *v
+       struct vc_data *svc = *default_mode;
+       struct fbcon_display *t, *p = &fb_display[vc->vc_num];
+       int logo = 1, new_rows, new_cols, rows, cols;
+-      int ret;
++      int cap, ret;
+       if (WARN_ON(info_idx == -1))
+           return;
+@@ -1034,6 +1034,7 @@ static void fbcon_init(struct vc_data *v
+               con2fb_map[vc->vc_num] = info_idx;
+       info = registered_fb[con2fb_map[vc->vc_num]];
++      cap = info->flags;
+       if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)
+               logo_shown = FBCON_LOGO_DONTSHOW;
+@@ -1135,13 +1136,11 @@ static void fbcon_init(struct vc_data *v
+       ops->graphics = 0;
+-      /*
+-       * No more hw acceleration for fbcon.
+-       *
+-       * FIXME: Garbage collect all the now dead code after sufficient time
+-       * has passed.
+-       */
+-      p->scrollmode = SCROLL_REDRAW;
++      if ((cap & FBINFO_HWACCEL_COPYAREA) &&
++          !(cap & FBINFO_HWACCEL_DISABLED))
++              p->scrollmode = SCROLL_MOVE;
++      else /* default to something safe */
++              p->scrollmode = SCROLL_REDRAW;
+       /*
+        *  ++guenther: console.c:vc_allocate() relies on initializing
+@@ -1953,15 +1952,45 @@ static void updatescrollmode(struct fbco
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       int fh = vc->vc_font.height;
++      int cap = info->flags;
++      u16 t = 0;
++      int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
++                                info->fix.xpanstep);
++      int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
+       int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+       int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
+                                  info->var.xres_virtual);
++      int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
++              divides(ypan, vc->vc_font.height) && vyres > yres;
++      int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
++              divides(ywrap, vc->vc_font.height) &&
++              divides(vc->vc_font.height, vyres) &&
++              divides(vc->vc_font.height, yres);
++      int reading_fast = cap & FBINFO_READS_FAST;
++      int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
++              !(cap & FBINFO_HWACCEL_DISABLED);
++      int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
++              !(cap & FBINFO_HWACCEL_DISABLED);
+       p->vrows = vyres/fh;
+       if (yres > (fh * (vc->vc_rows + 1)))
+               p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
+       if ((yres % fh) && (vyres % fh < yres % fh))
+               p->vrows--;
++
++      if (good_wrap || good_pan) {
++              if (reading_fast || fast_copyarea)
++                      p->scrollmode = good_wrap ?
++                              SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
++              else
++                      p->scrollmode = good_wrap ? SCROLL_REDRAW :
++                              SCROLL_PAN_REDRAW;
++      } else {
++              if (reading_fast || (fast_copyarea && !fast_imageblit))
++                      p->scrollmode = SCROLL_MOVE;
++              else
++                      p->scrollmode = SCROLL_REDRAW;
++      }
+ }
+ #define PITCH(w) (((w) + 7) >> 3)
diff --git a/queue-5.16/revert-fbdev-garbage-collect-fbdev-scrolling-acceleration-part-1-from-todo-list.patch b/queue-5.16/revert-fbdev-garbage-collect-fbdev-scrolling-acceleration-part-1-from-todo-list.patch
new file mode 100644 (file)
index 0000000..280a60f
--- /dev/null
@@ -0,0 +1,1129 @@
+From 1148836fd3226c20de841084aba24184d4fbbe77 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Wed, 2 Feb 2022 14:55:29 +0100
+Subject: Revert "fbdev: Garbage collect fbdev scrolling acceleration, part 1 (from TODO list)"
+
+From: Helge Deller <deller@gmx.de>
+
+commit 1148836fd3226c20de841084aba24184d4fbbe77 upstream.
+
+This reverts commit b3ec8cdf457e5e63d396fe1346cc788cf7c1b578.
+
+Revert the second (of 2) commits which disabled scrolling acceleration
+in fbcon/fbdev.  It introduced a regression for fbdev-supported graphic
+cards because of the performance penalty by doing screen scrolling by
+software instead of using the existing graphic card 2D hardware
+acceleration.
+
+Console scrolling acceleration was disabled by dropping code which
+checked at runtime the driver hardware capabilities for the
+BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it
+enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move
+screen contents.  After dropping those checks scrollmode was hard-wired
+to SCROLL_REDRAW instead, which forces all graphic cards to redraw every
+character at the new screen position when scrolling.
+
+This change effectively disabled all hardware-based scrolling acceleration for
+ALL drivers, because now all kind of 2D hardware acceleration (bitblt,
+fillrect) in the drivers isn't used any longer.
+
+The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm
+and gma500) used hardware acceleration in the past and thus code for checking
+and using scrolling acceleration is obsolete.
+
+This statement is NOT TRUE, because beside the DRM drivers there are around 35
+other fbdev drivers which depend on fbdev/fbcon and still provide hardware
+acceleration for fbdev/fbcon.
+
+The original commit message also states that syzbot found lots of bugs in fbcon
+and thus it's "often the solution to just delete code and remove features".
+This is true, and the bugs - which actually affected all users of fbcon,
+including DRM - were fixed, or code was dropped like e.g. the support for
+software scrollback in vgacon (commit 973c096f6a85).
+
+So to further analyze which bugs were found by syzbot, I've looked through all
+patches in drivers/video which were tagged with syzbot or syzkaller back to
+year 2005. The vast majority fixed the reported issues on a higher level, e.g.
+when screen is to be resized, or when font size is to be changed. The few ones
+which touched driver code fixed a real driver bug, e.g. by adding a check.
+
+But NONE of those patches touched code of either the SCROLL_MOVE or the
+SCROLL_REDRAW case.
+
+That means, there was no real reason why SCROLL_MOVE had to be ripped-out and
+just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far
+was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it
+could go away. That argument completely missed the fact that SCROLL_MOVE is
+still heavily used by fbdev (non-DRM) drivers.
+
+Some people mention that using memcpy() instead of the hardware acceleration is
+pretty much the same speed. But that's not true, at least not for older graphic
+cards and machines where we see speed decreases by factor 10 and more and thus
+this change leads to console responsiveness way worse than before.
+
+That's why the original commit is to be reverted. By reverting we
+reintroduce hardware-based scrolling acceleration and fix the
+performance regression for fbdev drivers.
+
+There isn't any impact on DRM when reverting those patches.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Acked-by: Sven Schnelle <svens@stackframe.org>
+Cc: stable@vger.kernel.org # v5.16+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220202135531.92183-2-deller@gmx.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/gpu/todo.rst              |   13 
+ drivers/video/fbdev/core/bitblit.c      |   16 +
+ drivers/video/fbdev/core/fbcon.c        |  509 ++++++++++++++++++++++++++++++--
+ drivers/video/fbdev/core/fbcon.h        |   59 +++
+ drivers/video/fbdev/core/fbcon_ccw.c    |   28 +
+ drivers/video/fbdev/core/fbcon_cw.c     |   28 +
+ drivers/video/fbdev/core/fbcon_rotate.h |    9 
+ drivers/video/fbdev/core/fbcon_ud.c     |   37 +-
+ drivers/video/fbdev/core/tileblit.c     |   16 +
+ drivers/video/fbdev/skeletonfb.c        |   12 
+ include/linux/fb.h                      |    2 
+ 11 files changed, 678 insertions(+), 51 deletions(-)
+
+--- a/Documentation/gpu/todo.rst
++++ b/Documentation/gpu/todo.rst
+@@ -314,19 +314,16 @@ Level: Advanced
+ Garbage collect fbdev scrolling acceleration
+ --------------------------------------------
+-Scroll acceleration has been disabled in fbcon. Now it works as the old
+-SCROLL_REDRAW mode. A ton of code was removed in fbcon.c and the hook bmove was
+-removed from fbcon_ops.
+-Remaining tasks:
++Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode =
++SCROLL_REDRAW. There's a ton of code this will allow us to remove:
+-- a bunch of the hooks in fbcon_ops could be removed or simplified by calling
++- lots of code in fbcon.c
++
++- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called
+   directly instead of the function table (with a switch on p->rotate)
+ - fb_copyarea is unused after this, and can be deleted from all drivers
+-- after that, fb_copyarea can be deleted from fb_ops in include/linux/fb.h as
+-  well as cfb_copyarea
+-
+ Note that not all acceleration code can be deleted, since clearing and cursor
+ support is still accelerated, which might be good candidates for further
+ deletion projects.
+--- a/drivers/video/fbdev/core/bitblit.c
++++ b/drivers/video/fbdev/core/bitblit.c
+@@ -43,6 +43,21 @@ static void update_attr(u8 *dst, u8 *src
+       }
+ }
++static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
++                    int sx, int dy, int dx, int height, int width)
++{
++      struct fb_copyarea area;
++
++      area.sx = sx * vc->vc_font.width;
++      area.sy = sy * vc->vc_font.height;
++      area.dx = dx * vc->vc_font.width;
++      area.dy = dy * vc->vc_font.height;
++      area.height = height * vc->vc_font.height;
++      area.width = width * vc->vc_font.width;
++
++      info->fbops->fb_copyarea(info, &area);
++}
++
+ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
+                     int sx, int height, int width)
+ {
+@@ -378,6 +393,7 @@ static int bit_update_start(struct fb_in
+ void fbcon_set_bitops(struct fbcon_ops *ops)
+ {
++      ops->bmove = bit_bmove;
+       ops->clear = bit_clear;
+       ops->putcs = bit_putcs;
+       ops->clear_margins = bit_clear_margins;
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -173,6 +173,8 @@ static void fbcon_putcs(struct vc_data *
+                       int count, int ypos, int xpos);
+ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);
+ static void fbcon_cursor(struct vc_data *vc, int mode);
++static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
++                      int height, int width);
+ static int fbcon_switch(struct vc_data *vc);
+ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
+ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
+@@ -180,8 +182,16 @@ static void fbcon_set_palette(struct vc_
+ /*
+  *  Internal routines
+  */
++static __inline__ void ywrap_up(struct vc_data *vc, int count);
++static __inline__ void ywrap_down(struct vc_data *vc, int count);
++static __inline__ void ypan_up(struct vc_data *vc, int count);
++static __inline__ void ypan_down(struct vc_data *vc, int count);
++static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
++                          int dy, int dx, int height, int width, u_int y_break);
+ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+                          int unit);
++static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
++                            int line, int count, int dy);
+ static void fbcon_modechanged(struct fb_info *info);
+ static void fbcon_set_all_vcs(struct fb_info *info);
+ static void fbcon_start(void);
+@@ -1126,6 +1136,14 @@ static void fbcon_init(struct vc_data *v
+       ops->graphics = 0;
+       /*
++       * No more hw acceleration for fbcon.
++       *
++       * FIXME: Garbage collect all the now dead code after sufficient time
++       * has passed.
++       */
++      p->scrollmode = SCROLL_REDRAW;
++
++      /*
+        *  ++guenther: console.c:vc_allocate() relies on initializing
+        *  vc_{cols,rows}, but we must not set those if we are only
+        *  resizing the console.
+@@ -1211,13 +1229,14 @@ finished:
+  *  This system is now divided into two levels because of complications
+  *  caused by hardware scrolling. Top level functions:
+  *
+- *    fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
++ *    fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
+  *
+  *  handles y values in range [0, scr_height-1] that correspond to real
+  *  screen positions. y_wrap shift means that first line of bitmap may be
+  *  anywhere on this display. These functions convert lineoffsets to
+  *  bitmap offsets and deal with the wrap-around case by splitting blits.
+  *
++ *    fbcon_bmove_physical_8()    -- These functions fast implementations
+  *    fbcon_clear_physical_8()    -- of original fbcon_XXX fns.
+  *    fbcon_putc_physical_8()     -- (font width != 8) may be added later
+  *
+@@ -1390,6 +1409,224 @@ static void fbcon_set_disp(struct fb_inf
+       }
+ }
++static __inline__ void ywrap_up(struct vc_data *vc, int count)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++
++      p->yscroll += count;
++      if (p->yscroll >= p->vrows)     /* Deal with wrap */
++              p->yscroll -= p->vrows;
++      ops->var.xoffset = 0;
++      ops->var.yoffset = p->yscroll * vc->vc_font.height;
++      ops->var.vmode |= FB_VMODE_YWRAP;
++      ops->update_start(info);
++      scrollback_max += count;
++      if (scrollback_max > scrollback_phys_max)
++              scrollback_max = scrollback_phys_max;
++      scrollback_current = 0;
++}
++
++static __inline__ void ywrap_down(struct vc_data *vc, int count)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++
++      p->yscroll -= count;
++      if (p->yscroll < 0)     /* Deal with wrap */
++              p->yscroll += p->vrows;
++      ops->var.xoffset = 0;
++      ops->var.yoffset = p->yscroll * vc->vc_font.height;
++      ops->var.vmode |= FB_VMODE_YWRAP;
++      ops->update_start(info);
++      scrollback_max -= count;
++      if (scrollback_max < 0)
++              scrollback_max = 0;
++      scrollback_current = 0;
++}
++
++static __inline__ void ypan_up(struct vc_data *vc, int count)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++      struct fbcon_ops *ops = info->fbcon_par;
++
++      p->yscroll += count;
++      if (p->yscroll > p->vrows - vc->vc_rows) {
++              ops->bmove(vc, info, p->vrows - vc->vc_rows,
++                          0, 0, 0, vc->vc_rows, vc->vc_cols);
++              p->yscroll -= p->vrows - vc->vc_rows;
++      }
++
++      ops->var.xoffset = 0;
++      ops->var.yoffset = p->yscroll * vc->vc_font.height;
++      ops->var.vmode &= ~FB_VMODE_YWRAP;
++      ops->update_start(info);
++      fbcon_clear_margins(vc, 1);
++      scrollback_max += count;
++      if (scrollback_max > scrollback_phys_max)
++              scrollback_max = scrollback_phys_max;
++      scrollback_current = 0;
++}
++
++static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++
++      p->yscroll += count;
++
++      if (p->yscroll > p->vrows - vc->vc_rows) {
++              p->yscroll -= p->vrows - vc->vc_rows;
++              fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
++      }
++
++      ops->var.xoffset = 0;
++      ops->var.yoffset = p->yscroll * vc->vc_font.height;
++      ops->var.vmode &= ~FB_VMODE_YWRAP;
++      ops->update_start(info);
++      fbcon_clear_margins(vc, 1);
++      scrollback_max += count;
++      if (scrollback_max > scrollback_phys_max)
++              scrollback_max = scrollback_phys_max;
++      scrollback_current = 0;
++}
++
++static __inline__ void ypan_down(struct vc_data *vc, int count)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++      struct fbcon_ops *ops = info->fbcon_par;
++
++      p->yscroll -= count;
++      if (p->yscroll < 0) {
++              ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
++                          0, vc->vc_rows, vc->vc_cols);
++              p->yscroll += p->vrows - vc->vc_rows;
++      }
++
++      ops->var.xoffset = 0;
++      ops->var.yoffset = p->yscroll * vc->vc_font.height;
++      ops->var.vmode &= ~FB_VMODE_YWRAP;
++      ops->update_start(info);
++      fbcon_clear_margins(vc, 1);
++      scrollback_max -= count;
++      if (scrollback_max < 0)
++              scrollback_max = 0;
++      scrollback_current = 0;
++}
++
++static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++
++      p->yscroll -= count;
++
++      if (p->yscroll < 0) {
++              p->yscroll += p->vrows - vc->vc_rows;
++              fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
++      }
++
++      ops->var.xoffset = 0;
++      ops->var.yoffset = p->yscroll * vc->vc_font.height;
++      ops->var.vmode &= ~FB_VMODE_YWRAP;
++      ops->update_start(info);
++      fbcon_clear_margins(vc, 1);
++      scrollback_max -= count;
++      if (scrollback_max < 0)
++              scrollback_max = 0;
++      scrollback_current = 0;
++}
++
++static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
++                            int line, int count, int dy)
++{
++      unsigned short *s = (unsigned short *)
++              (vc->vc_origin + vc->vc_size_row * line);
++
++      while (count--) {
++              unsigned short *start = s;
++              unsigned short *le = advance_row(s, 1);
++              unsigned short c;
++              int x = 0;
++              unsigned short attr = 1;
++
++              do {
++                      c = scr_readw(s);
++                      if (attr != (c & 0xff00)) {
++                              attr = c & 0xff00;
++                              if (s > start) {
++                                      fbcon_putcs(vc, start, s - start,
++                                                  dy, x);
++                                      x += s - start;
++                                      start = s;
++                              }
++                      }
++                      console_conditional_schedule();
++                      s++;
++              } while (s < le);
++              if (s > start)
++                      fbcon_putcs(vc, start, s - start, dy, x);
++              console_conditional_schedule();
++              dy++;
++      }
++}
++
++static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
++                      struct fbcon_display *p, int line, int count, int ycount)
++{
++      int offset = ycount * vc->vc_cols;
++      unsigned short *d = (unsigned short *)
++          (vc->vc_origin + vc->vc_size_row * line);
++      unsigned short *s = d + offset;
++      struct fbcon_ops *ops = info->fbcon_par;
++
++      while (count--) {
++              unsigned short *start = s;
++              unsigned short *le = advance_row(s, 1);
++              unsigned short c;
++              int x = 0;
++
++              do {
++                      c = scr_readw(s);
++
++                      if (c == scr_readw(d)) {
++                              if (s > start) {
++                                      ops->bmove(vc, info, line + ycount, x,
++                                                 line, x, 1, s-start);
++                                      x += s - start + 1;
++                                      start = s + 1;
++                              } else {
++                                      x++;
++                                      start++;
++                              }
++                      }
++
++                      scr_writew(c, d);
++                      console_conditional_schedule();
++                      s++;
++                      d++;
++              } while (s < le);
++              if (s > start)
++                      ops->bmove(vc, info, line + ycount, x, line, x, 1,
++                                 s-start);
++              console_conditional_schedule();
++              if (ycount > 0)
++                      line++;
++              else {
++                      line--;
++                      /* NOTE: We subtract two lines from these pointers */
++                      s -= vc->vc_size_row;
++                      d -= vc->vc_size_row;
++              }
++      }
++}
++
+ static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p,
+                        int line, int count, int offset)
+ {
+@@ -1450,6 +1687,7 @@ static bool fbcon_scroll(struct vc_data
+ {
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_display *p = &fb_display[vc->vc_num];
++      int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
+       if (fbcon_is_inactive(vc, info))
+               return true;
+@@ -1466,32 +1704,249 @@ static bool fbcon_scroll(struct vc_data
+       case SM_UP:
+               if (count > vc->vc_rows)        /* Maximum realistic size */
+                       count = vc->vc_rows;
+-              fbcon_redraw(vc, p, t, b - t - count,
+-                           count * vc->vc_cols);
+-              fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+-              scr_memsetw((unsigned short *) (vc->vc_origin +
+-                                              vc->vc_size_row *
+-                                              (b - count)),
+-                          vc->vc_video_erase_char,
+-                          vc->vc_size_row * count);
+-              return true;
++              if (logo_shown >= 0)
++                      goto redraw_up;
++              switch (p->scrollmode) {
++              case SCROLL_MOVE:
++                      fbcon_redraw_blit(vc, info, p, t, b - t - count,
++                                   count);
++                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      scr_memsetw((unsigned short *) (vc->vc_origin +
++                                                      vc->vc_size_row *
++                                                      (b - count)),
++                                  vc->vc_video_erase_char,
++                                  vc->vc_size_row * count);
++                      return true;
++
++              case SCROLL_WRAP_MOVE:
++                      if (b - t - count > 3 * vc->vc_rows >> 2) {
++                              if (t > 0)
++                                      fbcon_bmove(vc, 0, 0, count, 0, t,
++                                                  vc->vc_cols);
++                              ywrap_up(vc, count);
++                              if (vc->vc_rows - b > 0)
++                                      fbcon_bmove(vc, b - count, 0, b, 0,
++                                                  vc->vc_rows - b,
++                                                  vc->vc_cols);
++                      } else if (info->flags & FBINFO_READS_FAST)
++                              fbcon_bmove(vc, t + count, 0, t, 0,
++                                          b - t - count, vc->vc_cols);
++                      else
++                              goto redraw_up;
++                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      break;
++
++              case SCROLL_PAN_REDRAW:
++                      if ((p->yscroll + count <=
++                           2 * (p->vrows - vc->vc_rows))
++                          && ((!scroll_partial && (b - t == vc->vc_rows))
++                              || (scroll_partial
++                                  && (b - t - count >
++                                      3 * vc->vc_rows >> 2)))) {
++                              if (t > 0)
++                                      fbcon_redraw_move(vc, p, 0, t, count);
++                              ypan_up_redraw(vc, t, count);
++                              if (vc->vc_rows - b > 0)
++                                      fbcon_redraw_move(vc, p, b,
++                                                        vc->vc_rows - b, b);
++                      } else
++                              fbcon_redraw_move(vc, p, t + count, b - t - count, t);
++                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      break;
++
++              case SCROLL_PAN_MOVE:
++                      if ((p->yscroll + count <=
++                           2 * (p->vrows - vc->vc_rows))
++                          && ((!scroll_partial && (b - t == vc->vc_rows))
++                              || (scroll_partial
++                                  && (b - t - count >
++                                      3 * vc->vc_rows >> 2)))) {
++                              if (t > 0)
++                                      fbcon_bmove(vc, 0, 0, count, 0, t,
++                                                  vc->vc_cols);
++                              ypan_up(vc, count);
++                              if (vc->vc_rows - b > 0)
++                                      fbcon_bmove(vc, b - count, 0, b, 0,
++                                                  vc->vc_rows - b,
++                                                  vc->vc_cols);
++                      } else if (info->flags & FBINFO_READS_FAST)
++                              fbcon_bmove(vc, t + count, 0, t, 0,
++                                          b - t - count, vc->vc_cols);
++                      else
++                              goto redraw_up;
++                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      break;
++
++              case SCROLL_REDRAW:
++                    redraw_up:
++                      fbcon_redraw(vc, p, t, b - t - count,
++                                   count * vc->vc_cols);
++                      fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
++                      scr_memsetw((unsigned short *) (vc->vc_origin +
++                                                      vc->vc_size_row *
++                                                      (b - count)),
++                                  vc->vc_video_erase_char,
++                                  vc->vc_size_row * count);
++                      return true;
++              }
++              break;
+       case SM_DOWN:
+               if (count > vc->vc_rows)        /* Maximum realistic size */
+                       count = vc->vc_rows;
+-              fbcon_redraw(vc, p, b - 1, b - t - count,
+-                           -count * vc->vc_cols);
+-              fbcon_clear(vc, t, 0, count, vc->vc_cols);
+-              scr_memsetw((unsigned short *) (vc->vc_origin +
+-                                              vc->vc_size_row *
+-                                              t),
+-                          vc->vc_video_erase_char,
+-                          vc->vc_size_row * count);
+-              return true;
++              if (logo_shown >= 0)
++                      goto redraw_down;
++              switch (p->scrollmode) {
++              case SCROLL_MOVE:
++                      fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
++                                   -count);
++                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      scr_memsetw((unsigned short *) (vc->vc_origin +
++                                                      vc->vc_size_row *
++                                                      t),
++                                  vc->vc_video_erase_char,
++                                  vc->vc_size_row * count);
++                      return true;
++
++              case SCROLL_WRAP_MOVE:
++                      if (b - t - count > 3 * vc->vc_rows >> 2) {
++                              if (vc->vc_rows - b > 0)
++                                      fbcon_bmove(vc, b, 0, b - count, 0,
++                                                  vc->vc_rows - b,
++                                                  vc->vc_cols);
++                              ywrap_down(vc, count);
++                              if (t > 0)
++                                      fbcon_bmove(vc, count, 0, 0, 0, t,
++                                                  vc->vc_cols);
++                      } else if (info->flags & FBINFO_READS_FAST)
++                              fbcon_bmove(vc, t, 0, t + count, 0,
++                                          b - t - count, vc->vc_cols);
++                      else
++                              goto redraw_down;
++                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      break;
++
++              case SCROLL_PAN_MOVE:
++                      if ((count - p->yscroll <= p->vrows - vc->vc_rows)
++                          && ((!scroll_partial && (b - t == vc->vc_rows))
++                              || (scroll_partial
++                                  && (b - t - count >
++                                      3 * vc->vc_rows >> 2)))) {
++                              if (vc->vc_rows - b > 0)
++                                      fbcon_bmove(vc, b, 0, b - count, 0,
++                                                  vc->vc_rows - b,
++                                                  vc->vc_cols);
++                              ypan_down(vc, count);
++                              if (t > 0)
++                                      fbcon_bmove(vc, count, 0, 0, 0, t,
++                                                  vc->vc_cols);
++                      } else if (info->flags & FBINFO_READS_FAST)
++                              fbcon_bmove(vc, t, 0, t + count, 0,
++                                          b - t - count, vc->vc_cols);
++                      else
++                              goto redraw_down;
++                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      break;
++
++              case SCROLL_PAN_REDRAW:
++                      if ((count - p->yscroll <= p->vrows - vc->vc_rows)
++                          && ((!scroll_partial && (b - t == vc->vc_rows))
++                              || (scroll_partial
++                                  && (b - t - count >
++                                      3 * vc->vc_rows >> 2)))) {
++                              if (vc->vc_rows - b > 0)
++                                      fbcon_redraw_move(vc, p, b, vc->vc_rows - b,
++                                                        b - count);
++                              ypan_down_redraw(vc, t, count);
++                              if (t > 0)
++                                      fbcon_redraw_move(vc, p, count, t, 0);
++                      } else
++                              fbcon_redraw_move(vc, p, t, b - t - count, t + count);
++                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      break;
++
++              case SCROLL_REDRAW:
++                    redraw_down:
++                      fbcon_redraw(vc, p, b - 1, b - t - count,
++                                   -count * vc->vc_cols);
++                      fbcon_clear(vc, t, 0, count, vc->vc_cols);
++                      scr_memsetw((unsigned short *) (vc->vc_origin +
++                                                      vc->vc_size_row *
++                                                      t),
++                                  vc->vc_video_erase_char,
++                                  vc->vc_size_row * count);
++                      return true;
++              }
+       }
+       return false;
+ }
++
++static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
++                      int height, int width)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_display *p = &fb_display[vc->vc_num];
++
++      if (fbcon_is_inactive(vc, info))
++              return;
++
++      if (!width || !height)
++              return;
++
++      /*  Split blits that cross physical y_wrap case.
++       *  Pathological case involves 4 blits, better to use recursive
++       *  code rather than unrolled case
++       *
++       *  Recursive invocations don't need to erase the cursor over and
++       *  over again, so we use fbcon_bmove_rec()
++       */
++      fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,
++                      p->vrows - p->yscroll);
++}
++
++static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
++                          int dy, int dx, int height, int width, u_int y_break)
++{
++      struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
++      struct fbcon_ops *ops = info->fbcon_par;
++      u_int b;
++
++      if (sy < y_break && sy + height > y_break) {
++              b = y_break - sy;
++              if (dy < sy) {  /* Avoid trashing self */
++                      fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
++                                      y_break);
++                      fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
++                                      height - b, width, y_break);
++              } else {
++                      fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
++                                      height - b, width, y_break);
++                      fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
++                                      y_break);
++              }
++              return;
++      }
++
++      if (dy < y_break && dy + height > y_break) {
++              b = y_break - dy;
++              if (dy < sy) {  /* Avoid trashing self */
++                      fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
++                                      y_break);
++                      fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
++                                      height - b, width, y_break);
++              } else {
++                      fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
++                                      height - b, width, y_break);
++                      fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
++                                      y_break);
++              }
++              return;
++      }
++      ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
++                 height, width);
++}
++
+ static void updatescrollmode(struct fbcon_display *p,
+                                       struct fb_info *info,
+                                       struct vc_data *vc)
+@@ -1664,7 +2119,21 @@ static int fbcon_switch(struct vc_data *
+       updatescrollmode(p, info, vc);
+-      scrollback_phys_max = 0;
++      switch (p->scrollmode) {
++      case SCROLL_WRAP_MOVE:
++              scrollback_phys_max = p->vrows - vc->vc_rows;
++              break;
++      case SCROLL_PAN_MOVE:
++      case SCROLL_PAN_REDRAW:
++              scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
++              if (scrollback_phys_max < 0)
++                      scrollback_phys_max = 0;
++              break;
++      default:
++              scrollback_phys_max = 0;
++              break;
++      }
++
+       scrollback_max = 0;
+       scrollback_current = 0;
+--- a/drivers/video/fbdev/core/fbcon.h
++++ b/drivers/video/fbdev/core/fbcon.h
+@@ -29,6 +29,7 @@ struct fbcon_display {
+     /* Filled in by the low-level console driver */
+     const u_char *fontdata;
+     int userfont;                   /* != 0 if fontdata kmalloc()ed */
++    u_short scrollmode;             /* Scroll Method */
+     u_short inverse;                /* != 0 text black on white as default */
+     short yscroll;                  /* Hardware scrolling */
+     int vrows;                      /* number of virtual rows */
+@@ -51,6 +52,8 @@ struct fbcon_display {
+ };
+ struct fbcon_ops {
++      void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
++                    int sx, int dy, int dx, int height, int width);
+       void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
+                     int sx, int height, int width);
+       void (*putcs)(struct vc_data *vc, struct fb_info *info,
+@@ -149,6 +152,62 @@ static inline int attr_col_ec(int shift,
+ #define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0)
+ #define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1)
++    /*
++     *  Scroll Method
++     */
++
++/* There are several methods fbcon can use to move text around the screen:
++ *
++ *                     Operation   Pan    Wrap
++ *---------------------------------------------
++ * SCROLL_MOVE         copyarea    No     No
++ * SCROLL_PAN_MOVE     copyarea    Yes    No
++ * SCROLL_WRAP_MOVE    copyarea    No     Yes
++ * SCROLL_REDRAW       imageblit   No     No
++ * SCROLL_PAN_REDRAW   imageblit   Yes    No
++ * SCROLL_WRAP_REDRAW  imageblit   No     Yes
++ *
++ * (SCROLL_WRAP_REDRAW is not implemented yet)
++ *
++ * In general, fbcon will choose the best scrolling
++ * method based on the rule below:
++ *
++ * Pan/Wrap > accel imageblit > accel copyarea >
++ * soft imageblit > (soft copyarea)
++ *
++ * Exception to the rule: Pan + accel copyarea is
++ * preferred over Pan + accel imageblit.
++ *
++ * The above is typical for PCI/AGP cards. Unless
++ * overridden, fbcon will never use soft copyarea.
++ *
++ * If you need to override the above rule, set the
++ * appropriate flags in fb_info->flags.  For example,
++ * to prefer copyarea over imageblit, set
++ * FBINFO_READS_FAST.
++ *
++ * Other notes:
++ * + use the hardware engine to move the text
++ *    (hw-accelerated copyarea() and fillrect())
++ * + use hardware-supported panning on a large virtual screen
++ * + amifb can not only pan, but also wrap the display by N lines
++ *    (i.e. visible line i = physical line (i+N) % yres).
++ * + read what's already rendered on the screen and
++ *     write it in a different place (this is cfb_copyarea())
++ * + re-render the text to the screen
++ *
++ * Whether to use wrapping or panning can only be figured out at
++ * runtime (when we know whether our font height is a multiple
++ * of the pan/wrap step)
++ *
++ */
++
++#define SCROLL_MOVE      0x001
++#define SCROLL_PAN_MOVE          0x002
++#define SCROLL_WRAP_MOVE   0x003
++#define SCROLL_REDRAW    0x004
++#define SCROLL_PAN_REDRAW  0x005
++
+ #ifdef CONFIG_FB_TILEBLITTING
+ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
+ #endif
+--- a/drivers/video/fbdev/core/fbcon_ccw.c
++++ b/drivers/video/fbdev/core/fbcon_ccw.c
+@@ -59,12 +59,31 @@ static void ccw_update_attr(u8 *dst, u8
+       }
+ }
++
++static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
++                   int sx, int dy, int dx, int height, int width)
++{
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fb_copyarea area;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++
++      area.sx = sy * vc->vc_font.height;
++      area.sy = vyres - ((sx + width) * vc->vc_font.width);
++      area.dx = dy * vc->vc_font.height;
++      area.dy = vyres - ((dx + width) * vc->vc_font.width);
++      area.width = height * vc->vc_font.height;
++      area.height  = width * vc->vc_font.width;
++
++      info->fbops->fb_copyarea(info, &area);
++}
++
+ static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
+                    int sx, int height, int width)
+ {
++      struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_fillrect region;
+       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-      u32 vyres = info->var.yres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+       region.color = attr_bgcol_ec(bgshift,vc,info);
+       region.dx = sy * vc->vc_font.height;
+@@ -121,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc
+       u32 cnt, pitch, size;
+       u32 attribute = get_attribute(info, scr_readw(s));
+       u8 *dst, *buf = NULL;
+-      u32 vyres = info->var.yres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -210,7 +229,7 @@ static void ccw_cursor(struct vc_data *v
+       int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
+       int err = 1, dx, dy;
+       char *src;
+-      u32 vyres = info->var.yres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -368,7 +387,7 @@ static int ccw_update_start(struct fb_in
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       u32 yoffset;
+-      u32 vyres = info->var.yres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
+       int err;
+       yoffset = (vyres - info->var.yres) - ops->var.xoffset;
+@@ -383,6 +402,7 @@ static int ccw_update_start(struct fb_in
+ void fbcon_rotate_ccw(struct fbcon_ops *ops)
+ {
++      ops->bmove = ccw_bmove;
+       ops->clear = ccw_clear;
+       ops->putcs = ccw_putcs;
+       ops->clear_margins = ccw_clear_margins;
+--- a/drivers/video/fbdev/core/fbcon_cw.c
++++ b/drivers/video/fbdev/core/fbcon_cw.c
+@@ -44,12 +44,31 @@ static void cw_update_attr(u8 *dst, u8 *
+       }
+ }
++
++static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
++                   int sx, int dy, int dx, int height, int width)
++{
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fb_copyarea area;
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++
++      area.sx = vxres - ((sy + height) * vc->vc_font.height);
++      area.sy = sx * vc->vc_font.width;
++      area.dx = vxres - ((dy + height) * vc->vc_font.height);
++      area.dy = dx * vc->vc_font.width;
++      area.width = height * vc->vc_font.height;
++      area.height  = width * vc->vc_font.width;
++
++      info->fbops->fb_copyarea(info, &area);
++}
++
+ static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
+                    int sx, int height, int width)
+ {
++      struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_fillrect region;
+       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-      u32 vxres = info->var.xres;
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       region.color = attr_bgcol_ec(bgshift,vc,info);
+       region.dx = vxres - ((sy + height) * vc->vc_font.height);
+@@ -106,7 +125,7 @@ static void cw_putcs(struct vc_data *vc,
+       u32 cnt, pitch, size;
+       u32 attribute = get_attribute(info, scr_readw(s));
+       u8 *dst, *buf = NULL;
+-      u32 vxres = info->var.xres;
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -193,7 +212,7 @@ static void cw_cursor(struct vc_data *vc
+       int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
+       int err = 1, dx, dy;
+       char *src;
+-      u32 vxres = info->var.xres;
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -350,7 +369,7 @@ static void cw_cursor(struct vc_data *vc
+ static int cw_update_start(struct fb_info *info)
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+-      u32 vxres = info->var.xres;
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       u32 xoffset;
+       int err;
+@@ -366,6 +385,7 @@ static int cw_update_start(struct fb_inf
+ void fbcon_rotate_cw(struct fbcon_ops *ops)
+ {
++      ops->bmove = cw_bmove;
+       ops->clear = cw_clear;
+       ops->putcs = cw_putcs;
+       ops->clear_margins = cw_clear_margins;
+--- a/drivers/video/fbdev/core/fbcon_rotate.h
++++ b/drivers/video/fbdev/core/fbcon_rotate.h
+@@ -11,6 +11,15 @@
+ #ifndef _FBCON_ROTATE_H
+ #define _FBCON_ROTATE_H
++#define GETVYRES(s,i) ({                           \
++        (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
++        (i)->var.yres : (i)->var.yres_virtual; })
++
++#define GETVXRES(s,i) ({                           \
++        (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
++        (i)->var.xres : (i)->var.xres_virtual; })
++
++
+ static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
+ {
+       u32 tmp = (y * pitch) + x, index = tmp / 8,  bit = tmp % 8;
+--- a/drivers/video/fbdev/core/fbcon_ud.c
++++ b/drivers/video/fbdev/core/fbcon_ud.c
+@@ -44,13 +44,33 @@ static void ud_update_attr(u8 *dst, u8 *
+       }
+ }
++
++static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
++                   int sx, int dy, int dx, int height, int width)
++{
++      struct fbcon_ops *ops = info->fbcon_par;
++      struct fb_copyarea area;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
++
++      area.sy = vyres - ((sy + height) * vc->vc_font.height);
++      area.sx = vxres - ((sx + width) * vc->vc_font.width);
++      area.dy = vyres - ((dy + height) * vc->vc_font.height);
++      area.dx = vxres - ((dx + width) * vc->vc_font.width);
++      area.height = height * vc->vc_font.height;
++      area.width  = width * vc->vc_font.width;
++
++      info->fbops->fb_copyarea(info, &area);
++}
++
+ static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
+                    int sx, int height, int width)
+ {
++      struct fbcon_ops *ops = info->fbcon_par;
+       struct fb_fillrect region;
+       int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+-      u32 vyres = info->var.yres;
+-      u32 vxres = info->var.xres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       region.color = attr_bgcol_ec(bgshift,vc,info);
+       region.dy = vyres - ((sy + height) * vc->vc_font.height);
+@@ -142,8 +162,8 @@ static void ud_putcs(struct vc_data *vc,
+       u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
+       u32 attribute = get_attribute(info, scr_readw(s));
+       u8 *dst, *buf = NULL;
+-      u32 vyres = info->var.yres;
+-      u32 vxres = info->var.xres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -239,8 +259,8 @@ static void ud_cursor(struct vc_data *vc
+       int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
+       int err = 1, dx, dy;
+       char *src;
+-      u32 vyres = info->var.yres;
+-      u32 vxres = info->var.xres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       if (!ops->fontbuffer)
+               return;
+@@ -390,8 +410,8 @@ static int ud_update_start(struct fb_inf
+ {
+       struct fbcon_ops *ops = info->fbcon_par;
+       int xoffset, yoffset;
+-      u32 vyres = info->var.yres;
+-      u32 vxres = info->var.xres;
++      u32 vyres = GETVYRES(ops->p->scrollmode, info);
++      u32 vxres = GETVXRES(ops->p->scrollmode, info);
+       int err;
+       xoffset = vxres - info->var.xres - ops->var.xoffset;
+@@ -409,6 +429,7 @@ static int ud_update_start(struct fb_inf
+ void fbcon_rotate_ud(struct fbcon_ops *ops)
+ {
++      ops->bmove = ud_bmove;
+       ops->clear = ud_clear;
+       ops->putcs = ud_putcs;
+       ops->clear_margins = ud_clear_margins;
+--- a/drivers/video/fbdev/core/tileblit.c
++++ b/drivers/video/fbdev/core/tileblit.c
+@@ -16,6 +16,21 @@
+ #include <asm/types.h>
+ #include "fbcon.h"
++static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
++                     int sx, int dy, int dx, int height, int width)
++{
++      struct fb_tilearea area;
++
++      area.sx = sx;
++      area.sy = sy;
++      area.dx = dx;
++      area.dy = dy;
++      area.height = height;
++      area.width = width;
++
++      info->tileops->fb_tilecopy(info, &area);
++}
++
+ static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
+                      int sx, int height, int width)
+ {
+@@ -118,6 +133,7 @@ void fbcon_set_tileops(struct vc_data *v
+       struct fb_tilemap map;
+       struct fbcon_ops *ops = info->fbcon_par;
++      ops->bmove = tile_bmove;
+       ops->clear = tile_clear;
+       ops->putcs = tile_putcs;
+       ops->clear_margins = tile_clear_margins;
+--- a/drivers/video/fbdev/skeletonfb.c
++++ b/drivers/video/fbdev/skeletonfb.c
+@@ -505,15 +505,15 @@ void xxxfb_fillrect(struct fb_info *p, c
+ }
+ /**
+- *      xxxfb_copyarea - OBSOLETE function.
++ *      xxxfb_copyarea - REQUIRED function. Can use generic routines if
++ *                       non acclerated hardware and packed pixel based.
+  *                       Copies one area of the screen to another area.
+- *                       Will be deleted in a future version
+  *
+  *      @info: frame buffer structure that represents a single frame buffer
+  *      @area: Structure providing the data to copy the framebuffer contents
+  *           from one region to another.
+  *
+- *      This drawing operation copied a rectangular area from one area of the
++ *      This drawing operation copies a rectangular area from one area of the
+  *    screen to another area.
+  */
+ void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 
+@@ -645,9 +645,9 @@ static const struct fb_ops xxxfb_ops = {
+       .fb_setcolreg   = xxxfb_setcolreg,
+       .fb_blank       = xxxfb_blank,
+       .fb_pan_display = xxxfb_pan_display,
+-      .fb_fillrect    = xxxfb_fillrect,       /* Needed !!!   */
+-      .fb_copyarea    = xxxfb_copyarea,       /* Obsolete     */
+-      .fb_imageblit   = xxxfb_imageblit,      /* Needed !!!   */
++      .fb_fillrect    = xxxfb_fillrect,       /* Needed !!! */
++      .fb_copyarea    = xxxfb_copyarea,       /* Needed !!! */
++      .fb_imageblit   = xxxfb_imageblit,      /* Needed !!! */
+       .fb_cursor      = xxxfb_cursor,         /* Optional !!! */
+       .fb_sync        = xxxfb_sync,
+       .fb_ioctl       = xxxfb_ioctl,
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -262,7 +262,7 @@ struct fb_ops {
+       /* Draws a rectangle */
+       void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
+-      /* Copy data from area to another. Obsolete. */
++      /* Copy data from area to another */
+       void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
+       /* Draws a image to the display */
+       void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
diff --git a/queue-5.16/revert-fs-9p-search-open-fids-first.patch b/queue-5.16/revert-fs-9p-search-open-fids-first.patch
new file mode 100644 (file)
index 0000000..de0cded
--- /dev/null
@@ -0,0 +1,67 @@
+From 22e424feb6658c5d6789e45121830357809c59cb Mon Sep 17 00:00:00 2001
+From: Dominique Martinet <asmadeus@codewreck.org>
+Date: Sat, 29 Jan 2022 18:42:59 +0900
+Subject: Revert "fs/9p: search open fids first"
+
+From: Dominique Martinet <asmadeus@codewreck.org>
+
+commit 22e424feb6658c5d6789e45121830357809c59cb upstream.
+
+This reverts commit 478ba09edc1f2f2ee27180a06150cb2d1a686f9c.
+
+That commit was meant as a fix for setattrs with by fd (e.g. ftruncate)
+to use an open fid instead of the first fid it found on lookup.
+The proper fix for that is to use the fid associated with the open file
+struct, available in iattr->ia_file for such operations, and was
+actually done just before in 66246641609b ("9p: retrieve fid from file
+when file instance exist.")
+As such, this commit is no longer required.
+
+Furthermore, changing lookup to return open fids first had unwanted side
+effects, as it turns out the protocol forbids the use of open fids for
+further walks (e.g. clone_fid) and we broke mounts for some servers
+enforcing this rule.
+
+Note this only reverts to the old working behaviour, but it's still
+possible for lookup to return open fids if dentry->d_fsdata is not set,
+so more work is needed to make sure we respect this rule in the future,
+for example by adding a flag to the lookup functions to only match
+certain fid open modes depending on caller requirements.
+
+Link: https://lkml.kernel.org/r/20220130130651.712293-1-asmadeus@codewreck.org
+Fixes: 478ba09edc1f ("fs/9p: search open fids first")
+Cc: stable@vger.kernel.org # v5.11+
+Reported-by: ron minnich <rminnich@gmail.com>
+Reported-by: ng@0x80.stream
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/9p/fid.c |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/fs/9p/fid.c
++++ b/fs/9p/fid.c
+@@ -96,12 +96,8 @@ static struct p9_fid *v9fs_fid_find(stru
+                dentry, dentry, from_kuid(&init_user_ns, uid),
+                any);
+       ret = NULL;
+-
+-      if (d_inode(dentry))
+-              ret = v9fs_fid_find_inode(d_inode(dentry), uid);
+-
+       /* we'll recheck under lock if there's anything to look in */
+-      if (!ret && dentry->d_fsdata) {
++      if (dentry->d_fsdata) {
+               struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
+               spin_lock(&dentry->d_lock);
+@@ -113,6 +109,9 @@ static struct p9_fid *v9fs_fid_find(stru
+                       }
+               }
+               spin_unlock(&dentry->d_lock);
++      } else {
++              if (dentry->d_inode)
++                      ret = v9fs_fid_find_inode(dentry->d_inode, uid);
+       }
+       return ret;
diff --git a/queue-5.16/selinux-fix-double-free-of-cond_list-on-error-paths.patch b/queue-5.16/selinux-fix-double-free-of-cond_list-on-error-paths.patch
new file mode 100644 (file)
index 0000000..3c222e4
--- /dev/null
@@ -0,0 +1,45 @@
+From 186edf7e368c40d06cf727a1ad14698ea67b74ad Mon Sep 17 00:00:00 2001
+From: Vratislav Bendel <vbendel@redhat.com>
+Date: Wed, 2 Feb 2022 12:25:11 +0100
+Subject: selinux: fix double free of cond_list on error paths
+
+From: Vratislav Bendel <vbendel@redhat.com>
+
+commit 186edf7e368c40d06cf727a1ad14698ea67b74ad upstream.
+
+On error path from cond_read_list() and duplicate_policydb_cond_list()
+the cond_list_destroy() gets called a second time in caller functions,
+resulting in NULL pointer deref.  Fix this by resetting the
+cond_list_len to 0 in cond_list_destroy(), making subsequent calls a
+noop.
+
+Also consistently reset the cond_list pointer to NULL after freeing.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Vratislav Bendel <vbendel@redhat.com>
+[PM: fix line lengths in the description]
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ security/selinux/ss/conditional.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/security/selinux/ss/conditional.c
++++ b/security/selinux/ss/conditional.c
+@@ -152,6 +152,8 @@ static void cond_list_destroy(struct pol
+       for (i = 0; i < p->cond_list_len; i++)
+               cond_node_destroy(&p->cond_list[i]);
+       kfree(p->cond_list);
++      p->cond_list = NULL;
++      p->cond_list_len = 0;
+ }
+ void cond_policydb_destroy(struct policydb *p)
+@@ -441,7 +443,6 @@ int cond_read_list(struct policydb *p, v
+       return 0;
+ err:
+       cond_list_destroy(p);
+-      p->cond_list = NULL;
+       return rc;
+ }
diff --git a/queue-5.16/series b/queue-5.16/series
new file mode 100644 (file)
index 0000000..5462035
--- /dev/null
@@ -0,0 +1,42 @@
+drm-i915-disable-dsb-usage-for-now.patch
+selinux-fix-double-free-of-cond_list-on-error-paths.patch
+audit-improve-audit-queue-handling-when-audit-1-on-cmdline.patch
+ipc-sem-do-not-sleep-with-a-spin-lock-held.patch
+spi-stm32-qspi-update-spi-registering.patch
+asoc-hdmi-codec-fix-oob-memory-accesses.patch
+asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw.patch
+asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_volsw_sx.patch
+asoc-ops-reject-out-of-bounds-values-in-snd_soc_put_xr_sx.patch
+alsa-usb-audio-correct-quirk-for-vf0770.patch
+alsa-hda-fix-uaf-of-leds-class-devs-at-unbinding.patch
+alsa-hda-realtek-fix-race-at-concurrent-coef-updates.patch
+alsa-hda-realtek-add-quirk-for-asus-gu603.patch
+alsa-hda-realtek-add-missing-fixup-model-entry-for-gigabyte-x570-alc1220-quirks.patch
+alsa-hda-realtek-fix-silent-output-on-gigabyte-x570s-aorus-master-newer-chipset.patch
+alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-xtreme-after-reboot-from-windows.patch
+ata-libata-core-introduce-ata_horkage_no_log_dir-horkage.patch
+btrfs-don-t-start-transaction-for-scrub-if-the-fs-is-mounted-read-only.patch
+btrfs-fix-deadlock-between-quota-disable-and-qgroup-rescan-worker.patch
+btrfs-fix-use-after-free-after-failure-to-create-a-snapshot.patch
+revert-fs-9p-search-open-fids-first.patch
+drm-nouveau-fix-off-by-one-in-bios-boundary-checking.patch
+drm-i915-adlp-fix-typec-phy-ready-status-readout.patch
+drm-amdgpu-fix-a-potential-gpu-hang-on-cyan-skillfish.patch
+drm-amd-pm-correct-the-mgpufanboost-support-for-beige-goby.patch
+drm-amd-display-update-watermark-values-for-dcn301.patch
+drm-amd-display-watermark-latencies-is-not-enough-on-dcn31.patch
+drm-amd-display-force-link_rate-as-link_rate_rbr2-for-2018-15-apple-retina-panels.patch
+nvme-fabrics-fix-state-check-in-nvmf_ctlr_matches_baseopts.patch
+mm-debug_vm_pgtable-remove-pte-entry-from-the-page-table.patch
+mm-pgtable-define-pte_index-so-that-preprocessor-could-recognize-it.patch
+mm-kmemleak-avoid-scanning-potential-huge-holes.patch
+block-bio-integrity-advance-seed-correctly-for-larger-interval-sizes.patch
+cifs-fix-workstation_name-for-multiuser-mounts.patch
+dma-buf-heaps-fix-potential-spectre-v1-gadget.patch
+ib-hfi1-fix-panic-with-larger-ipoib-send_queue_size.patch
+ib-hfi1-fix-alloc-failure-with-larger-txqueuelen.patch
+ib-hfi1-fix-aip-early-init-panic.patch
+revert-fbdev-garbage-collect-fbdev-scrolling-acceleration-part-1-from-todo-list.patch
+revert-fbcon-disable-accelerated-scrolling.patch
+fbcon-add-option-to-enable-legacy-hardware-acceleration.patch
+mptcp-fix-msk-traversal-in-mptcp_nl_cmd_set_flags.patch
diff --git a/queue-5.16/spi-stm32-qspi-update-spi-registering.patch b/queue-5.16/spi-stm32-qspi-update-spi-registering.patch
new file mode 100644 (file)
index 0000000..b6883ae
--- /dev/null
@@ -0,0 +1,144 @@
+From e4d63473d3110afd170e6e0e48494d3789d26136 Mon Sep 17 00:00:00 2001
+From: Patrice Chotard <patrice.chotard@foss.st.com>
+Date: Mon, 17 Jan 2022 13:17:44 +0100
+Subject: spi: stm32-qspi: Update spi registering
+
+From: Patrice Chotard <patrice.chotard@foss.st.com>
+
+commit e4d63473d3110afd170e6e0e48494d3789d26136 upstream.
+
+Some device driver need to communicate to qspi device during the remove
+process, qspi controller must be functional when spi_unregister_master()
+is called.
+
+To ensure this, replace devm_spi_register_master() by spi_register_master()
+and spi_unregister_master() is called directly in .remove callback before
+stopping the qspi controller.
+
+This issue was put in evidence using kernel v5.11 and later
+with a spi-nor which supports the software reset feature introduced
+by commit d73ee7534cc5 ("mtd: spi-nor: core: perform a Soft Reset on
+shutdown")
+
+Fixes: c530cd1d9d5e ("spi: spi-mem: add stm32 qspi controller")
+
+Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
+Cc: <stable@vger.kernel.org> # 5.8.x
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Link: https://lore.kernel.org/r/20220117121744.29729-1-patrice.chotard@foss.st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-stm32-qspi.c |   47 +++++++++++++++----------------------------
+ 1 file changed, 17 insertions(+), 30 deletions(-)
+
+--- a/drivers/spi/spi-stm32-qspi.c
++++ b/drivers/spi/spi-stm32-qspi.c
+@@ -688,7 +688,7 @@ static int stm32_qspi_probe(struct platf
+       struct resource *res;
+       int ret, irq;
+-      ctrl = spi_alloc_master(dev, sizeof(*qspi));
++      ctrl = devm_spi_alloc_master(dev, sizeof(*qspi));
+       if (!ctrl)
+               return -ENOMEM;
+@@ -697,58 +697,46 @@ static int stm32_qspi_probe(struct platf
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi");
+       qspi->io_base = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(qspi->io_base)) {
+-              ret = PTR_ERR(qspi->io_base);
+-              goto err_master_put;
+-      }
++      if (IS_ERR(qspi->io_base))
++              return PTR_ERR(qspi->io_base);
+       qspi->phys_base = res->start;
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mm");
+       qspi->mm_base = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(qspi->mm_base)) {
+-              ret = PTR_ERR(qspi->mm_base);
+-              goto err_master_put;
+-      }
++      if (IS_ERR(qspi->mm_base))
++              return PTR_ERR(qspi->mm_base);
+       qspi->mm_size = resource_size(res);
+-      if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) {
+-              ret = -EINVAL;
+-              goto err_master_put;
+-      }
++      if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ)
++              return -EINVAL;
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              ret = irq;
+-              goto err_master_put;
+-      }
++      if (irq < 0)
++              return irq;
+       ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0,
+                              dev_name(dev), qspi);
+       if (ret) {
+               dev_err(dev, "failed to request irq\n");
+-              goto err_master_put;
++              return ret;
+       }
+       init_completion(&qspi->data_completion);
+       init_completion(&qspi->match_completion);
+       qspi->clk = devm_clk_get(dev, NULL);
+-      if (IS_ERR(qspi->clk)) {
+-              ret = PTR_ERR(qspi->clk);
+-              goto err_master_put;
+-      }
++      if (IS_ERR(qspi->clk))
++              return PTR_ERR(qspi->clk);
+       qspi->clk_rate = clk_get_rate(qspi->clk);
+-      if (!qspi->clk_rate) {
+-              ret = -EINVAL;
+-              goto err_master_put;
+-      }
++      if (!qspi->clk_rate)
++              return -EINVAL;
+       ret = clk_prepare_enable(qspi->clk);
+       if (ret) {
+               dev_err(dev, "can not enable the clock\n");
+-              goto err_master_put;
++              return ret;
+       }
+       rstc = devm_reset_control_get_exclusive(dev, NULL);
+@@ -784,7 +772,7 @@ static int stm32_qspi_probe(struct platf
+       pm_runtime_enable(dev);
+       pm_runtime_get_noresume(dev);
+-      ret = devm_spi_register_master(dev, ctrl);
++      ret = spi_register_master(ctrl);
+       if (ret)
+               goto err_pm_runtime_free;
+@@ -806,8 +794,6 @@ err_dma_free:
+       stm32_qspi_dma_free(qspi);
+ err_clk_disable:
+       clk_disable_unprepare(qspi->clk);
+-err_master_put:
+-      spi_master_put(qspi->ctrl);
+       return ret;
+ }
+@@ -817,6 +803,7 @@ static int stm32_qspi_remove(struct plat
+       struct stm32_qspi *qspi = platform_get_drvdata(pdev);
+       pm_runtime_get_sync(qspi->dev);
++      spi_unregister_master(qspi->ctrl);
+       /* disable qspi */
+       writel_relaxed(0, qspi->io_base + QSPI_CR);
+       stm32_qspi_dma_free(qspi);